Re: [PATCH] drm/amd/amdkfd/kfd_int_process_v9: Use true and false for boolean values

2018-08-06 Thread Huang Rui
On Sat, Aug 04, 2018 at 07:30:45PM -0500, Gustavo A. R. Silva wrote:
> Return statements in functions returning bool should use true or false
> instead of an integer value.
> 
> This code was detected with the help of Coccinelle.
> 
> Signed-off-by: Gustavo A. R. Silva 

Reviewed-by: Huang Rui 

Also add Felix for his awareness.

Thanks,
Ray

> ---
>  drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c 
> b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
> index f836897..42e92e3 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
> @@ -37,12 +37,12 @@ static bool event_interrupt_isr_v9(struct kfd_dev *dev,
>   vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry);
>   if (vmid < dev->vm_info.first_vmid_kfd ||
>   vmid > dev->vm_info.last_vmid_kfd)
> - return 0;
> + return false;
>  
>   /* If there is no valid PASID, it's likely a firmware bug */
>   pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry);
>   if (WARN_ONCE(pasid == 0, "FW bug: No PASID in KFD interrupt"))
> - return 0;
> + return false;
>  
>   source_id = SOC15_SOURCE_ID_FROM_IH_ENTRY(ih_ring_entry);
>   client_id = SOC15_CLIENT_ID_FROM_IH_ENTRY(ih_ring_entry);
> -- 
> 2.7.4
> 
> ___
> amd-gfx mailing list
> amd-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/amdkfd: Use true and false for boolean values

2018-08-06 Thread Huang Rui
On Sat, Aug 04, 2018 at 07:27:02PM -0500, Gustavo A. R. Silva wrote:
> Return statements in functions returning bool should use true or false
> instead of an integer value.
> 
> This code was detected with the help of Coccinelle.
> 
> Signed-off-by: Gustavo A. R. Silva 

Looks good for me.
Reviewed-by: Huang Rui 

Add Felix for his awareness.

> ---
>  drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c 
> b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
> index 5d2475d..16af9d1 100644
> --- a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
> +++ b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
> @@ -62,12 +62,12 @@ static bool cik_event_interrupt_isr(struct kfd_dev *dev,
>   vmid  = (ihre->ring_id & 0xff00) >> 8;
>   if (vmid < dev->vm_info.first_vmid_kfd ||
>   vmid > dev->vm_info.last_vmid_kfd)
> - return 0;
> + return false;
>  
>   /* If there is no valid PASID, it's likely a firmware bug */
>   pasid = (ihre->ring_id & 0x) >> 16;
>   if (WARN_ONCE(pasid == 0, "FW bug: No PASID in KFD interrupt"))
> - return 0;
> + return false;
>  
>   /* Interrupt types we care about: various signals and faults.
>* They will be forwarded to a work queue (see below).
> -- 
> 2.7.4
> 
> ___
> amd-gfx mailing list
> amd-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 11/13] drm/mediatek: use layer_nr function to get layer number to init plane

2018-08-06 Thread CK Hu
Hi, Stu:

On Mon, 2018-08-06 at 19:58 +0800, Stu Hsieh wrote:
> This patch use layer_nr function to get layer number to init plane
> 
> When plane init in crtc create,
> it use the number of OVL layer to init plane.
> That's OVL can read 4 memory address.
> 
> For mt2712 third ddp, it use RDMA to read memory.
> RDMA can read 1 memory address, so it just init one plane.
> 
> For compatibility, this patch use mtk_ddp_comp_layer_nr function
> to get layer number from their HW component in ddp for plane init.
> 
> Signed-off-by: Stu Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 37 
> +
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.h |  1 -
>  2 files changed, 24 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 2d6aa150a9ff..1a8685fbbf57 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -45,7 +45,8 @@ struct mtk_drm_crtc {
>   boolpending_needs_vblank;
>   struct drm_pending_vblank_event *event;
>  
> - struct drm_planeplanes[OVL_LAYER_NR];
> + struct drm_plane**planes;

Why double pointer? This make things more complicated.
Single pointer is equal to array, so you need not to modify so many
place.

Regards,
CK

> + unsigned intlayer_nr;
>   boolpending_planes;
>  
>   void __iomem*config_regs;
> @@ -286,8 +287,8 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc 
> *mtk_crtc)
>   }
>  
>   /* Initially configure all planes */
> - for (i = 0; i < OVL_LAYER_NR; i++) {
> - struct drm_plane *plane = &mtk_crtc->planes[i];
> + for (i = 0; i < mtk_crtc->layer_nr; i++) {
> + struct drm_plane *plane = mtk_crtc->planes[i];
>   struct mtk_plane_state *plane_state;
>  
>   plane_state = to_mtk_plane_state(plane->state);
> @@ -351,8 +352,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
>   }
>  
>   if (mtk_crtc->pending_planes) {
> - for (i = 0; i < OVL_LAYER_NR; i++) {
> - struct drm_plane *plane = &mtk_crtc->planes[i];
> + for (i = 0; i < mtk_crtc->layer_nr; i++) {
> + struct drm_plane *plane = mtk_crtc->planes[i];
>   struct mtk_plane_state *plane_state;
>  
>   plane_state = to_mtk_plane_state(plane->state);
> @@ -403,8 +404,8 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc 
> *crtc,
>   return;
>  
>   /* Set all pending plane state to disabled */
> - for (i = 0; i < OVL_LAYER_NR; i++) {
> - struct drm_plane *plane = &mtk_crtc->planes[i];
> + for (i = 0; i < mtk_crtc->layer_nr; i++) {
> + struct drm_plane *plane = mtk_crtc->planes[i];
>   struct mtk_plane_state *plane_state;
>  
>   plane_state = to_mtk_plane_state(plane->state);
> @@ -450,8 +451,8 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
> *crtc,
>  
>   if (mtk_crtc->event)
>   mtk_crtc->pending_needs_vblank = true;
> - for (i = 0; i < OVL_LAYER_NR; i++) {
> - struct drm_plane *plane = &mtk_crtc->planes[i];
> + for (i = 0; i < mtk_crtc->layer_nr; i++) {
> + struct drm_plane *plane = mtk_crtc->planes[i];
>   struct mtk_plane_state *plane_state;
>  
>   plane_state = to_mtk_plane_state(plane->state);
> @@ -598,18 +599,28 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>   mtk_crtc->ddp_comp[i] = comp;
>   }
>  
> - for (zpos = 0; zpos < OVL_LAYER_NR; zpos++) {
> + mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]);
> + mtk_crtc->planes = devm_kmalloc_array(dev, mtk_crtc->layer_nr,
> +   sizeof(*mtk_crtc->planes),
> +   GFP_KERNEL);
> +
> + for (zpos = 0; zpos < mtk_crtc->layer_nr; zpos++) {
> + mtk_crtc->planes[zpos] = devm_kzalloc(dev,
> + sizeof(*mtk_crtc->planes[zpos]),
> + GFP_KERNEL);
> +
>   type = (zpos == 0) ? DRM_PLANE_TYPE_PRIMARY :
>   (zpos == 1) ? DRM_PLANE_TYPE_CURSOR :
>   DRM_PLANE_TYPE_OVERLAY;
> - ret = mtk_plane_init(drm_dev, &mtk_crtc->planes[zpos],
> + ret = mtk_plane_init(drm_dev, mtk_crtc->planes[zpos],
>BIT(pipe), type);
>   if (ret)
>   goto unprepare;
>   }
>  
> - ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, &mtk_crtc->planes[0],
> - &mtk_crtc->planes[1], pipe);
> + ret = mtk_drm_crtc_init(drm_dev, mtk_crt

Re: [PATCH v3 10/13] drm/mediatek: add callback function to return RDMA layer number

2018-08-06 Thread CK Hu
Hi, Stu:

On Mon, 2018-08-06 at 19:58 +0800, Stu Hsieh wrote:
> This patch add callback function to return RDMA layer number
> 
> RDMA always has one layer.
> 
> Signed-off-by: Stu Hsieh 

I would like to remove the term 'callback' because this is just function
pointer rather than callback function. OVL does not register callback
function to crtc and crtc call OVL function directly. The modification
is good to me, so

Reviewed-by: CK Hu 

> ---
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index 91a8b6e27d39..68c99253285b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -188,6 +188,11 @@ static unsigned int rdma_fmt_convert(struct 
> mtk_disp_rdma *rdma,
>   }
>  }
>  
> +static unsigned int mtk_rdma_layer_nr(struct mtk_ddp_comp *comp)
> +{
> + return 1;
> +}
> +
>  static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int 
> idx,
> struct mtk_plane_state *state)
>  {
> @@ -220,6 +225,7 @@ static const struct mtk_ddp_comp_funcs 
> mtk_disp_rdma_funcs = {
>   .stop = mtk_rdma_stop,
>   .enable_vblank = mtk_rdma_enable_vblank,
>   .disable_vblank = mtk_rdma_disable_vblank,
> + .layer_nr = mtk_rdma_layer_nr,
>   .layer_config = mtk_rdma_layer_config,
>  };
>  


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


Re: [PATCH v3 09/13] drm/mediatek: add callback function to return OVL layer number

2018-08-06 Thread CK Hu
Hi, Stu:

On Mon, 2018-08-06 at 19:58 +0800, Stu Hsieh wrote:
> This patch add callback function to return OVL layer number
> 
> For now, MT8173, MT2712, MT2701 OVL all has 4 layer.
> 
> Signed-off-by: Stu Hsieh 

I would like to remove the term 'callback' because this is just function
pointer rather than callback function. OVL does not register callback
function to crtc and crtc call OVL function directly. The modification
is good to me, so

Reviewed-by: CK Hu 

> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 978782a77629..66060e79afbc 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -132,6 +132,11 @@ static void mtk_ovl_config(struct mtk_ddp_comp *comp, 
> unsigned int w,
>   writel(0x0, comp->regs + DISP_REG_OVL_RST);
>  }
>  
> +static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
> +{
> + return 4;
> +}
> +
>  static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
>  {
>   unsigned int reg;
> @@ -221,6 +226,7 @@ static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs 
> = {
>   .stop = mtk_ovl_stop,
>   .enable_vblank = mtk_ovl_enable_vblank,
>   .disable_vblank = mtk_ovl_disable_vblank,
> + .layer_nr = mtk_ovl_layer_nr,
>   .layer_on = mtk_ovl_layer_on,
>   .layer_off = mtk_ovl_layer_off,
>   .layer_config = mtk_ovl_layer_config,


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


Re: [PATCH v3 08/13] drm/mediatek: add function to get layer number for component

2018-08-06 Thread CK Hu
Hi, Stu:

On Mon, 2018-08-06 at 19:58 +0800, Stu Hsieh wrote:
> This patch add function to get layer number for component
> 
> Signed-off-by: Stu Hsieh 

Reviewed-by: CK Hu 

> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 9 +
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h 
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 7413ffeb3c9d..8399229e6ad2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -78,6 +78,7 @@ struct mtk_ddp_comp_funcs {
>   void (*stop)(struct mtk_ddp_comp *comp);
>   void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
>   void (*disable_vblank)(struct mtk_ddp_comp *comp);
> + unsigned int (*layer_nr)(struct mtk_ddp_comp *comp);
>   void (*layer_on)(struct mtk_ddp_comp *comp, unsigned int idx);
>   void (*layer_off)(struct mtk_ddp_comp *comp, unsigned int idx);
>   void (*layer_config)(struct mtk_ddp_comp *comp, unsigned int idx,
> @@ -128,6 +129,14 @@ static inline void mtk_ddp_comp_disable_vblank(struct 
> mtk_ddp_comp *comp)
>   comp->funcs->disable_vblank(comp);
>  }
>  
> +static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp)
> +{
> + if (comp->funcs && comp->funcs->layer_nr)
> + return comp->funcs->layer_nr(comp);
> +
> + return 0;
> +}
> +
>  static inline void mtk_ddp_comp_layer_on(struct mtk_ddp_comp *comp,
>unsigned int idx)
>  {


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


Re: [PATCH v3 07/13] drm/mediatek: add YUYV/UYVY color format support for RDMA

2018-08-06 Thread CK Hu
Hi, Stu:

On Mon, 2018-08-06 at 19:58 +0800, Stu Hsieh wrote:
> This patch add YUYV/UYVY color format support for RDMA
> and transform matrix for YUYV/UYVY.
> 
> Signed-off-by: Stu Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 15 +++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index ba72d392dc27..91a8b6e27d39 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -33,6 +33,8 @@
>  #define RDMA_ENGINE_EN   BIT(0)
>  #define RDMA_MODE_MEMORY BIT(1)
>  #define DISP_REG_RDMA_SIZE_CON_0 0x0014
> +#define RDMA_MATRIX_ENABLE   BIT(17)
> +#define RDMA_MATRIX_INT_MTX_SEL  (7UL << 20)
>  #define DISP_REG_RDMA_SIZE_CON_1 0x0018
>  #define DISP_REG_RDMA_TARGET_LINE0x001c
>  #define DISP_RDMA_MEM_CON0x0024
> @@ -46,12 +48,15 @@
>  #define RDMA_FIFO_SIZE(rdma) ((rdma)->data->fifo_size)
>  #define DISP_RDMA_MEM_START_ADDR 0x0f00
>  
> +#define MATRIX_INT_MTX_SEL_DEFAULT   0xb0
>  #define RDMA_MEM_GMC 0x40402020
>  
>  #define MEM_MODE_INPUT_FORMAT_RGB565 0x0
>  #define MEM_MODE_INPUT_FORMAT_RGB888 (0x001 << 4)
>  #define MEM_MODE_INPUT_FORMAT_RGBA   (0x002 << 4)
>  #define MEM_MODE_INPUT_FORMAT_ARGB   (0x003 << 4)
> +#define MEM_MODE_INPUT_FORMAT_UYVY   (0x004 << 4)
> +#define MEM_MODE_INPUT_FORMAT_YUYV   (0x005 << 4)
>  
>  struct mtk_disp_rdma_data {
>   unsigned int fifo_size;
> @@ -176,6 +181,10 @@ static unsigned int rdma_fmt_convert(struct 
> mtk_disp_rdma *rdma,
>   case DRM_FORMAT_XBGR:
>   case DRM_FORMAT_ABGR:
>   return MEM_MODE_INPUT_FORMAT_RGBA | MEM_MODE_INPUT_SWAP;
> + case DRM_FORMAT_UYVY:
> + return MEM_MODE_INPUT_FORMAT_UYVY;
> + case DRM_FORMAT_YUYV:
> + return MEM_MODE_INPUT_FORMAT_YUYV;
>   }
>  }
>  
> @@ -191,6 +200,12 @@ static void mtk_rdma_layer_config(struct mtk_ddp_comp 
> *comp, unsigned int idx,
>  
>   con = rdma_fmt_convert(rdma, fmt);
>   writel_relaxed(con, comp->regs + DISP_RDMA_MEM_CON);
> + if (fmt == DRM_FORMAT_UYVY || fmt == DRM_FORMAT_YUYV)
> + rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, 0xff,

Symbolize 0xff. Maybe you should define as

#define RDMA_MATRIX_INT_MTX_SEL GENMASK(23, 20)
#define RDMA_MATRIX_INT_MTX_YUV_TO_RGB   0x7
#define RDMA_MATRIX_INT_MTX_RGB_TO_RGB   0xb

Correct the naming to align data sheet.

Regards,
CK

> +  RDMA_MATRIX_ENABLE | RDMA_MATRIX_INT_MTX_SEL);
> + else
> + rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, 0xff,
> +  MATRIX_INT_MTX_SEL_DEFAULT);
>  
>   writel_relaxed(addr, comp->regs + DISP_RDMA_MEM_START_ADDR);
>   writel_relaxed(pitch, comp->regs + DISP_RDMA_MEM_SRC_PITCH);


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


Re: [PATCH v3 06/13] drm/mediatek: add RGB color format support for RDMA

2018-08-06 Thread CK Hu
Hi, Stu:

On Mon, 2018-08-06 at 19:58 +0800, Stu Hsieh wrote:
> This patch add RGB color format support for RDMA,
> including RGB565, RGB888, RGBA and ARGB.
> 
> Signed-off-by: Stu Hsieh 
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 41 
> 
>  1 file changed, 41 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index 08866550740f..ba72d392dc27 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -35,6 +35,8 @@
>  #define DISP_REG_RDMA_SIZE_CON_0 0x0014
>  #define DISP_REG_RDMA_SIZE_CON_1 0x0018
>  #define DISP_REG_RDMA_TARGET_LINE0x001c
> +#define DISP_RDMA_MEM_CON0x0024
> +#define MEM_MODE_INPUT_SWAP  BIT(8)
>  #define DISP_RDMA_MEM_SRC_PITCH  0x002c
>  #define DISP_RDMA_MEM_GMC_SETTING_0  0x0030
>  #define DISP_REG_RDMA_FIFO_CON   0x0040
> @@ -46,6 +48,11 @@
>  
>  #define RDMA_MEM_GMC 0x40402020
>  
> +#define MEM_MODE_INPUT_FORMAT_RGB565 0x0
> +#define MEM_MODE_INPUT_FORMAT_RGB888 (0x001 << 4)
> +#define MEM_MODE_INPUT_FORMAT_RGBA   (0x002 << 4)
> +#define MEM_MODE_INPUT_FORMAT_ARGB   (0x003 << 4)
> +
>  struct mtk_disp_rdma_data {
>   unsigned int fifo_size;
>  };
> @@ -144,12 +151,46 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, 
> unsigned int width,
>   writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON);
>  }
>  
> +static unsigned int rdma_fmt_convert(struct mtk_disp_rdma *rdma,
> +  unsigned int fmt)
> +{
> + switch (fmt) {
> + default:
> + case DRM_FORMAT_RGB565:
> + return MEM_MODE_INPUT_FORMAT_RGB565;
> + case DRM_FORMAT_BGR565:
> + return MEM_MODE_INPUT_FORMAT_RGB565 | MEM_MODE_INPUT_SWAP;
> + case DRM_FORMAT_RGB888:
> + return MEM_MODE_INPUT_FORMAT_RGB888;
> + case DRM_FORMAT_BGR888:
> + return MEM_MODE_INPUT_FORMAT_RGB888 | MEM_MODE_INPUT_SWAP;
> + case DRM_FORMAT_RGBX:
> + case DRM_FORMAT_RGBA:
> + return MEM_MODE_INPUT_FORMAT_ARGB;

I think the alphabet order of the naming reflect the dram order for each
color. Of course, big-endian and little-endian would result in reversed
naming order. I could not understand why RDMA use ARGB naming for
DRM RGBA. If the typo is from data sheet, I could just accept this
typo and give an explain in driver because I want to align driver with
data sheet.

Regards,
CK

> + case DRM_FORMAT_BGRX:
> + case DRM_FORMAT_BGRA:
> + return MEM_MODE_INPUT_FORMAT_ARGB | MEM_MODE_INPUT_SWAP;
> + case DRM_FORMAT_XRGB:
> + case DRM_FORMAT_ARGB:
> + return MEM_MODE_INPUT_FORMAT_RGBA;
> + case DRM_FORMAT_XBGR:
> + case DRM_FORMAT_ABGR:
> + return MEM_MODE_INPUT_FORMAT_RGBA | MEM_MODE_INPUT_SWAP;
> + }
> +}
> +
>  static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int 
> idx,
> struct mtk_plane_state *state)
>  {
> + struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
>   struct mtk_plane_pending_state *pending = &state->pending;
>   unsigned int addr = pending->addr;
>   unsigned int pitch = pending->pitch & 0x;
> + unsigned int fmt = pending->format;
> + unsigned int con;
> +
> + con = rdma_fmt_convert(rdma, fmt);
> + writel_relaxed(con, comp->regs + DISP_RDMA_MEM_CON);
>  
>   writel_relaxed(addr, comp->regs + DISP_RDMA_MEM_START_ADDR);
>   writel_relaxed(pitch, comp->regs + DISP_RDMA_MEM_SRC_PITCH);


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


Re: [PATCH v3 05/13] drm/mediatek: add memory mode and layer_config for RDMA

2018-08-06 Thread CK Hu
Hi, Stu:

On Mon, 2018-08-06 at 19:58 +0800, Stu Hsieh wrote:
> This patch add memory mode for RDMA and layer_config for RDMA
> 
> If use RDMA to read data from memory, it should set memory mode to RDMA
> 
> Layer config set the data address and pitch to RDMA from plane setting.
> 
> Signed-off-by: Stu Hsieh 

Reviewed-by: CK Hu 

> ---
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 21 +
>  1 file changed, 21 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index 585943c81e1f..08866550740f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -31,14 +31,20 @@
>  #define RDMA_REG_UPDATE_INT  BIT(0)
>  #define DISP_REG_RDMA_GLOBAL_CON 0x0010
>  #define RDMA_ENGINE_EN   BIT(0)
> +#define RDMA_MODE_MEMORY BIT(1)
>  #define DISP_REG_RDMA_SIZE_CON_0 0x0014
>  #define DISP_REG_RDMA_SIZE_CON_1 0x0018
>  #define DISP_REG_RDMA_TARGET_LINE0x001c
> +#define DISP_RDMA_MEM_SRC_PITCH  0x002c
> +#define DISP_RDMA_MEM_GMC_SETTING_0  0x0030
>  #define DISP_REG_RDMA_FIFO_CON   0x0040
>  #define RDMA_FIFO_UNDERFLOW_EN   BIT(31)
>  #define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16)
>  #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes)  ((bytes) / 16)
>  #define RDMA_FIFO_SIZE(rdma) ((rdma)->data->fifo_size)
> +#define DISP_RDMA_MEM_START_ADDR 0x0f00
> +
> +#define RDMA_MEM_GMC 0x40402020
>  
>  struct mtk_disp_rdma_data {
>   unsigned int fifo_size;
> @@ -138,12 +144,27 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, 
> unsigned int width,
>   writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON);
>  }
>  
> +static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int 
> idx,
> +   struct mtk_plane_state *state)
> +{
> + struct mtk_plane_pending_state *pending = &state->pending;
> + unsigned int addr = pending->addr;
> + unsigned int pitch = pending->pitch & 0x;
> +
> + writel_relaxed(addr, comp->regs + DISP_RDMA_MEM_START_ADDR);
> + writel_relaxed(pitch, comp->regs + DISP_RDMA_MEM_SRC_PITCH);
> + writel(RDMA_MEM_GMC, comp->regs + DISP_RDMA_MEM_GMC_SETTING_0);
> + rdma_update_bits(comp, DISP_REG_RDMA_GLOBAL_CON,
> +  RDMA_MODE_MEMORY, RDMA_MODE_MEMORY);
> +}
> +
>  static const struct mtk_ddp_comp_funcs mtk_disp_rdma_funcs = {
>   .config = mtk_rdma_config,
>   .start = mtk_rdma_start,
>   .stop = mtk_rdma_stop,
>   .enable_vblank = mtk_rdma_enable_vblank,
>   .disable_vblank = mtk_rdma_disable_vblank,
> + .layer_config = mtk_rdma_layer_config,
>  };
>  
>  static int mtk_disp_rdma_bind(struct device *dev, struct device *master,


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


Re: [PATCH] drm/i915/kvmgt: Fix potential Spectre v1

2018-08-06 Thread Zhenyu Wang
On 2018.08.02 22:40:19 -0500, Gustavo A. R. Silva wrote:
> info.index can be indirectly controlled by user-space, hence leading
> to a potential exploitation of the Spectre variant 1 vulnerability.
> 
> This issue was detected with the help of Smatch:
> 
> drivers/gpu/drm/i915/gvt/kvmgt.c:1232 intel_vgpu_ioctl() warn:
> potential spectre issue 'vgpu->vdev.region' [r]
> 
> Fix this by sanitizing info.index before indirectly using it to index
> vgpu->vdev.region

Thanks for catching this! Applied.

> 
> Notice that given that speculation windows are large, the policy is
> to kill the speculation on the first load and not worry if it can be
> completed with a dependent load/store [1].
> 
> [1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
> 
> Cc: sta...@vger.kernel.org
> Signed-off-by: Gustavo A. R. Silva 
> ---
>  drivers/gpu/drm/i915/gvt/kvmgt.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c 
> b/drivers/gpu/drm/i915/gvt/kvmgt.c
> index 4d2f53a..b703f20 100644
> --- a/drivers/gpu/drm/i915/gvt/kvmgt.c
> +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
> @@ -43,6 +43,8 @@
>  #include 
>  #include 
>  
> +#include 
> +
>  #include "i915_drv.h"
>  #include "gvt.h"
>  
> @@ -1139,7 +1141,8 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
> unsigned int cmd,
>   } else if (cmd == VFIO_DEVICE_GET_REGION_INFO) {
>   struct vfio_region_info info;
>   struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
> - int i, ret;
> + unsigned int i;
> + int ret;
>   struct vfio_region_info_cap_sparse_mmap *sparse = NULL;
>   size_t size;
>   int nr_areas = 1;
> @@ -1224,6 +1227,10 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, 
> unsigned int cmd,
>   if (info.index >= VFIO_PCI_NUM_REGIONS +
>   vgpu->vdev.num_regions)
>   return -EINVAL;
> + info.index =
> + array_index_nospec(info.index,
> + VFIO_PCI_NUM_REGIONS +
> + vgpu->vdev.num_regions);
>  
>   i = info.index - VFIO_PCI_NUM_REGIONS;
>  
> -- 
> 2.7.4
> 
> ___
> intel-gvt-dev mailing list
> intel-gvt-...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev

-- 
Open Source Technology Center, Intel ltd.

$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827


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


Re: [PATCH v2 1/5] drm/vc4: Fix TILE_Y_OFFSET definitions

2018-08-06 Thread Eric Anholt
Boris Brezillon  writes:

> On Mon, 06 Aug 2018 13:02:48 -0700
> Eric Anholt  wrote:
>
>> Boris Brezillon  writes:
>> 
>> > From: Eric Anholt 
>> >
>> > Y_OFFSET field starts at bit 8 not 7.
>> >
>> > Signed-off-by: Eric Anholt 
>> > Signed-off-by: Boris Brezillon   
>> 
>> Your changes in this series have my r-b.  Time to add your ack to my
>
> Adding SoB implicitly means A-b for me, but I can add them if you
> prefer. 

Yeah, I guess that does, you're right.


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


[PULL] drm-intel-next-fixes

2018-08-06 Thread Rodrigo Vivi
Hi Dave,

Initial fixes for 4.19. Starting by the one where gvt compilation gets
broken after a silent conflict between next and fixes.

Here goes drm-intel-next-fixes-2018-08-06:
- Fix gvt compilation broken on a silent conflict on fixes vs next merge
- Fix runtime PM for LPE audio
- Revert on ICL workaround
- Interactive RPS mode
- Fix for PSR sink status report

Thanks,
Rodrigo.

The following changes since commit 15da09500a7053612e4ab049ff998e99a77a8df0:

  Merge branch 'drm-armada-devel' of git://git.armlinux.org.uk/~rmk/linux-arm 
into drm-next (2018-08-01 09:02:16 +1000)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-intel 
tags/drm-intel-next-fixes-2018-08-06

for you to fetch changes up to 3237c0dbe21f8d2ca2feaa3891aff3619873cd30:

  drm/i915/kvmgt: Fix compilation error (2018-08-06 11:28:35 -0700)


- Fix gvt compilation broken on a silent conflict on fixes vs next merge
- Fix runtime PM for LPE audio
- Revert on ICL workaround
- Interactive RPS mode
- Fix for PSR sink status report


Chris Wilson (2):
  drm/i915: Interactive RPS mode
  drm/i915/lpe: Mark LPE audio runtime pm as "no callbacks"

Michał Winiarski (1):
  drm/i915/kvmgt: Fix compilation error

Mika Kuoppala (1):
  Revert "drm/i915/icl: WaEnableFloatBlendOptimization"

Rodrigo Vivi (1):
  drm/i915: Fix psr sink status report.

 drivers/gpu/drm/i915/gvt/kvmgt.c |   6 --
 drivers/gpu/drm/i915/i915_debugfs.c  |  26 +---
 drivers/gpu/drm/i915/i915_drv.h  |  16 +++--
 drivers/gpu/drm/i915/i915_irq.c  |   4 +-
 drivers/gpu/drm/i915/i915_reg.h  |   3 -
 drivers/gpu/drm/i915/intel_display.c |  20 ++
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 drivers/gpu/drm/i915/intel_lpe_audio.c   |   4 +-
 drivers/gpu/drm/i915/intel_pm.c  | 101 ---
 drivers/gpu/drm/i915/intel_workarounds.c |   3 -
 10 files changed, 123 insertions(+), 62 deletions(-)
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 100745] amdgpu fails to wake up DisplayPort DELL monitors with 'clock recovery failed'

2018-08-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=100745

--- Comment #15 from Kimmo  ---
(In reply to Kimmo from comment #14)
> Confirming still similar problem (Screen stays black while trying resume
> from suspend)
> 2x DELL u2415h + display port daisy chain + RX480 (amdgpu 18.0.1-2)

Actually need to correct myself. The suspend problem seems to be fixed and
working ok for me so far. Problem seems to be more related if Dell monitor is
allowed to shutdown by itself due to inactivity, but not sure if it has any
relations to amdgpu. Using KDE plasma desktop 5.13.3. Sorry for inconvenience.

-- 
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 20/22] drm/omap: venc: Fixup video mode in .check_timings() operation

2018-08-06 Thread Laurent Pinchart
The VENC encoder modifies the requested video mode to match the NTSC or
PAL timings (or reject the video mode completely) in the .set_timings()
operation. This should be performed in the .check_timings() operation
instead. Move the fixup.

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

diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index 09ec8b0eafee..126efbf89898 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -452,7 +452,7 @@ static void venc_runtime_put(struct venc_device *venc)
WARN_ON(r < 0 && r != -ENOSYS);
 }
 
-static const struct venc_config *venc_timings_to_config(struct videomode *vm)
+static const struct venc_config *venc_timings_to_config(const struct videomode 
*vm)
 {
switch (venc_get_videomode(vm)) {
default:
@@ -582,28 +582,16 @@ static void venc_set_timings(struct omap_dss_device 
*dssdev,
 const struct videomode *vm)
 {
struct venc_device *venc = dssdev_to_venc(dssdev);
-   struct videomode actual_vm;
 
DSSDBG("venc_set_timings\n");
 
mutex_lock(&venc->venc_lock);
 
-   switch (venc_get_videomode(vm)) {
-   default:
-   WARN_ON_ONCE(1);
-   case VENC_MODE_PAL:
-   actual_vm = omap_dss_pal_vm;
-   break;
-   case VENC_MODE_NTSC:
-   actual_vm = omap_dss_ntsc_vm;
-   break;
-   }
-
/* Reset WSS data when the TV standard changes. */
-   if (memcmp(&venc->vm, &actual_vm, sizeof(actual_vm)))
+   if (memcmp(&venc->vm, vm, sizeof(*vm)))
venc->wss_data = 0;
 
-   venc->vm = actual_vm;
+   venc->vm = *vm;
 
dispc_set_tv_pclk(venc->dss->dispc, 1350);
 
@@ -617,8 +605,13 @@ static int venc_check_timings(struct omap_dss_device 
*dssdev,
 
switch (venc_get_videomode(vm)) {
case VENC_MODE_PAL:
+   *vm = omap_dss_pal_vm;
+   return 0;
+
case VENC_MODE_NTSC:
+   *vm = omap_dss_ntsc_vm;
return 0;
+
default:
return -EINVAL;
}
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 13/22] drm/omap: Move bus flag hack to encoder implementation

2018-08-06 Thread Laurent Pinchart
The bus flags stored in omap_dss_device instances are used to fixup the
video mode before setting it, to honour constraints that can't be
expressed through drm_display_mode. The fixup occurs in the CRTC mode
set operation and the resulting video mode is stored internally in the
CRTC. It is then used next by omap_encoder_enable() to apply mode fixups
for the omap_dss_device instances in omap_encoder_update().

Move the hack to the omap_encoder_update() function right before
applying the omap_dss_device fixups, in order to group all fixups
together.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c| 42 +
 drivers/gpu/drm/omapdrm/omap_encoder.c | 48 +-
 2 files changed, 43 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 39693dfe54af..62928ec0e7db 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -420,8 +420,6 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
-   struct videomode *vm = &omap_crtc->vm;
-   struct omap_dss_device *dssdev;
 
DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
omap_crtc->name, mode->base.id, mode->name,
@@ -430,45 +428,7 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal,
mode->type, mode->flags);
 
-   drm_display_mode_to_videomode(mode, vm);
-
-   /*
-* HACK: This fixes the vm flags.
-* struct drm_display_mode does not contain the VSYNC/HSYNC/DE flags
-* and they get lost when converting back and forth between
-* struct drm_display_mode and struct videomode. The hack below
-* goes and fetches the missing flags from the panel drivers.
-*
-* A better solution is to use DRM's bus-flags through the whole driver.
-*/
-
-   for (dssdev = omap_crtc->pipe->output; dssdev; dssdev = dssdev->next) {
-   unsigned long bus_flags = dssdev->bus_flags;
-
-   if (!(vm->flags & (DISPLAY_FLAGS_DE_LOW |
-  DISPLAY_FLAGS_DE_HIGH))) {
-   if (bus_flags & DRM_BUS_FLAG_DE_LOW)
-   vm->flags |= DISPLAY_FLAGS_DE_LOW;
-   else if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
-   vm->flags |= DISPLAY_FLAGS_DE_HIGH;
-   }
-
-   if (!(vm->flags & (DISPLAY_FLAGS_PIXDATA_POSEDGE |
-  DISPLAY_FLAGS_PIXDATA_NEGEDGE))) {
-   if (bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
-   vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
-   else if (bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
-   vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
-   }
-
-   if (!(vm->flags & (DISPLAY_FLAGS_SYNC_POSEDGE |
-  DISPLAY_FLAGS_SYNC_NEGEDGE))) {
-   if (bus_flags & DRM_BUS_FLAG_SYNC_POSEDGE)
-   vm->flags |= DISPLAY_FLAGS_SYNC_POSEDGE;
-   else if (bus_flags & DRM_BUS_FLAG_SYNC_NEGEDGE)
-   vm->flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
-   }
-   }
+   drm_display_mode_to_videomode(mode, &omap_crtc->vm);
 }
 
 static int omap_crtc_atomic_check(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index bb010c20d8b8..82cdcba961a8 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -103,13 +103,49 @@ static int omap_encoder_update(struct drm_encoder 
*encoder,
int ret;
 
for (dssdev = omap_encoder->output; dssdev; dssdev = dssdev->next) {
-   if (!dssdev->ops->check_timings)
-   continue;
+   unsigned long bus_flags = dssdev->bus_flags;
+
+   if (dssdev->ops->check_timings) {
+   ret = dssdev->ops->check_timings(dssdev, vm);
+   if (ret) {
+   dev_err(dev->dev, "invalid timings: %d\n", ret);
+   return ret;
+   }
+   }
+
+   /*
+* HACK: This fixes the vm flags.
+* struct drm_display_mode does not contain the VSYNC/HSYNC/DE
+* flags and they get lost when converting back and forth
+* between struct drm_display_mode and struct videomode. The
+* hack below goes and fetches the missing flags.
+*

[PATCH v2 19/22] drm/omap: sdi: Fixup video mode in .check_timings() operation

2018-08-06 Thread Laurent Pinchart
The SDI encoder modifies the pixel clock of the requested video mode to
take the limitations of the PLL into account in the .enable() operation.
This should be performed in the .check_timings() operation instead. Move
the fixup.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/sdi.c | 37 ++---
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c 
b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 736a74db3ad5..e98c1b6e3d2d 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -132,10 +132,8 @@ static void sdi_config_lcd_manager(struct sdi_device *sdi)
 static int sdi_display_enable(struct omap_dss_device *dssdev)
 {
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
-   struct videomode *vm = &sdi->vm;
-   unsigned long fck;
struct dispc_clock_info dispc_cinfo;
-   unsigned long pck;
+   unsigned long fck;
int r;
 
if (!sdi->output.dispc_channel_connected) {
@@ -151,23 +149,13 @@ static int sdi_display_enable(struct omap_dss_device 
*dssdev)
if (r)
goto err_get_dispc;
 
-   r = sdi_calc_clock_div(sdi, vm->pixelclock, &fck, &dispc_cinfo);
+   r = sdi_calc_clock_div(sdi, sdi->vm.pixelclock, &fck, &dispc_cinfo);
if (r)
goto err_calc_clock_div;
 
sdi->mgr_config.clock_info = dispc_cinfo;
 
-   pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div;
-
-   if (pck != vm->pixelclock) {
-   DSSWARN("Could not find exact pixel clock. Requested %lu Hz, 
got %lu Hz\n",
-   vm->pixelclock, pck);
-
-   vm->pixelclock = pck;
-   }
-
-
-   dss_mgr_set_timings(&sdi->output, vm);
+   dss_mgr_set_timings(&sdi->output, &sdi->vm);
 
r = dss_set_fck_rate(sdi->dss, fck);
if (r)
@@ -237,9 +225,28 @@ static void sdi_set_timings(struct omap_dss_device *dssdev,
 static int sdi_check_timings(struct omap_dss_device *dssdev,
 struct videomode *vm)
 {
+   struct sdi_device *sdi = dssdev_to_sdi(dssdev);
+   struct dispc_clock_info dispc_cinfo;
+   unsigned long fck;
+   unsigned long pck;
+   int r;
+
if (vm->pixelclock == 0)
return -EINVAL;
 
+   r = sdi_calc_clock_div(sdi, vm->pixelclock, &fck, &dispc_cinfo);
+   if (r)
+   return r;
+
+   pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div;
+
+   if (pck != vm->pixelclock) {
+   DSSWARN("Pixel clock adjusted from %lu Hz to %lu Hz\n",
+   vm->pixelclock, pck);
+
+   vm->pixelclock = pck;
+   }
+
return 0;
 }
 
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 17/22] drm/omap: dsi: Fixup video mode in .set_config() operation

2018-08-06 Thread Laurent Pinchart
The DSI encoder modifies the passed videomode to take the requirements
of the internal DISPC-DSI bus into account in the .enable_video_output()
operation. This should be performed in the .check_timings() operation
instead. There is however no .check_timings() operation as the DSI
encoder uses a custom API, so move it to the closest match which is the
.set_config() operation.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 280f63081224..d1734ea2534a 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3265,7 +3265,7 @@ static void dsi_config_vp_num_line_buffers(struct 
dsi_data *dsi)
 
if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
-   struct videomode *vm = &dsi->vm;
+   const struct videomode *vm = &dsi->vm;
/*
 * Don't use line buffers if width is greater than the video
 * port's line buffer size
@@ -3394,7 +3394,7 @@ static void dsi_config_cmd_mode_interleaving(struct 
dsi_data *dsi)
int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat;
int tclk_trail, ths_exit, exiths_clk;
bool ddr_alwon;
-   struct videomode *vm = &dsi->vm;
+   const struct videomode *vm = &dsi->vm;
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
int ndl = dsi->num_lanes_used - 1;
int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.mX[HSDIV_DSI] + 1;
@@ -3644,7 +3644,7 @@ static void dsi_proto_timings(struct dsi_data *dsi)
int vbp = dsi->vm_timings.vbp;
int window_sync = dsi->vm_timings.window_sync;
bool hsync_end;
-   struct videomode *vm = &dsi->vm;
+   const struct videomode *vm = &dsi->vm;
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
int tl, t_he, width_bytes;
 
@@ -4044,16 +4044,6 @@ static int dsi_display_init_dispc(struct dsi_data *dsi)
dsi->mgr_config.fifohandcheck = false;
}
 
-   /*
-* override interlace, logic level and edge related parameters in
-* videomode with default values
-*/
-   dsi->vm.flags &= ~DISPLAY_FLAGS_INTERLACED;
-   dsi->vm.flags &= ~DISPLAY_FLAGS_HSYNC_LOW;
-   dsi->vm.flags |= DISPLAY_FLAGS_HSYNC_HIGH;
-   dsi->vm.flags &= ~DISPLAY_FLAGS_VSYNC_LOW;
-   dsi->vm.flags |= DISPLAY_FLAGS_VSYNC_HIGH;
-
dss_mgr_set_timings(&dsi->output, &dsi->vm);
 
r = dsi_configure_dispc_clocks(dsi);
@@ -4755,6 +4745,17 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
dsi->user_dispc_cinfo = ctx.dispc_cinfo;
 
dsi->vm = ctx.vm;
+
+   /*
+* override interlace, logic level and edge related parameters in
+* videomode with default values
+*/
+   dsi->vm.flags &= ~DISPLAY_FLAGS_INTERLACED;
+   dsi->vm.flags &= ~DISPLAY_FLAGS_HSYNC_LOW;
+   dsi->vm.flags |= DISPLAY_FLAGS_HSYNC_HIGH;
+   dsi->vm.flags &= ~DISPLAY_FLAGS_VSYNC_LOW;
+   dsi->vm.flags |= DISPLAY_FLAGS_VSYNC_HIGH;
+
dsi->vm_timings = ctx.dsi_vm;
 
mutex_unlock(&dsi->lock);
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 21/22] drm/omap: Store CRTC timings in .set_timings() operation

2018-08-06 Thread Laurent Pinchart
The video timings are stored in the CRTC structure by the
omap_crtc_dss_set_timings() function, called by dss_mgr_set_timings()
from the .enable() operation of the internal encoders. This instead
belongs to the .set_timings() code paths. Move the
omap_crtc_dss_set_timings() calls accordingly.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c   | 4 ++--
 drivers/gpu/drm/omapdrm/dss/dsi.c   | 6 ++
 drivers/gpu/drm/omapdrm/dss/hdmi4.c | 5 ++---
 drivers/gpu/drm/omapdrm/dss/hdmi5.c | 5 ++---
 drivers/gpu/drm/omapdrm/dss/sdi.c   | 4 ++--
 drivers/gpu/drm/omapdrm/dss/venc.c  | 4 ++--
 6 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 2a4ad732679f..223586788648 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -361,8 +361,6 @@ static int dpi_set_mode(struct dpi_data *dpi)
if (r)
return r;
 
-   dss_mgr_set_timings(&dpi->output, vm);
-
return 0;
 }
 
@@ -479,6 +477,8 @@ static void dpi_set_timings(struct omap_dss_device *dssdev,
 
dpi->vm = *vm;
 
+   dss_mgr_set_timings(&dpi->output, vm);
+
mutex_unlock(&dpi->lock);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index d1734ea2534a..394c129cfb3b 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -3901,8 +3901,6 @@ static void dsi_update_screen_dispc(struct dsi_data *dsi)
msecs_to_jiffies(250));
BUG_ON(r == 0);
 
-   dss_mgr_set_timings(&dsi->output, &dsi->vm);
-
dss_mgr_start_update(&dsi->output);
 
if (dsi->te_enabled) {
@@ -4044,8 +4042,6 @@ static int dsi_display_init_dispc(struct dsi_data *dsi)
dsi->mgr_config.fifohandcheck = false;
}
 
-   dss_mgr_set_timings(&dsi->output, &dsi->vm);
-
r = dsi_configure_dispc_clocks(dsi);
if (r)
goto err1;
@@ -4756,6 +4752,8 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
dsi->vm.flags &= ~DISPLAY_FLAGS_VSYNC_LOW;
dsi->vm.flags |= DISPLAY_FLAGS_VSYNC_HIGH;
 
+   dss_mgr_set_timings(&dsi->output, &dsi->vm);
+
dsi->vm_timings = ctx.dsi_vm;
 
mutex_unlock(&dsi->lock);
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 7ad173098c22..df7cfb3e2b12 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -207,9 +207,6 @@ static int hdmi_power_on_full(struct omap_hdmi *hdmi)
 
hdmi4_configure(&hdmi->core, &hdmi->wp, &hdmi->cfg);
 
-   /* tv size */
-   dss_mgr_set_timings(&hdmi->output, vm);
-
r = dss_mgr_enable(&hdmi->output);
if (r)
goto err_mgr_enable;
@@ -262,6 +259,8 @@ static void hdmi_display_set_timings(struct omap_dss_device 
*dssdev,
 
dispc_set_tv_pclk(hdmi->dss->dispc, vm->pixelclock);
 
+   dss_mgr_set_timings(&hdmi->output, vm);
+
mutex_unlock(&hdmi->lock);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 147c3550df51..cb212e5e790f 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -206,9 +206,6 @@ static int hdmi_power_on_full(struct omap_hdmi *hdmi)
 
hdmi5_configure(&hdmi->core, &hdmi->wp, &hdmi->cfg);
 
-   /* tv size */
-   dss_mgr_set_timings(&hdmi->output, vm);
-
r = dss_mgr_enable(&hdmi->output);
if (r)
goto err_mgr_enable;
@@ -261,6 +258,8 @@ static void hdmi_display_set_timings(struct omap_dss_device 
*dssdev,
 
dispc_set_tv_pclk(hdmi->dss->dispc, vm->pixelclock);
 
+   dss_mgr_set_timings(&hdmi->output, vm);
+
mutex_unlock(&hdmi->lock);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c 
b/drivers/gpu/drm/omapdrm/dss/sdi.c
index e98c1b6e3d2d..36edcdbf0609 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -155,8 +155,6 @@ static int sdi_display_enable(struct omap_dss_device 
*dssdev)
 
sdi->mgr_config.clock_info = dispc_cinfo;
 
-   dss_mgr_set_timings(&sdi->output, &sdi->vm);
-
r = dss_set_fck_rate(sdi->dss, fck);
if (r)
goto err_set_dss_clock_div;
@@ -220,6 +218,8 @@ static void sdi_set_timings(struct omap_dss_device *dssdev,
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
 
sdi->vm = *vm;
+
+   dss_mgr_set_timings(&sdi->output, vm);
 }
 
 static int sdi_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index 126efbf89898..39e3c43c54c1 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -491,8 +491,6 @@ static int venc_power_on(struct venc_device *venc)
 
venc_write_reg(venc, VENC_OUTPUT_CONTROL, l);
 

[PATCH v2 03/22] drm/omap: dss: hdmi: Rename hdmi_display_(set|check)_timing() functions

2018-08-06 Thread Laurent Pinchart
The two functions implement the .set_timings() and .check_timings()
operations. Rename them to hdmi_disply_set_timings() and
hdmi_display_check_timings() respectively to match the operations names
and make searching the source code easier.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c |  2 --
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   | 12 ++--
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   | 12 ++--
 3 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index 29bda16afbdc..54f133d7da07 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -92,8 +92,6 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   tfp410_fix_timings(vm);
-
ddata->vm = *vm;
 
src->ops->set_timings(src, vm);
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index c92564300446..73ca79471ce4 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -251,8 +251,8 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi)
hdmi_power_off_core(hdmi);
 }
 
-static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
-struct videomode *vm)
+static int hdmi_display_check_timings(struct omap_dss_device *dssdev,
+ struct videomode *vm)
 {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 
@@ -262,8 +262,8 @@ static int hdmi_display_check_timing(struct omap_dss_device 
*dssdev,
return 0;
 }
 
-static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
-   struct videomode *vm)
+static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
+struct videomode *vm)
 {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 
@@ -508,8 +508,8 @@ static const struct omap_dss_device_ops hdmi_ops = {
.enable = hdmi_display_enable,
.disable= hdmi_display_disable,
 
-   .check_timings  = hdmi_display_check_timing,
-   .set_timings= hdmi_display_set_timing,
+   .check_timings  = hdmi_display_check_timings,
+   .set_timings= hdmi_display_set_timings,
 
.read_edid  = hdmi_read_edid,
 
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 2aaa8ee61662..259cd39d0c1d 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -250,8 +250,8 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi)
hdmi_power_off_core(hdmi);
 }
 
-static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
-struct videomode *vm)
+static int hdmi_display_check_timings(struct omap_dss_device *dssdev,
+ struct videomode *vm)
 {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 
@@ -261,8 +261,8 @@ static int hdmi_display_check_timing(struct omap_dss_device 
*dssdev,
return 0;
 }
 
-static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
-   struct videomode *vm)
+static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
+struct videomode *vm)
 {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 
@@ -502,8 +502,8 @@ static const struct omap_dss_device_ops hdmi_ops = {
.enable = hdmi_display_enable,
.disable= hdmi_display_disable,
 
-   .check_timings  = hdmi_display_check_timing,
-   .set_timings= hdmi_display_set_timing,
+   .check_timings  = hdmi_display_check_timings,
+   .set_timings= hdmi_display_set_timings,
 
.read_edid  = hdmi_read_edid,
 
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 22/22] drm/omap: Don't call .set_timings() operation recursively

2018-08-06 Thread Laurent Pinchart
Instead of calling the .set_timings() operation recursively from the
display device backwards, iterate over the devices manually in the DRM
encoder code. This moves the complexity to a single central location and
simplifies the logic in omap_dss_device drivers.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 .../gpu/drm/omapdrm/displays/connector-analog-tv.c   | 10 --
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c | 10 --
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c| 10 --
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c| 11 ---
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c|  9 -
 drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c |  9 -
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c |  9 -
 .../drm/omapdrm/displays/panel-lgphilips-lb035q02.c  |  9 -
 .../gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c  |  9 -
 .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c   |  9 -
 .../gpu/drm/omapdrm/displays/panel-sony-acx565akm.c  |  9 -
 .../gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c  |  9 -
 .../gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c  |  9 -
 drivers/gpu/drm/omapdrm/dss/dpi.c|  2 --
 drivers/gpu/drm/omapdrm/dss/hdmi4.c  |  2 --
 drivers/gpu/drm/omapdrm/dss/hdmi5.c  |  2 --
 drivers/gpu/drm/omapdrm/dss/sdi.c|  2 --
 drivers/gpu/drm/omapdrm/dss/venc.c   |  2 --
 drivers/gpu/drm/omapdrm/omap_encoder.c   | 20 
 19 files changed, 8 insertions(+), 144 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 4866bf8ed524..28a3ce8f88d2 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -73,22 +73,12 @@ static void tvc_disable(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
-static void tvc_set_timings(struct omap_dss_device *dssdev,
-   const struct videomode *vm)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   src->ops->set_timings(src, vm);
-}
-
 static const struct omap_dss_device_ops tvc_ops = {
.connect= tvc_connect,
.disconnect = tvc_disconnect,
 
.enable = tvc_enable,
.disable= tvc_disable,
-
-   .set_timings= tvc_set_timings,
 };
 
 static int tvc_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index 818a4dc452e0..24b14f44248e 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -78,14 +78,6 @@ static void dvic_disable(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
-static void dvic_set_timings(struct omap_dss_device *dssdev,
-const struct videomode *vm)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   src->ops->set_timings(src, vm);
-}
-
 static int dvic_ddc_read(struct i2c_adapter *adapter,
unsigned char *buf, u16 count, u8 offset)
 {
@@ -192,8 +184,6 @@ static const struct omap_dss_device_ops dvic_ops = {
.enable = dvic_enable,
.disable= dvic_disable,
 
-   .set_timings= dvic_set_timings,
-
.read_edid  = dvic_read_edid,
.detect = dvic_detect,
 
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index a32e4159242d..e602fa4a50a4 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -79,14 +79,6 @@ static void hdmic_disable(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
-static void hdmic_set_timings(struct omap_dss_device *dssdev,
- const struct videomode *vm)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   src->ops->set_timings(src, vm);
-}
-
 static bool hdmic_detect(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -124,8 +116,6 @@ static const struct omap_dss_device_ops hdmic_ops = {
.enable = hdmic_enable,
.disable= hdmic_disable,
 
-   .set_timings= hdmic_set_timings,
-
.detect = hdmic_detect,
.register_hpd_cb= hdmic_register_hpd_cb,
.unregister_hpd_cb  = hdmic_unregister_hpd_cb,
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index bdf796123133..4fefd80f53bb 100644
--- a/drivers/gpu/

[PATCH v2 12/22] drm/omap: panels: Don't modify fixed timings

2018-08-06 Thread Laurent Pinchart
Panels drivers store their timings in a device data structure field that
is initialized at probe time, either from hardcoded values or from
firmware-supplied values. Those timings are then reported through the
.get_timings() operation to construct the panel display mode.

The panel timings are further modified by the .set_timings() operation,
which is called with the timings retrieved by .get_timings(), and
mangled by .check_timings(). The latter potentially adjusts the pixel
clock only.

Conceptually, modifying the panel timings is wrong, as the timings are
an intrinsic property of the panel and should thus be fixed.
Furthermore, modifying them this way at runtime can result in display
modes reported to userspace varying between calls, which is also wrong.

There's no actual need to store the mangled pixel clock value in the
timings. Don't modify the panel timings in the .set_timings() operation,
just forward it to the previous device in the display pipeline.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c| 3 ---
 drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c | 3 ---
 drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c | 3 ---
 drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c  | 3 ---
 drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c | 3 ---
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c | 3 ---
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c | 3 ---
 7 files changed, 21 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c 
b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
index e75600a33c37..95cdfde174aa 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
@@ -96,11 +96,8 @@ static void panel_dpi_disable(struct omap_dss_device *dssdev)
 static void panel_dpi_set_timings(struct omap_dss_device *dssdev,
  const struct videomode *vm)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   ddata->vm = *vm;
-
src->ops->set_timings(src, vm);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c 
b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
index 3c221f7f0598..4e21de0e010d 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
@@ -166,11 +166,8 @@ static void lb035q02_disable(struct omap_dss_device 
*dssdev)
 static void lb035q02_set_timings(struct omap_dss_device *dssdev,
 const struct videomode *vm)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   ddata->vm = *vm;
-
src->ops->set_timings(src, vm);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c 
b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
index 78ff18c4eb46..f6fc7b8e639b 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
@@ -159,11 +159,8 @@ static void nec_8048_disable(struct omap_dss_device 
*dssdev)
 static void nec_8048_set_timings(struct omap_dss_device *dssdev,
 const struct videomode *vm)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   ddata->vm = *vm;
-
src->ops->set_timings(src, vm);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c 
b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
index 47e97dbffc07..51ca92c82e2a 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
@@ -129,11 +129,8 @@ static void sharp_ls_disable(struct omap_dss_device 
*dssdev)
 static void sharp_ls_set_timings(struct omap_dss_device *dssdev,
 const struct videomode *vm)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   ddata->vm = *vm;
-
src->ops->set_timings(src, vm);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c 
b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
index 1ec3b1e2107c..974982c46445 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
@@ -632,11 +632,8 @@ static void acx565akm_disable(struct omap_dss_device 
*dssdev)
 static void acx565akm_set_timings(struct omap_dss_device *dssdev,
  const struct videomode *vm)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   ddata->vm = *vm;
-
src->ops->set_timings(src,

[PATCH v2 02/22] drm/omap: Determine connector type directly in omap_connector.c

2018-08-06 Thread Laurent Pinchart
Instead of determining the connector type from the type of the display's
omap_dss_device and passing it to the omap_connector_init() function,
move the type determination code to omap_connector.c and remove the type
argument to the connector init function. This moves code to a more
natural location, making the driver easier to read.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 29 ++---
 drivers/gpu/drm/omapdrm/omap_connector.h |  5 +++--
 drivers/gpu/drm/omapdrm/omap_drv.c   | 27 ++-
 3 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 92fea0085a9c..06c48a64b745 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -325,10 +325,33 @@ static const struct drm_connector_helper_funcs 
omap_connector_helper_funcs = {
.mode_valid = omap_connector_mode_valid,
 };
 
+static int omap_connector_get_type(struct omap_dss_device *display)
+{
+   switch (display->type) {
+   case OMAP_DISPLAY_TYPE_HDMI:
+   return DRM_MODE_CONNECTOR_HDMIA;
+   case OMAP_DISPLAY_TYPE_DVI:
+   return DRM_MODE_CONNECTOR_DVID;
+   case OMAP_DISPLAY_TYPE_DSI:
+   return DRM_MODE_CONNECTOR_DSI;
+   case OMAP_DISPLAY_TYPE_DPI:
+   case OMAP_DISPLAY_TYPE_DBI:
+   return DRM_MODE_CONNECTOR_DPI;
+   case OMAP_DISPLAY_TYPE_VENC:
+   /* TODO: This could also be composite */
+   return DRM_MODE_CONNECTOR_SVIDEO;
+   case OMAP_DISPLAY_TYPE_SDI:
+   return DRM_MODE_CONNECTOR_LVDS;
+   default:
+   return DRM_MODE_CONNECTOR_Unknown;
+   }
+}
+
 /* initialize connector */
 struct drm_connector *omap_connector_init(struct drm_device *dev,
-   int connector_type, struct omap_dss_device *output,
-   struct omap_dss_device *display, struct drm_encoder *encoder)
+ struct omap_dss_device *output,
+ struct omap_dss_device *display,
+ struct drm_encoder *encoder)
 {
struct drm_connector *connector = NULL;
struct omap_connector *omap_connector;
@@ -348,7 +371,7 @@ struct drm_connector *omap_connector_init(struct drm_device 
*dev,
connector->doublescan_allowed = 0;
 
drm_connector_init(dev, connector, &omap_connector_funcs,
-   connector_type);
+  omap_connector_get_type(display));
drm_connector_helper_add(connector, &omap_connector_helper_funcs);
 
/*
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.h 
b/drivers/gpu/drm/omapdrm/omap_connector.h
index 42ff0a106179..854099801649 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.h
+++ b/drivers/gpu/drm/omapdrm/omap_connector.h
@@ -28,8 +28,9 @@ struct drm_encoder;
 struct omap_dss_device;
 
 struct drm_connector *omap_connector_init(struct drm_device *dev,
-   int connector_type, struct omap_dss_device *output,
-   struct omap_dss_device *display, struct drm_encoder *encoder);
+ 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);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 03771f818eaa..5f98506ac2c5 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -129,28 +129,6 @@ static const struct drm_mode_config_funcs 
omap_mode_config_funcs = {
.atomic_commit = drm_atomic_helper_commit,
 };
 
-static int get_connector_type(struct omap_dss_device *display)
-{
-   switch (display->type) {
-   case OMAP_DISPLAY_TYPE_HDMI:
-   return DRM_MODE_CONNECTOR_HDMIA;
-   case OMAP_DISPLAY_TYPE_DVI:
-   return DRM_MODE_CONNECTOR_DVID;
-   case OMAP_DISPLAY_TYPE_DSI:
-   return DRM_MODE_CONNECTOR_DSI;
-   case OMAP_DISPLAY_TYPE_DPI:
-   case OMAP_DISPLAY_TYPE_DBI:
-   return DRM_MODE_CONNECTOR_DPI;
-   case OMAP_DISPLAY_TYPE_VENC:
-   /* TODO: This could also be composite */
-   return DRM_MODE_CONNECTOR_SVIDEO;
-   case OMAP_DISPLAY_TYPE_SDI:
-   return DRM_MODE_CONNECTOR_LVDS;
-   default:
-   return DRM_MODE_CONNECTOR_Unknown;
-   }
-}
-
 static void omap_disconnect_pipelines(struct drm_device *ddev)
 {
struct omap_drm_private *priv = ddev->dev_private;
@@ -322,9 +300,8 @@ static int om

[PATCH v2 16/22] drm/omap: dpi: Don't fixup video mode in dpi_set_mode()

2018-08-06 Thread Laurent Pinchart
The video mode is aleady fixed up by the .check_timings() operation,
there's no need to repeat that when enabling the DPI output.

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

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index d814d71fffbc..2a4ad732679f 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -347,10 +347,9 @@ static int dpi_set_dispc_clk(struct dpi_data *dpi, 
unsigned long pck_req,
 
 static int dpi_set_mode(struct dpi_data *dpi)
 {
-   struct videomode *vm = &dpi->vm;
+   const struct videomode *vm = &dpi->vm;
int lck_div = 0, pck_div = 0;
unsigned long fck = 0;
-   unsigned long pck;
int r = 0;
 
if (dpi->pll)
@@ -362,15 +361,6 @@ static int dpi_set_mode(struct dpi_data *dpi)
if (r)
return r;
 
-   pck = fck / lck_div / pck_div;
-
-   if (pck != vm->pixelclock) {
-   DSSWARN("Could not find exact pixel clock. Requested %lu Hz, 
got %lu Hz\n",
-   vm->pixelclock, pck);
-
-   vm->pixelclock = pck;
-   }
-
dss_mgr_set_timings(&dpi->output, vm);
 
return 0;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 14/22] drm/omap: Split mode fixup and mode set from encoder enable

2018-08-06 Thread Laurent Pinchart
The encoder enable operation currently performs mode fixup and mode
setting for all omap_dss_device instances in the display pipeline. There
are dedicated encoder operations for those operations (respectively
.atomic_check() and .mode_set()), but they are not used for this
purpose.

Move the mode fixup code to .atomic_check() and the mode set code
.mode_set() to better fit the KMS model. The bus flags fixup has to
happen at .mode_set() time as there is no place to store the bus flags
in the atomic state structures. This could be solved by extending one of
the state structures, but as the goal is to replace the fixup by direct
usage of bus flags through the driver, that would be pointless.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_encoder.c | 148 ++---
 1 file changed, 79 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 82cdcba961a8..0177a2c4b77a 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -53,16 +53,69 @@ static const struct drm_encoder_funcs omap_encoder_funcs = {
 };
 
 static void omap_encoder_mode_set(struct drm_encoder *encoder,
-   struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
 {
struct drm_device *dev = encoder->dev;
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-   struct omap_dss_device *dssdev = omap_encoder->output;
+   struct omap_dss_device *display = omap_encoder->display;
struct drm_connector *connector;
+   struct omap_dss_device *dssdev;
+   struct videomode vm = { 0 };
bool hdmi_mode;
int r;
 
+   drm_display_mode_to_videomode(adjusted_mode, &vm);
+
+   /*
+* HACK: This fixes the vm flags.
+* struct drm_display_mode does not contain the VSYNC/HSYNC/DE flags and
+* they get lost when converting back and forth between struct
+* drm_display_mode and struct videomode. The hack below goes and
+* fetches the missing flags.
+*
+* A better solution is to use DRM's bus-flags through the whole driver.
+*/
+   for (dssdev = omap_encoder->output; dssdev; dssdev = dssdev->next) {
+   unsigned long bus_flags = dssdev->bus_flags;
+
+   if (!(vm.flags & (DISPLAY_FLAGS_DE_LOW |
+ DISPLAY_FLAGS_DE_HIGH))) {
+   if (bus_flags & DRM_BUS_FLAG_DE_LOW)
+   vm.flags |= DISPLAY_FLAGS_DE_LOW;
+   else if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
+   vm.flags |= DISPLAY_FLAGS_DE_HIGH;
+   }
+
+   if (!(vm.flags & (DISPLAY_FLAGS_PIXDATA_POSEDGE |
+ DISPLAY_FLAGS_PIXDATA_NEGEDGE))) {
+   if (bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
+   vm.flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
+   else if (bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
+   vm.flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
+   }
+
+   if (!(vm.flags & (DISPLAY_FLAGS_SYNC_POSEDGE |
+ DISPLAY_FLAGS_SYNC_NEGEDGE))) {
+   if (bus_flags & DRM_BUS_FLAG_SYNC_POSEDGE)
+   vm.flags |= DISPLAY_FLAGS_SYNC_POSEDGE;
+   else if (bus_flags & DRM_BUS_FLAG_SYNC_NEGEDGE)
+   vm.flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
+   }
+   }
+
+   /*
+* HACK: Call the .set_timings() operation if available, this will
+* eventually store timings in the CRTC. Otherwise (for DSI outputs)
+* store the timings directly.
+*
+* All outputs should be brought in sync to operate similarly.
+*/
+   if (display->ops->set_timings)
+   display->ops->set_timings(display, &vm);
+   else
+   *omap_crtc_timings(encoder->crtc) = vm;
+
hdmi_mode = false;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->encoder == encoder) {
@@ -71,6 +124,8 @@ static void omap_encoder_mode_set(struct drm_encoder 
*encoder,
}
}
 
+   dssdev = omap_encoder->output;
+
if (dssdev->ops->hdmi.set_hdmi_mode)
dssdev->ops->hdmi.set_hdmi_mode(dssdev, hdmi_mode);
 
@@ -92,78 +147,12 @@ static void omap_encoder_disable(struct drm_encoder 
*encoder)
dssdev->ops->disable(dssdev);
 }
 
-static int omap_encoder_update(struct drm_encoder *encoder,
-  enum omap_channel 

[PATCH v2 18/22] drm/omap: hdmi: Constify video mode and related pointers

2018-08-06 Thread Laurent Pinchart
Constify many pointers to struct videomode, as well as pointers to
container structures, to ensure the video mode isn't modified after
the .check_timings() operation.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/hdmi.h   | 8 
 drivers/gpu/drm/omapdrm/dss/hdmi4.c  | 2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c  | 2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 6 +++---
 drivers/gpu/drm/omapdrm/dss/hdmi_wp.c| 8 
 5 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h 
b/drivers/gpu/drm/omapdrm/dss/hdmi.h
index 3aeb4cabd59f..7f0dc490a31d 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi.h
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h
@@ -313,13 +313,13 @@ void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 
mask);
 int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val);
 int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val);
 void hdmi_wp_video_config_format(struct hdmi_wp_data *wp,
-   struct hdmi_video_format *video_fmt);
+   const struct hdmi_video_format *video_fmt);
 void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
-   struct videomode *vm);
+   const struct videomode *vm);
 void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
-   struct videomode *vm);
+   const struct videomode *vm);
 void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
-   struct videomode *vm, struct hdmi_config *param);
+   struct videomode *vm, const struct hdmi_config *param);
 int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp,
 unsigned int version);
 phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp);
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 3e2bc85ef538..7ad173098c22 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -154,7 +154,7 @@ static void hdmi_power_off_core(struct omap_hdmi *hdmi)
 static int hdmi_power_on_full(struct omap_hdmi *hdmi)
 {
int r;
-   struct videomode *vm;
+   const struct videomode *vm;
struct hdmi_wp_data *wp = &hdmi->wp;
struct dss_pll_clock_info hdmi_cinfo = { 0 };
unsigned int pc;
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index c02e08299155..147c3550df51 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -153,7 +153,7 @@ static void hdmi_power_off_core(struct omap_hdmi *hdmi)
 static int hdmi_power_on_full(struct omap_hdmi *hdmi)
 {
int r;
-   struct videomode *vm;
+   const struct videomode *vm;
struct dss_pll_clock_info hdmi_cinfo = { 0 };
unsigned int pc;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c
index 2282e48574c6..02efabc7ed76 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c
@@ -287,7 +287,7 @@ void hdmi5_core_dump(struct hdmi_core_data *core, struct 
seq_file *s)
 }
 
 static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg,
-   struct hdmi_config *cfg)
+  const struct hdmi_config *cfg)
 {
DSSDBG("hdmi_core_init\n");
 
@@ -325,10 +325,10 @@ static void hdmi_core_init(struct hdmi_core_vid_config 
*video_cfg,
 
 /* DSS_HDMI_CORE_VIDEO_CONFIG */
 static void hdmi_core_video_config(struct hdmi_core_data *core,
-   struct hdmi_core_vid_config *cfg)
+   const struct hdmi_core_vid_config *cfg)
 {
void __iomem *base = core->base;
-   struct videomode *vm = &cfg->v_fc_config.vm;
+   const struct videomode *vm = &cfg->v_fc_config.vm;
unsigned char r = 0;
bool vsync_pol, hsync_pol;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
index 53bc5f78050c..100efb9f08c6 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
@@ -131,7 +131,7 @@ void hdmi_wp_video_stop(struct hdmi_wp_data *wp)
 }
 
 void hdmi_wp_video_config_format(struct hdmi_wp_data *wp,
-   struct hdmi_video_format *video_fmt)
+   const struct hdmi_video_format *video_fmt)
 {
u32 l = 0;
 
@@ -144,7 +144,7 @@ void hdmi_wp_video_config_format(struct hdmi_wp_data *wp,
 }
 
 void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
-   struct videomode *vm)
+   const struct videomode *vm)
 {
u32 r;
bool vsync_inv, hsync_inv;
@@ -164,7 +164,7 @@ void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
 }
 
 void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
-struct videomode *vm)
+ 

[PATCH v2 15/22] drm/omap: Call dispc timings check operation directly

2018-08-06 Thread Laurent Pinchart
Instead of call the dispc timings check function dispc_mgr_timings_ok()
from the internal encoders .check_timings() operation, expose it through
the dispc ops (after renaming it to check_timings) and call it directly
from omapdrm. This allows removal of now empty omap_dss_device
.check_timings() operations.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dispc.c  | 18 ++
 drivers/gpu/drm/omapdrm/dss/dpi.c|  4 
 drivers/gpu/drm/omapdrm/dss/dss.h|  3 ---
 drivers/gpu/drm/omapdrm/dss/hdmi4.c  | 12 
 drivers/gpu/drm/omapdrm/dss/hdmi5.c  | 12 
 drivers/gpu/drm/omapdrm/dss/omapdss.h|  3 +++
 drivers/gpu/drm/omapdrm/dss/sdi.c|  6 --
 drivers/gpu/drm/omapdrm/omap_connector.c |  6 ++
 drivers/gpu/drm/omapdrm/omap_encoder.c   | 18 +-
 9 files changed, 32 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c 
b/drivers/gpu/drm/omapdrm/dss/dispc.c
index da95dbfdf790..e61a9592a650 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -3113,28 +3113,29 @@ static bool _dispc_mgr_pclk_ok(struct dispc_device 
*dispc,
return pclk <= dispc->feat->max_tv_pclk;
 }
 
-bool dispc_mgr_timings_ok(struct dispc_device *dispc, enum omap_channel 
channel,
- const struct videomode *vm)
+static int dispc_mgr_check_timings(struct dispc_device *dispc,
+  enum omap_channel channel,
+  const struct videomode *vm)
 {
if (!_dispc_mgr_size_ok(dispc, vm->hactive, vm->vactive))
-   return false;
+   return MODE_BAD;
 
if (!_dispc_mgr_pclk_ok(dispc, channel, vm->pixelclock))
-   return false;
+   return MODE_BAD;
 
if (dss_mgr_is_lcd(channel)) {
/* TODO: OMAP4+ supports interlace for LCD outputs */
if (vm->flags & DISPLAY_FLAGS_INTERLACED)
-   return false;
+   return MODE_BAD;
 
if (!_dispc_lcd_timings_ok(dispc, vm->hsync_len,
vm->hfront_porch, vm->hback_porch,
vm->vsync_len, vm->vfront_porch,
vm->vback_porch))
-   return false;
+   return MODE_BAD;
}
 
-   return true;
+   return MODE_OK;
 }
 
 static void _dispc_mgr_set_lcd_timings(struct dispc_device *dispc,
@@ -3236,7 +3237,7 @@ static void dispc_mgr_set_timings(struct dispc_device 
*dispc,
 
DSSDBG("channel %d xres %u yres %u\n", channel, t.hactive, t.vactive);
 
-   if (!dispc_mgr_timings_ok(dispc, channel, &t)) {
+   if (dispc_mgr_check_timings(dispc, channel, &t)) {
BUG();
return;
}
@@ -4733,6 +4734,7 @@ static const struct dispc_ops dispc_ops = {
.mgr_go_busy = dispc_mgr_go_busy,
.mgr_go = dispc_mgr_go,
.mgr_set_lcd_config = dispc_mgr_set_lcd_config,
+   .mgr_check_timings = dispc_mgr_check_timings,
.mgr_set_timings = dispc_mgr_set_timings,
.mgr_setup = dispc_mgr_setup,
.mgr_gamma_size = dispc_mgr_gamma_size,
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 58237decb5a8..d814d71fffbc 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -496,7 +496,6 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
 struct videomode *vm)
 {
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
-   enum omap_channel channel = dpi->output.dispc_channel;
int lck_div, pck_div;
unsigned long fck;
unsigned long pck;
@@ -506,9 +505,6 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
if (vm->hactive % 8 != 0)
return -EINVAL;
 
-   if (!dispc_mgr_timings_ok(dpi->dss->dispc, channel, vm))
-   return -EINVAL;
-
if (vm->pixelclock == 0)
return -EINVAL;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h 
b/drivers/gpu/drm/omapdrm/dss/dss.h
index ee06051933c5..37790c363128 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -417,9 +417,6 @@ bool dispc_div_calc(struct dispc_device *dispc, unsigned 
long dispc_freq,
unsigned long pck_min, unsigned long pck_max,
dispc_div_calc_func func, void *data);
 
-bool dispc_mgr_timings_ok(struct dispc_device *dispc,
- enum omap_channel channel,
- const struct videomode *vm);
 int dispc_calc_clock_rates(struct dispc_device *dispc,
   unsigned long dispc_fclk_rate,
   struct dispc_clock_info *cinfo);
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi

[PATCH v2 06/22] drm/omap: Remove unneeded fallback for missing .check_timings()

2018-08-06 Thread Laurent Pinchart
The .check_timings() operation is present in all panels and connectors.
The fallback that uses .get_timings() in the absence of .check_timings()
is thus unneeded.

While it could be argued that the fallback implements a useful check
that should be extended to cover all fixed-resolution panels, the code
is currently unused and gets in the way of the ongoing refactoring.
Remove it, a similar feature can always be added later.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 25 +
 drivers/gpu/drm/omapdrm/omap_encoder.c   | 16 ++--
 2 files changed, 3 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 06c48a64b745..b58d9a0bb53d 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -261,30 +261,7 @@ static int omap_connector_mode_valid(struct drm_connector 
*connector,
drm_display_mode_to_videomode(mode, &vm);
mode->vrefresh = drm_mode_vrefresh(mode);
 
-   /*
-* if the panel driver doesn't have a check_timings, it's most likely
-* a fixed resolution panel, check if the timings match with the
-* panel's timings
-*/
-   if (dssdev->ops->check_timings) {
-   r = dssdev->ops->check_timings(dssdev, &vm);
-   } else {
-   struct videomode t = {0};
-
-   dssdev->ops->get_timings(dssdev, &t);
-
-   /*
-* Ignore the flags, as we don't get them from
-* drm_display_mode_to_videomode.
-*/
-   t.flags = 0;
-
-   if (memcmp(&vm, &t, sizeof(vm)))
-   r = -EINVAL;
-   else
-   r = 0;
-   }
-
+   r = dssdev->ops->check_timings(dssdev, &vm);
if (!r) {
/* check if vrefresh is still valid */
new_mode = drm_mode_duplicate(dev, mode);
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 94b75d018e71..a6dce480b2cf 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -101,21 +101,9 @@ static int omap_encoder_update(struct drm_encoder *encoder,
struct omap_dss_device *dssdev = omap_encoder->display;
int ret;
 
-   if (dssdev->ops->check_timings) {
-   ret = dssdev->ops->check_timings(dssdev, vm);
-   } else {
-   struct videomode t = {0};
-
-   dssdev->ops->get_timings(dssdev, &t);
-
-   if (memcmp(vm, &t, sizeof(*vm)))
-   ret = -EINVAL;
-   else
-   ret = 0;
-   }
-
+   ret = dssdev->ops->check_timings(dssdev, vm);
if (ret) {
-   dev_err(dev->dev, "could not set timings: %d\n", ret);
+   dev_err(dev->dev, "invalid timings: %d\n", ret);
return ret;
}
 
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 09/22] drm/omap: Don't call .check_timings() operation recursively

2018-08-06 Thread Laurent Pinchart
The .check_timings() operation is called recursively from the display
device back to the output device. Most components just forward the
operation to the previous component in the chain, resulting in lots of
duplicated pass-through functions. To avoid that, iterate over the
components manually.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 .../gpu/drm/omapdrm/displays/connector-analog-tv.c |  9 --
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  9 --
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  |  9 --
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c  | 11 
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c  |  9 --
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   |  9 --
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c   |  9 --
 .../omapdrm/displays/panel-lgphilips-lb035q02.c|  9 --
 .../drm/omapdrm/displays/panel-nec-nl8048hl11.c|  9 --
 .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c |  9 --
 .../drm/omapdrm/displays/panel-sony-acx565akm.c|  9 --
 .../drm/omapdrm/displays/panel-tpo-td028ttec1.c|  9 --
 .../drm/omapdrm/displays/panel-tpo-td043mtea1.c|  9 --
 drivers/gpu/drm/omapdrm/omap_connector.c   | 32 +-
 drivers/gpu/drm/omapdrm/omap_encoder.c | 20 +-
 15 files changed, 32 insertions(+), 139 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index fb6d4fce1853..a9e2a366a851 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -109,14 +109,6 @@ static void tvc_get_timings(struct omap_dss_device *dssdev,
*vm = ddata->vm;
 }
 
-static int tvc_check_timings(struct omap_dss_device *dssdev,
-struct videomode *vm)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   return src->ops->check_timings(src, vm);
-}
-
 static const struct omap_dss_device_ops tvc_ops = {
.connect= tvc_connect,
.disconnect = tvc_disconnect,
@@ -126,7 +118,6 @@ static const struct omap_dss_device_ops tvc_ops = {
 
.set_timings= tvc_set_timings,
.get_timings= tvc_get_timings,
-   .check_timings  = tvc_check_timings,
 };
 
 static int tvc_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index 5871872ae19b..a9e2f1181987 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -116,14 +116,6 @@ static void dvic_get_timings(struct omap_dss_device 
*dssdev,
*vm = ddata->vm;
 }
 
-static int dvic_check_timings(struct omap_dss_device *dssdev,
- struct videomode *vm)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   return src->ops->check_timings(src, vm);
-}
-
 static int dvic_ddc_read(struct i2c_adapter *adapter,
unsigned char *buf, u16 count, u8 offset)
 {
@@ -232,7 +224,6 @@ static const struct omap_dss_device_ops dvic_ops = {
 
.set_timings= dvic_set_timings,
.get_timings= dvic_get_timings,
-   .check_timings  = dvic_check_timings,
 
.read_edid  = dvic_read_edid,
.detect = dvic_detect,
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 898eb583688f..7e449f8a9b5d 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -114,14 +114,6 @@ static void hdmic_get_timings(struct omap_dss_device 
*dssdev,
*vm = ddata->vm;
 }
 
-static int hdmic_check_timings(struct omap_dss_device *dssdev,
-  struct videomode *vm)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   return src->ops->check_timings(src, vm);
-}
-
 static bool hdmic_detect(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -161,7 +153,6 @@ static const struct omap_dss_device_ops hdmic_ops = {
 
.set_timings= hdmic_set_timings,
.get_timings= hdmic_get_timings,
-   .check_timings  = hdmic_check_timings,
 
.detect = hdmic_detect,
.register_hpd_cb= hdmic_register_hpd_cb,
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index 05d128600712..bdf796123133 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -95,22 +95,11 @@ static void opa362_set_timings(struct omap_dss_device 
*dssdev,
src->ops->set_timings(src, vm);
 }
 
-static int opa362_check_timings(struct omap_dss_d

[PATCH v2 01/22] drm/omap: Pass both output and display omap_dss_device to connector init

2018-08-06 Thread Laurent Pinchart
The drm_connector implementation requires access to the omap_dss_device
corresponding to the display, which is passed to its initialization
function and stored internally. Refactoring of the timings operations
will require access to the output omap_dss_device. To prepare for that,
pass it to the connector initialization function and store it internally
as well.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 30 +-
 drivers/gpu/drm/omapdrm/omap_connector.h |  4 ++--
 drivers/gpu/drm/omapdrm/omap_drv.c   |  3 ++-
 3 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 5091991363d6..92fea0085a9c 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -29,7 +29,8 @@
 
 struct omap_connector {
struct drm_connector base;
-   struct omap_dss_device *dssdev;
+   struct omap_dss_device *output;
+   struct omap_dss_device *display;
struct omap_dss_device *hpd;
bool hdmi_mode;
 };
@@ -104,7 +105,7 @@ omap_connector_find_device(struct drm_connector *connector,
struct omap_connector *omap_connector = to_omap_connector(connector);
struct omap_dss_device *dssdev;
 
-   for (dssdev = omap_connector->dssdev; dssdev; dssdev = dssdev->src) {
+   for (dssdev = omap_connector->display; dssdev; dssdev = dssdev->src) {
if (dssdev->ops_flags & op)
return dssdev;
}
@@ -129,7 +130,7 @@ static enum drm_connector_status omap_connector_detect(
 
omap_connector_hpd_notify(connector, dssdev->src, status);
} else {
-   switch (omap_connector->dssdev->type) {
+   switch (omap_connector->display->type) {
case OMAP_DISPLAY_TYPE_DPI:
case OMAP_DISPLAY_TYPE_DBI:
case OMAP_DISPLAY_TYPE_SDI:
@@ -142,7 +143,7 @@ static enum drm_connector_status omap_connector_detect(
}
}
 
-   VERB("%s: %d (force=%d)", omap_connector->dssdev->name, status, force);
+   VERB("%s: %d (force=%d)", omap_connector->display->name, status, force);
 
return status;
 }
@@ -151,7 +152,7 @@ static void omap_connector_destroy(struct drm_connector 
*connector)
 {
struct omap_connector *omap_connector = to_omap_connector(connector);
 
-   DBG("%s", omap_connector->dssdev->name);
+   DBG("%s", omap_connector->display->name);
 
if (omap_connector->hpd) {
struct omap_dss_device *hpd = omap_connector->hpd;
@@ -165,7 +166,8 @@ static void omap_connector_destroy(struct drm_connector 
*connector)
drm_connector_cleanup(connector);
kfree(omap_connector);
 
-   omapdss_device_put(omap_connector->dssdev);
+   omapdss_device_put(omap_connector->output);
+   omapdss_device_put(omap_connector->display);
 }
 
 #define MAX_EDID  512
@@ -212,7 +214,7 @@ static int omap_connector_get_modes(struct drm_connector 
*connector)
struct drm_display_mode *mode;
struct videomode vm = {0};
 
-   DBG("%s", omap_connector->dssdev->name);
+   DBG("%s", omap_connector->display->name);
 
/*
 * If display exposes EDID, then we parse that in the normal way to
@@ -229,7 +231,7 @@ static int omap_connector_get_modes(struct drm_connector 
*connector)
if (!mode)
return 0;
 
-   dssdev = omap_connector->dssdev;
+   dssdev = omap_connector->display;
dssdev->ops->get_timings(dssdev, &vm);
 
drm_display_mode_from_videomode(&vm, mode);
@@ -250,7 +252,7 @@ static int omap_connector_mode_valid(struct drm_connector 
*connector,
 struct drm_display_mode *mode)
 {
struct omap_connector *omap_connector = to_omap_connector(connector);
-   struct omap_dss_device *dssdev = omap_connector->dssdev;
+   struct omap_dss_device *dssdev = omap_connector->display;
struct videomode vm = {0};
struct drm_device *dev = connector->dev;
struct drm_display_mode *new_mode;
@@ -325,19 +327,21 @@ static const struct drm_connector_helper_funcs 
omap_connector_helper_funcs = {
 
 /* initialize connector */
 struct drm_connector *omap_connector_init(struct drm_device *dev,
-   int connector_type, struct omap_dss_device *dssdev,
-   struct drm_encoder *encoder)
+   int connector_type, struct omap_dss_device *output,
+   struct omap_dss_device *display, struct drm_encoder *encoder)
 {
struct drm_connector *connector = NULL;
struct omap_connector *omap_connector;
+   struct omap_dss_device *dssdev;
 
-   DBG("%s", dssdev->name);
+   DBG("%s", display->name);
 
omap_connector = kzalloc(sizeof(*omap_connector), GFP_KERNEL);
if (!omap_connector)
 

[PATCH v2 11/22] drm/omap: Remove .get_timings() operation from display connectors

2018-08-06 Thread Laurent Pinchart
The analog TV, DVI and HDMI connectors all report timing information
through the .get_timings() information.

For analog TV outputs the information is queried from the encoder, so
the operation is unused. Remove it.

For HDMI outputs the display pipeline provides EDID capability, so the
operation is unused as well. Remove it.

For DVI outputs the operation is also unused if the pipeline provides
EDID capability. Otherwise (when the DDC bus is not connected) we
shouldn't hardcode a single mode, but instead report no mode and let the
KMS core add default modes. This is achieved by removing the operation.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 .../gpu/drm/omapdrm/displays/connector-analog-tv.c | 31 
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   | 33 --
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  | 30 
 3 files changed, 94 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index a9e2a366a851..4866bf8ed524 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -20,23 +20,6 @@ struct panel_drv_data {
struct omap_dss_device dssdev;
 
struct device *dev;
-
-   struct videomode vm;
-};
-
-static const struct videomode tvc_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,
 };
 
 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
@@ -93,22 +76,11 @@ static void tvc_disable(struct omap_dss_device *dssdev)
 static void tvc_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   ddata->vm = *vm;
-
src->ops->set_timings(src, vm);
 }
 
-static void tvc_get_timings(struct omap_dss_device *dssdev,
-   struct videomode *vm)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-
-   *vm = ddata->vm;
-}
-
 static const struct omap_dss_device_ops tvc_ops = {
.connect= tvc_connect,
.disconnect = tvc_disconnect,
@@ -117,7 +89,6 @@ static const struct omap_dss_device_ops tvc_ops = {
.disable= tvc_disable,
 
.set_timings= tvc_set_timings,
-   .get_timings= tvc_get_timings,
 };
 
 static int tvc_probe(struct platform_device *pdev)
@@ -132,8 +103,6 @@ static int tvc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
ddata->dev = &pdev->dev;
 
-   ddata->vm = tvc_pal_vm;
-
dssdev = &ddata->dssdev;
dssdev->ops = &tvc_ops;
dssdev->dev = &pdev->dev;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index a9e2f1181987..818a4dc452e0 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -19,28 +19,9 @@
 
 #include "../dss/omapdss.h"
 
-static const struct videomode dvic_default_vm = {
-   .hactive= 640,
-   .vactive= 480,
-
-   .pixelclock = 2350,
-
-   .hfront_porch   = 48,
-   .hsync_len  = 32,
-   .hback_porch= 80,
-
-   .vfront_porch   = 3,
-   .vsync_len  = 4,
-   .vback_porch= 7,
-
-   .flags  = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH,
-};
-
 struct panel_drv_data {
struct omap_dss_device dssdev;
 
-   struct videomode vm;
-
struct i2c_adapter *i2c_adapter;
 
struct gpio_desc *hpd_gpio;
@@ -100,22 +81,11 @@ static void dvic_disable(struct omap_dss_device *dssdev)
 static void dvic_set_timings(struct omap_dss_device *dssdev,
 const struct videomode *vm)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   ddata->vm = *vm;
-
src->ops->set_timings(src, vm);
 }
 
-static void dvic_get_timings(struct omap_dss_device *dssdev,
-struct videomode *vm)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-
-   *vm = ddata->vm;
-}
-
 static int dvic_ddc_read(struct i2c_adapter *adapter,
unsigned char *buf, u16 count, u8 offset)
 {
@@ -223,7 +193,6 @@ static const struct omap_dss_device_ops dvic_ops = {
.disable= dvic_disable,
 
.set_timings= dvic_set_t

[PATCH v2 00/22] omapdrm: Rework the timing-related operations

2018-08-06 Thread Laurent Pinchart
Hello,

This patch series reworks all the timing-related operations (.get_timings(),
.set_timings() and .check_timings()) as a step toward moving from
omap_dss_device to drm_bridge.

All timing-related operations are called by the omapdrm driver on the
omap_dss_device at the end of display pipeline, and the operations are then
handled directly or forwarded to the previous omap_dss_device in the pipeline.
This causes an issue in our quest to move to drm_bridge: the drm_bridge
equivalent to the timing operations, .mode_valid(), .mode_fixup() and
.mode_set(), are called in the source to sink direction.

Furthermore, timing handling in the omapdrm driver is very complicated, with
timings getting mangled, stored in random places, retrieved back by unrelated
code, mangled again, stored in different places, and modified across objects.
Simplifying that is crucial to move to drm_bridge.

This patch series simplifies the timings operation and reverse the direction
in which they're called. The driver still uses the videomode structure instead
of the drm_display_mode structure to store timing information, this will be
fixed in a second step.

The series is really a succession of cleanups interleaved with the real
changes, with a total of 406 lines of code removed overall. It starts with
small changes, cleanups and code removal in patches 01/22 to 07/22. Patches
08/22 and 09/22 start reworking the .check_timings() operation by making use
of the bus flags. Patches 10/22 to 12/22 rework the .get_timings() operation,
and patches 13/22 to 20/22 complete the .check_timings() rework. Patches 21/22
and 22/22 finally rework the .set_timings() operation.

The series is based on top of the previously submitted "[PATCH v2 00/21]
omapdrm: Rework the HPD-related operations" patch series. For convenience I've
pushed it to my tree at

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

Since v1 patch "drm: Add display info bus flags to specify sync signals clock
edges" has been dropped as a competing implementation has been merged in the
DRM tree.

Laurent Pinchart (22):
  drm/omap: Pass both output and display omap_dss_device to connector
init
  drm/omap: Determine connector type directly in omap_connector.c
  drm/omap: dss: hdmi: Rename hdmi_display_(set|check)_timing()
functions
  drm/omap: Make the video_mode pointer to .set_timings() const
  drm/omap: Remove duplicate calls to .set_timings() operation
  drm/omap: Remove unneeded fallback for missing .check_timings()
  drm/omap: Don't store video mode internally for external encoders
  drm/omap: Store bus flags in the omap_dss_device structure
  drm/omap: Don't call .check_timings() operation recursively
  drm/omap: Query timing information from analog TV encoder
  drm/omap: Remove .get_timings() operation from display connectors
  drm/omap: panels: Don't modify fixed timings
  drm/omap: Move bus flag hack to encoder implementation
  drm/omap: Split mode fixup and mode set from encoder enable
  drm/omap: Call dispc timings check operation directly
  drm/omap: dpi: Don't fixup video mode in dpi_set_mode()
  drm/omap: dsi: Fixup video mode in .set_config() operation
  drm/omap: hdmi: Constify video mode and related pointers
  drm/omap: sdi: Fixup video mode in .check_timings() operation
  drm/omap: venc: Fixup video mode in .check_timings() operation
  drm/omap: Store CRTC timings in .set_timings() operation
  drm/omap: Don't call .set_timings() operation recursively

 .../gpu/drm/omapdrm/displays/connector-analog-tv.c |  52 
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  57 -
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  |  51 
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c  |  29 -
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c  |  37 +-
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   |  26 
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c   |  23 
 .../omapdrm/displays/panel-lgphilips-lb035q02.c|  40 ++
 .../drm/omapdrm/displays/panel-nec-nl8048hl11.c|  29 +
 .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c |  38 ++
 .../drm/omapdrm/displays/panel-sony-acx565akm.c|  29 +
 .../drm/omapdrm/displays/panel-tpo-td028ttec1.c|  38 ++
 .../drm/omapdrm/displays/panel-tpo-td043mtea1.c|  38 ++
 drivers/gpu/drm/omapdrm/dss/dispc.c|  18 +--
 drivers/gpu/drm/omapdrm/dss/dpi.c  |  20 +--
 drivers/gpu/drm/omapdrm/dss/dsi.c  |  42 +++
 drivers/gpu/drm/omapdrm/dss/dss.h  |   3 -
 drivers/gpu/drm/omapdrm/dss/hdmi.h |   8 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4.c|  23 +---
 drivers/gpu/drm/omapdrm/dss/hdmi5.c|  23 +---
 drivers/gpu/drm/omapdrm/dss/hdmi5_core.c   |   6 +-
 drivers/gpu/drm/omapdrm/dss/hdmi_wp.c  |   8 +-
 drivers/gpu/drm/omapdrm/dss/omapdss.h  |   6 +-
 drivers/gpu/drm/omapdrm/dss/sdi.c 

[PATCH v2 10/22] drm/omap: Query timing information from analog TV encoder

2018-08-06 Thread Laurent Pinchart
Timings for the TV output are currently reported by the analog TV
connector. This has the disadvantage of having to handle timing-related
operations in a connector omap_dss_device that has, at the hardware
level, no knowledge of any timing information.

Implement the .get_timings() operation in the venc driver, and get
timings from the first component in the pipeline that implements the
operatation. This switches the duty of reporting analog TV timings from
the connector to the encoder.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/venc.c   | 12 +++
 drivers/gpu/drm/omapdrm/omap_connector.c | 34 +++-
 2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index 255bf2cd8afc..09ec8b0eafee 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -568,6 +568,16 @@ static void venc_display_disable(struct omap_dss_device 
*dssdev)
mutex_unlock(&venc->venc_lock);
 }
 
+static void venc_get_timings(struct omap_dss_device *dssdev,
+struct videomode *vm)
+{
+   struct venc_device *venc = dssdev_to_venc(dssdev);
+
+   mutex_lock(&venc->venc_lock);
+   *vm = venc->vm;
+   mutex_unlock(&venc->venc_lock);
+}
+
 static void venc_set_timings(struct omap_dss_device *dssdev,
 const struct videomode *vm)
 {
@@ -720,6 +730,7 @@ static const struct omap_dss_device_ops venc_ops = {
.disable = venc_display_disable,
 
.check_timings = venc_check_timings,
+   .get_timings = venc_get_timings,
.set_timings = venc_set_timings,
 };
 
@@ -877,6 +888,7 @@ 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);
venc->base = devm_ioremap_resource(&pdev->dev, venc_mem);
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 302f2ed245d0..b8317b697083 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -218,20 +218,41 @@ static int omap_connector_get_modes(struct drm_connector 
*connector)
 
/*
 * If display exposes EDID, then we parse that in the normal way to
-* build table of supported modes. Otherwise (ie. fixed resolution
-* LCD panels) we just return a single mode corresponding to the
-* currently configured timings.
+* build table of supported modes.
 */
dssdev = omap_connector_find_device(connector,
OMAP_DSS_DEVICE_OP_EDID);
if (dssdev)
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);
+
+   /*
+* Iterate over the pipeline to find the first device that can provide
+* timing information. If we can't find any, we just let the KMS core
+* add the default modes.
+*/
+   for (dssdev = omap_connector->display; dssdev; dssdev = dssdev->src) {
+   if (dssdev->ops->get_timings)
+   break;
+   }
+   if (!dssdev)
+   return 0;
+
+   /* Add a single mode corresponding to the fixed panel timings. */
mode = drm_mode_create(connector->dev);
if (!mode)
return 0;
 
-   dssdev = omap_connector->display;
dssdev->ops->get_timings(dssdev, &vm);
 
drm_display_mode_from_videomode(&vm, mode);
@@ -240,11 +261,6 @@ static int omap_connector_get_modes(struct drm_connector 
*connector)
drm_mode_set_name(mode);
drm_mode_probed_add(connector, mode);
 
-   if (dssdev->driver && dssdev->driver->get_size)
-   dssdev->driver->get_size(dssdev,
-&connector->display_info.width_mm,
-&connector->display_info.height_mm);
-
return 1;
 }
 
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 08/22] drm/omap: Store bus flags in the omap_dss_device structure

2018-08-06 Thread Laurent Pinchart
Source components in the display pipeline need to configure their output
signals polarities and clock driving edge based on the requirements of
the sink component.

Those requirements are currently shared across the whole pipeline in the
flags of a videomode structure, instead of being local to each bus. This
both prevents multiple buses from having different configurations (when
the hardware supports it), and makes it difficult to move from videomode
to drm_display_mode as the latter doesn't contain bus polarities and
clock edge flags.

Add a bus_flags field to the omap_dss_device structure and move the
DISPLAY_FLAGS_DE_(LOW|HIGH), DISPLAY_FLAGS_PIXDATA_(POS|NEG)EDGE and
DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE videomode flags to bus_flags in all
external encoders, connectors and panels. The videomode flags are still
used internally for internal encoders, this will be addressed in a
second step.

The related videomode flags in the default mode of the DVI connector can
simply be dropped, as they are always overridden by the TFP410 driver.
Note that this results in both the DISPLAY_FLAGS_SYNC_POSEDGE and
DISPLAY_FLAGS_SYNC_NEGEDGE flags being set, which is invalid, but only
the former is tested for when programming the DISPC, so the DVI
connector flags are effectively overridden by the TFP410 flags.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  4 +--
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c  | 10 ++
 .../omapdrm/displays/panel-lgphilips-lb035q02.c| 17 -
 .../drm/omapdrm/displays/panel-nec-nl8048hl11.c|  6 ++--
 .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c | 15 
 .../drm/omapdrm/displays/panel-sony-acx565akm.c|  6 ++--
 .../drm/omapdrm/displays/panel-tpo-td028ttec1.c| 15 
 .../drm/omapdrm/displays/panel-tpo-td043mtea1.c| 15 
 drivers/gpu/drm/omapdrm/dss/dsi.c  |  9 ++---
 drivers/gpu/drm/omapdrm/dss/omapdss.h  |  1 +
 drivers/gpu/drm/omapdrm/dss/sdi.c  |  5 ++-
 drivers/gpu/drm/omapdrm/omap_crtc.c| 42 --
 12 files changed, 79 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index b89555ed53a0..5871872ae19b 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -33,9 +33,7 @@ static const struct videomode dvic_default_vm = {
.vsync_len  = 4,
.vback_porch= 7,
 
-   .flags  = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH |
- DISPLAY_FLAGS_SYNC_NEGEDGE | DISPLAY_FLAGS_DE_HIGH |
- DISPLAY_FLAGS_PIXDATA_POSEDGE,
+   .flags  = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH,
 };
 
 struct panel_drv_data {
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index 86c90c15681e..56b78cd38701 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -76,12 +76,6 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
-static void tfp410_fix_timings(struct videomode *vm)
-{
-   vm->flags |= DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
-DISPLAY_FLAGS_SYNC_POSEDGE;
-}
-
 static void tfp410_set_timings(struct omap_dss_device *dssdev,
   const struct videomode *vm)
 {
@@ -95,8 +89,6 @@ static int tfp410_check_timings(struct omap_dss_device 
*dssdev,
 {
struct omap_dss_device *src = dssdev->src;
 
-   tfp410_fix_timings(vm);
-
return src->ops->check_timings(src, vm);
 }
 
@@ -137,6 +129,8 @@ static int tfp410_probe(struct platform_device *pdev)
dssdev->output_type = OMAP_DISPLAY_TYPE_DVI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(1) | BIT(0);
+   dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_POSEDGE
+ | DRM_BUS_FLAG_PIXDATA_POSEDGE;
 
dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1);
if (IS_ERR(dssdev->next)) {
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c 
b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
index ffa69fd44d87..a211506506c0 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
@@ -33,14 +33,7 @@ static const struct videomode lb035q02_vm = {
.vfront_porch   = 4,
.vback_porch= 18,
 
-   .flags  = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
- DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_SYNC_NEGEDGE |
- DISPLAY_FLAGS_PIXDATA_POSEDGE,
-   /*
- 

[PATCH v2 04/22] drm/omap: Make the video_mode pointer to .set_timings() const

2018-08-06 Thread Laurent Pinchart
The .set_timings() operations of the omap_dss_device instances don't
need to modify the passed timings. Make the pointer const.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c  | 2 +-
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c| 2 +-
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c   | 2 +-
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c   | 2 +-
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c   | 2 +-
 drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c| 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c| 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c  | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c | 2 +-
 drivers/gpu/drm/omapdrm/dss/dpi.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   | 2 +-
 drivers/gpu/drm/omapdrm/dss/sdi.c   | 2 +-
 drivers/gpu/drm/omapdrm/dss/venc.c  | 2 +-
 19 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 563fc7e618b3..22bc2e734b0b 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -93,7 +93,7 @@ static void tvc_disable(struct omap_dss_device *dssdev)
 }
 
 static void tvc_set_timings(struct omap_dss_device *dssdev,
-   struct videomode *vm)
+   const struct videomode *vm)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index eae4108330f1..8f953303ece6 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -103,7 +103,7 @@ static void dvic_disable(struct omap_dss_device *dssdev)
 }
 
 static void dvic_set_timings(struct omap_dss_device *dssdev,
-struct videomode *vm)
+const struct videomode *vm)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index fe6d2923ed81..1cbc593c79ff 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -98,7 +98,7 @@ static void hdmic_disable(struct omap_dss_device *dssdev)
 }
 
 static void hdmic_set_timings(struct omap_dss_device *dssdev,
- struct videomode *vm)
+ const struct videomode *vm)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index 3243e5f9bd06..19d1804e3fe5 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -90,7 +90,7 @@ static void opa362_disable(struct omap_dss_device *dssdev)
 }
 
 static void opa362_set_timings(struct omap_dss_device *dssdev,
-  struct videomode *vm)
+  const struct videomode *vm)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index 54f133d7da07..fa6ed1e8649d 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -87,7 +87,7 @@ static void tfp410_fix_timings(struct videomode *vm)
 }
 
 static void tfp410_set_timings(struct omap_dss_device *dssdev,
-  struct videomode *vm)
+  const struct videomode *vm)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index babaac856067..21c2667f9f06 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displa

[PATCH v2 05/22] drm/omap: Remove duplicate calls to .set_timings() operation

2018-08-06 Thread Laurent Pinchart
The omap_dss_device .set_timings() operations are called directly from
omap_encoder_update(), and indirectly from the omap_dss_device .enable()
operation. The latter is called from omap_encoder_enable(), right after
calling omap_encoder_update(). The .set_timings() operation it thus
called twice in a row. Fix it by removing the indirect call.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c  | 2 --
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c| 3 ---
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c   | 2 --
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c   | 2 --
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c   | 2 --
 drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c| 3 ---
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c| 2 --
 drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c | 2 --
 drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c | 2 --
 drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c  | 2 --
 drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c | 2 --
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c | 2 --
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c | 2 --
 13 files changed, 28 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 22bc2e734b0b..fb6d4fce1853 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -66,8 +66,6 @@ static int tvc_enable(struct omap_dss_device *dssdev)
if (omapdss_device_is_enabled(dssdev))
return 0;
 
-   src->ops->set_timings(src, &ddata->vm);
-
r = src->ops->enable(src);
if (r)
return r;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index 8f953303ece6..b89555ed53a0 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -69,7 +69,6 @@ static void dvic_disconnect(struct omap_dss_device *src,
 
 static int dvic_enable(struct omap_dss_device *dssdev)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
 
@@ -79,8 +78,6 @@ static int dvic_enable(struct omap_dss_device *dssdev)
if (omapdss_device_is_enabled(dssdev))
return 0;
 
-   src->ops->set_timings(src, &ddata->vm);
-
r = src->ops->enable(src);
if (r)
return r;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 1cbc593c79ff..898eb583688f 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -71,8 +71,6 @@ static int hdmic_enable(struct omap_dss_device *dssdev)
if (omapdss_device_is_enabled(dssdev))
return 0;
 
-   src->ops->set_timings(src, &ddata->vm);
-
r = src->ops->enable(src);
if (r)
return r;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index 19d1804e3fe5..824f302a515b 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -57,8 +57,6 @@ static int opa362_enable(struct omap_dss_device *dssdev)
if (omapdss_device_is_enabled(dssdev))
return 0;
 
-   src->ops->set_timings(src, &ddata->vm);
-
r = src->ops->enable(src);
if (r)
return r;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index fa6ed1e8649d..de4233980898 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -50,8 +50,6 @@ static int tfp410_enable(struct omap_dss_device *dssdev)
if (omapdss_device_is_enabled(dssdev))
return 0;
 
-   src->ops->set_timings(src, &ddata->vm);
-
r = src->ops->enable(src);
if (r)
return r;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index 21c2667f9f06..d9a590244eaa 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -66,15 +66,12 @@ static void tpd_disconnect(struct omap_dss_device *src,
 
 static int tpd_enable(struct omap_dss_device *dssdev)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
 
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
 
-   src->ops->set_timings(src, &dd

[PATCH v2 07/22] drm/omap: Don't store video mode internally for external encoders

2018-08-06 Thread Laurent Pinchart
The omap_dss_device .set_timings() operation for external encoders
stores the video mode in the device data structure. That mode is then
never used again. Drop it.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c| 5 -
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c| 5 -
 drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 5 -
 3 files changed, 15 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index 824f302a515b..05d128600712 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -25,8 +25,6 @@ struct panel_drv_data {
struct omap_dss_device dssdev;
 
struct gpio_desc *enable_gpio;
-
-   struct videomode vm;
 };
 
 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
@@ -90,13 +88,10 @@ static void opa362_disable(struct omap_dss_device *dssdev)
 static void opa362_set_timings(struct omap_dss_device *dssdev,
   const struct videomode *vm)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
dev_dbg(dssdev->dev, "set_timings\n");
 
-   ddata->vm = *vm;
-
src->ops->set_timings(src, vm);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index de4233980898..86c90c15681e 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -20,8 +20,6 @@ struct panel_drv_data {
struct omap_dss_device dssdev;
 
struct gpio_desc *pd_gpio;
-
-   struct videomode vm;
 };
 
 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
@@ -87,11 +85,8 @@ static void tfp410_fix_timings(struct videomode *vm)
 static void tfp410_set_timings(struct omap_dss_device *dssdev,
   const struct videomode *vm)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   ddata->vm = *vm;
-
src->ops->set_timings(src, vm);
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index d9a590244eaa..1e24559e0aa1 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -28,8 +28,6 @@ struct panel_drv_data {
struct gpio_desc *ct_cp_hpd_gpio;
struct gpio_desc *ls_oe_gpio;
struct gpio_desc *hpd_gpio;
-
-   struct videomode vm;
 };
 
 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
@@ -96,11 +94,8 @@ static void tpd_disable(struct omap_dss_device *dssdev)
 static void tpd_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm)
 {
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   ddata->vm = *vm;
-
src->ops->set_timings(src, vm);
 }
 
-- 
Regards,

Laurent Pinchart

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


Re: [PATCH] gpu: drm: radeon: radeon_test: Replace mdelay() with msleep()

2018-08-06 Thread Alex Deucher
On Fri, Aug 3, 2018 at 8:01 PM, Jia-Ju Bai  wrote:
> radeon_test_ring_sync() and radeon_test_ring_sync2() are never
> called in atomic context.
> They call mdelay() to busily wait, which is not necessary.
> mdelay() can be replaced with msleep().
>
> This is found by a static analysis tool named DCNS written by myself.
>
> Signed-off-by: Jia-Ju Bai 

Applied.  thanks!

Alex

> ---
>  drivers/gpu/drm/radeon/radeon_test.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_test.c 
> b/drivers/gpu/drm/radeon/radeon_test.c
> index f5e9abfadb56..411efa303f54 100644
> --- a/drivers/gpu/drm/radeon/radeon_test.c
> +++ b/drivers/gpu/drm/radeon/radeon_test.c
> @@ -347,7 +347,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev,
> if (r)
> goto out_cleanup;
>
> -   mdelay(1000);
> +   msleep(1000);
>
> if (radeon_fence_signaled(fence1)) {
> DRM_ERROR("Fence 1 signaled without waiting for 
> semaphore.\n");
> @@ -368,7 +368,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev,
> goto out_cleanup;
> }
>
> -   mdelay(1000);
> +   msleep(1000);
>
> if (radeon_fence_signaled(fence2)) {
> DRM_ERROR("Fence 2 signaled without waiting for 
> semaphore.\n");
> @@ -441,7 +441,7 @@ static void radeon_test_ring_sync2(struct radeon_device 
> *rdev,
> if (r)
> goto out_cleanup;
>
> -   mdelay(1000);
> +   msleep(1000);
>
> if (radeon_fence_signaled(fenceA)) {
> DRM_ERROR("Fence A signaled without waiting for 
> semaphore.\n");
> @@ -461,7 +461,7 @@ static void radeon_test_ring_sync2(struct radeon_device 
> *rdev,
> radeon_ring_unlock_commit(rdev, ringC, false);
>
> for (i = 0; i < 30; ++i) {
> -   mdelay(100);
> +   msleep(100);
> sigA = radeon_fence_signaled(fenceA);
> sigB = radeon_fence_signaled(fenceB);
> if (sigA || sigB)
> @@ -486,7 +486,7 @@ static void radeon_test_ring_sync2(struct radeon_device 
> *rdev,
> radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore);
> radeon_ring_unlock_commit(rdev, ringC, false);
>
> -   mdelay(1000);
> +   msleep(1000);
>
> r = radeon_fence_wait(fenceA, false);
> if (r) {
> --
> 2.17.0
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] gpu: drm: radeon: si: Replace mdelay() with msleep() in si_pcie_gen3_enable()

2018-08-06 Thread Alex Deucher
On Fri, Aug 3, 2018 at 8:33 PM, Jia-Ju Bai  wrote:
> si_pcie_gen3_enable() is never called in atomic context.
> It calls mdelay() to busily wait, which is not necessary.
> mdelay() can be replaced with msleep().
>
> This is found by a static analysis tool named DCNS written by myself
>
> Signed-off-by: Jia-Ju Bai 

Applied.  thanks!

Alex

> ---
>  drivers/gpu/drm/radeon/si.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
> index 1907c950d76f..c28743443970 100644
> --- a/drivers/gpu/drm/radeon/si.c
> +++ b/drivers/gpu/drm/radeon/si.c
> @@ -7181,7 +7181,7 @@ static void si_pcie_gen3_enable(struct radeon_device 
> *rdev)
> tmp |= LC_REDO_EQ;
> WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
>
> -   mdelay(100);
> +   msleep(100);
>
> /* linkctl */
> pci_read_config_word(root, bridge_pos + 
> PCI_EXP_LNKCTL, &tmp16);
> --
> 2.17.0
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2.1 04/21] drm/omap: Check omap_dss_device type based on the output_type field

2018-08-06 Thread Laurent Pinchart
Various functions that need to differentiate between omap_dss_device
instances corresponding to displays and to internal encoders use the
omap_dss_device.driver field, which is only set for display instances.
This gets in the way of the omap_dss_device operations refactoring.
Replace that with a check based on the output_type field which is set
for all omap_dss_device instances but displays.

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

- Fixed checkpatch warning
- Picked Sebastian's R-b tag

 drivers/gpu/drm/omapdrm/dss/base.c| 5 +++--
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 6 ++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 2051bab30484..614331b7d702 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -164,7 +164,8 @@ struct omap_dss_device *omapdss_device_get_next(struct 
omap_dss_device *from,
 * Accept display entities if the display type is requested,
 * and output entities if the output type is requested.
 */
-   if ((type & OMAP_DSS_DEVICE_TYPE_DISPLAY) && dssdev->driver)
+   if ((type & OMAP_DSS_DEVICE_TYPE_DISPLAY) &&
+   !dssdev->output_type)
goto done;
if ((type & OMAP_DSS_DEVICE_TYPE_OUTPUT) && dssdev->id &&
dssdev->next)
@@ -223,7 +224,7 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
dev_dbg(dst->dev, "disconnect\n");
 
if (!dst->id && !omapdss_device_is_connected(dst)) {
-   WARN_ON(!dst->driver);
+   WARN_ON(dst->output_type);
return;
}
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index c29633765898..6d22b38f2ce5 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -406,6 +406,12 @@ struct omap_dss_device {
unsigned int alias_id;
 
enum omap_display_type type;
+   /*
+* DSS output type that this device generates (for DSS internal devices)
+* or requires (for external encoders). Must be OMAP_DISPLAY_TYPE_NONE
+* for display devices (connectors and panels) and to non-zero value for
+* all other devices.
+*/
enum omap_display_type output_type;
 
const char *name;
-- 
Regards,

Laurent Pinchart

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


Re: [PATCH] gpu: drm: radeon: cik: Replace mdelay() with msleep() in cik_pcie_gen3_enable()

2018-08-06 Thread Alex Deucher
On Fri, Aug 3, 2018 at 8:25 PM, Jia-Ju Bai  wrote:
> cik_pcie_gen3_enable() is never called in atomic context.
> It calls mdelay() to busily wait, which is not necessary.
> mdelay() can be replaced with msleep().
>
> This is found by a static analysis tool named DCNS written by myself.
>
> Signed-off-by: Jia-Ju Bai 

Applied.  thanks.

Alex

> ---
>  drivers/gpu/drm/radeon/cik.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
> index 7c73bc7e2f85..c1b4d4fbcf3a 100644
> --- a/drivers/gpu/drm/radeon/cik.c
> +++ b/drivers/gpu/drm/radeon/cik.c
> @@ -9598,7 +9598,7 @@ static void cik_pcie_gen3_enable(struct radeon_device 
> *rdev)
> tmp |= LC_REDO_EQ;
> WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
>
> -   mdelay(100);
> +   msleep(100);
>
> /* linkctl */
> pci_read_config_word(root, bridge_pos + 
> PCI_EXP_LNKCTL, &tmp16);
> --
> 2.17.0
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 20/21] drm/omap: Pass both output and display omap_dss_device to encoder init

2018-08-06 Thread Laurent Pinchart
The drm_encoder implementation requires access to the omap_dss_device
corresponding to the display, which is passed to its initialization
function and stored internally. Clean up of the HDMI mode and infoframe
handling will require access to the output omap_dss_device. To prepare
for that, pass it to the encoder initialization function and store it
internally as well.

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

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 0cca16c323d9..174bf498f4e5 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -318,7 +318,7 @@ static int omap_modeset_init(struct drm_device *dev)
struct drm_encoder *encoder;
struct drm_crtc *crtc;
 
-   encoder = omap_encoder_init(dev, display);
+   encoder = omap_encoder_init(dev, pipe->output, display);
if (!encoder)
return -ENOMEM;
 
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 87e2b3799a45..2689ae74ea60 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -36,7 +36,8 @@
  */
 struct omap_encoder {
struct drm_encoder base;
-   struct omap_dss_device *dssdev;
+   struct omap_dss_device *output;
+   struct omap_dss_device *display;
 };
 
 static void omap_encoder_destroy(struct drm_encoder *encoder)
@@ -57,7 +58,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
 {
struct drm_device *dev = encoder->dev;
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-   struct omap_dss_device *dssdev = omap_encoder->dssdev;
+   struct omap_dss_device *dssdev = omap_encoder->display;
struct drm_connector *connector;
bool hdmi_mode;
int r;
@@ -86,7 +87,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
 static void omap_encoder_disable(struct drm_encoder *encoder)
 {
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-   struct omap_dss_device *dssdev = omap_encoder->dssdev;
+   struct omap_dss_device *dssdev = omap_encoder->display;
 
dssdev->ops->disable(dssdev);
 }
@@ -97,7 +98,7 @@ static int omap_encoder_update(struct drm_encoder *encoder,
 {
struct drm_device *dev = encoder->dev;
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-   struct omap_dss_device *dssdev = omap_encoder->dssdev;
+   struct omap_dss_device *dssdev = omap_encoder->display;
int ret;
 
if (dssdev->ops->check_timings) {
@@ -127,7 +128,7 @@ static int omap_encoder_update(struct drm_encoder *encoder,
 static void omap_encoder_enable(struct drm_encoder *encoder)
 {
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-   struct omap_dss_device *dssdev = omap_encoder->dssdev;
+   struct omap_dss_device *dssdev = omap_encoder->display;
int r;
 
omap_encoder_update(encoder, omap_crtc_channel(encoder->crtc),
@@ -156,7 +157,8 @@ 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 *dssdev)
+ struct omap_dss_device *output,
+ struct omap_dss_device *display)
 {
struct drm_encoder *encoder = NULL;
struct omap_encoder *omap_encoder;
@@ -165,7 +167,8 @@ struct drm_encoder *omap_encoder_init(struct drm_device 
*dev,
if (!omap_encoder)
goto fail;
 
-   omap_encoder->dssdev = dssdev;
+   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 e8f1a35dce2f..a7b5dde63ecb 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.h
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.h
@@ -25,6 +25,7 @@ struct drm_encoder;
 struct omap_dss_device;
 
 struct drm_encoder *omap_encoder_init(struct drm_device *dev,
-   struct omap_dss_device *dssdev);
+ struct omap_dss_device *output,
+ struct omap_dss_device *display);
 
 #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 18/21] drm/omap: Don't call EDID read operation recursively

2018-08-06 Thread Laurent Pinchart
Instead of calling the EDID read operation (.read_edid()) recursively
from the display device back to the first device that provides EDID read
support, iterate over the devices manually in the DRM connector code.
This moves the complexity to a single central location and simplifies
the logic in omap_dss_device drivers.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  15 +--
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  |  11 ---
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   |  13 ---
 drivers/gpu/drm/omapdrm/dss/hdmi4.c|   1 +
 drivers/gpu/drm/omapdrm/dss/hdmi5.c|   1 +
 drivers/gpu/drm/omapdrm/omap_connector.c   | 101 -
 6 files changed, 65 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index 6be260ff6458..eae4108330f1 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -166,12 +166,6 @@ static int dvic_read_edid(struct omap_dss_device *dssdev,
struct panel_drv_data *ddata = to_panel_data(dssdev);
int r, l, bytes_read;
 
-   if (ddata->hpd_gpio && !gpiod_get_value_cansleep(ddata->hpd_gpio))
-   return -ENODEV;
-
-   if (!ddata->i2c_adapter)
-   return -ENODEV;
-
l = min(EDID_LENGTH, len);
r = dvic_ddc_read(ddata->i2c_adapter, edid, l, 0);
if (r)
@@ -341,10 +335,11 @@ static int dvic_probe(struct platform_device *pdev)
dssdev->of_ports = BIT(0);
 
if (ddata->hpd_gpio)
-   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT
- | OMAP_DSS_DEVICE_OP_HPD;
-   else if (ddata->i2c_adapter)
-   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT;
+   dssdev->ops_flags |= OMAP_DSS_DEVICE_OP_DETECT
+ |  OMAP_DSS_DEVICE_OP_HPD;
+   if (ddata->i2c_adapter)
+   dssdev->ops_flags |= OMAP_DSS_DEVICE_OP_DETECT
+ |  OMAP_DSS_DEVICE_OP_EDID;
 
omapdss_display_init(dssdev);
omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 6f2364afb14a..16dc22edcb8e 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -15,8 +15,6 @@
 #include 
 #include 
 
-#include 
-
 #include "../dss/omapdss.h"
 
 static const struct videomode hdmic_default_vm = {
@@ -126,14 +124,6 @@ static int hdmic_check_timings(struct omap_dss_device 
*dssdev,
return src->ops->check_timings(src, vm);
 }
 
-static int hdmic_read_edid(struct omap_dss_device *dssdev,
-   u8 *edid, int len)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   return src->ops->read_edid(src, edid, len);
-}
-
 static bool hdmic_detect(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -190,7 +180,6 @@ static const struct omap_dss_device_ops hdmic_ops = {
.get_timings= hdmic_get_timings,
.check_timings  = hdmic_check_timings,
 
-   .read_edid  = hdmic_read_edid,
.detect = hdmic_detect,
.register_hpd_cb= hdmic_register_hpd_cb,
.unregister_hpd_cb  = hdmic_unregister_hpd_cb,
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index da97d357bde7..3ce1c935a48c 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -115,18 +115,6 @@ static int tpd_check_timings(struct omap_dss_device 
*dssdev,
return src->ops->check_timings(src, vm);
 }
 
-static int tpd_read_edid(struct omap_dss_device *dssdev,
-   u8 *edid, int len)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-   struct omap_dss_device *src = dssdev->src;
-
-   if (!gpiod_get_value_cansleep(ddata->hpd_gpio))
-   return -ENODEV;
-
-   return src->ops->read_edid(src, edid, len);
-}
-
 static bool tpd_detect(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -180,7 +168,6 @@ static const struct omap_dss_device_ops tpd_ops = {
.disable= tpd_disable,
.check_timings  = tpd_check_timings,
.set_timings= tpd_set_timings,
-   .read_edid  = tpd_read_edid,
.detect = tpd_detect,
.register_hpd_cb= tpd_register_hpd_cb,
.unregister_hpd_cb  = tpd_unregister_hpd_cb,
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index bebce93fed3e..c92564300446 1

[PATCH v2 21/21] drm/omap: Don't call HDMI mode and infoframe operations recursively

2018-08-06 Thread Laurent Pinchart
The HDMI mode (.set_hdmi_mode()) and infoframe (.set_infoframe())
operations are called recursively from the display device back to the
HDMI encoder. This isn't required, as all components other than the HDMI
encoder just forward the operation to the previous component in the
chain. Call the operations directly on the HDMI encoder.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c   | 20 
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c| 21 -
 drivers/gpu/drm/omapdrm/omap_encoder.c  |  2 +-
 3 files changed, 1 insertion(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 16dc22edcb8e..fe6d2923ed81 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -154,21 +154,6 @@ static void hdmic_unregister_hpd_cb(struct omap_dss_device 
*dssdev)
mutex_unlock(&ddata->hpd_lock);
 }
 
-static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   return src->ops->hdmi.set_hdmi_mode(src, hdmi_mode);
-}
-
-static int hdmic_set_infoframe(struct omap_dss_device *dssdev,
-   const struct hdmi_avi_infoframe *avi)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   return src->ops->hdmi.set_infoframe(src, avi);
-}
-
 static const struct omap_dss_device_ops hdmic_ops = {
.connect= hdmic_connect,
.disconnect = hdmic_disconnect,
@@ -183,11 +168,6 @@ static const struct omap_dss_device_ops hdmic_ops = {
.detect = hdmic_detect,
.register_hpd_cb= hdmic_register_hpd_cb,
.unregister_hpd_cb  = hdmic_unregister_hpd_cb,
-
-   .hdmi = {
-   .set_hdmi_mode  = hdmic_set_hdmi_mode,
-   .set_infoframe  = hdmic_set_infoframe,
-   },
 };
 
 static irqreturn_t hdmic_hpd_isr(int irq, void *data)
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index 3ce1c935a48c..babaac856067 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -145,22 +145,6 @@ static void tpd_unregister_hpd_cb(struct omap_dss_device 
*dssdev)
mutex_unlock(&ddata->hpd_lock);
 }
 
-static int tpd_set_infoframe(struct omap_dss_device *dssdev,
-   const struct hdmi_avi_infoframe *avi)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   return src->ops->hdmi.set_infoframe(src, avi);
-}
-
-static int tpd_set_hdmi_mode(struct omap_dss_device *dssdev,
-   bool hdmi_mode)
-{
-   struct omap_dss_device *src = dssdev->src;
-
-   return src->ops->hdmi.set_hdmi_mode(src, hdmi_mode);
-}
-
 static const struct omap_dss_device_ops tpd_ops = {
.connect= tpd_connect,
.disconnect = tpd_disconnect,
@@ -171,11 +155,6 @@ static const struct omap_dss_device_ops tpd_ops = {
.detect = tpd_detect,
.register_hpd_cb= tpd_register_hpd_cb,
.unregister_hpd_cb  = tpd_unregister_hpd_cb,
-
-   .hdmi = {
-   .set_infoframe  = tpd_set_infoframe,
-   .set_hdmi_mode  = tpd_set_hdmi_mode,
-   },
 };
 
 static irqreturn_t tpd_hpd_isr(int irq, void *data)
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 2689ae74ea60..94b75d018e71 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -58,7 +58,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
 {
struct drm_device *dev = encoder->dev;
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-   struct omap_dss_device *dssdev = omap_encoder->display;
+   struct omap_dss_device *dssdev = omap_encoder->output;
struct drm_connector *connector;
bool hdmi_mode;
int r;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 17/21] drm/omap: Move HPD disconnection handling to omap_connector

2018-08-06 Thread Laurent Pinchart
On HDMI outputs, CEC support requires notification of HPD signal
deassertion. The HPD signal can be handled by various omap_dss_device
instances in the pipeline, and all of them forward HPD events to the
OMAP4 internal HDMI encoder.

Knowledge of the DSS internals need to be removed from the
omap_dss_device instances in order to migrate to drm_bridge. To do so,
move HPD handling for CEC to the omap_connector.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  |  7 +
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   |  7 +
 drivers/gpu/drm/omapdrm/omap_connector.c   | 33 ++
 3 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 84cc68388940..6f2364afb14a 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -137,13 +137,8 @@ static int hdmic_read_edid(struct omap_dss_device *dssdev,
 static bool hdmic_detect(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
-   struct omap_dss_device *src = dssdev->src;
-   bool connected;
 
-   connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
-   if (!connected && src->ops->hdmi.lost_hotplug)
-   src->ops->hdmi.lost_hotplug(src);
-   return connected;
+   return gpiod_get_value_cansleep(ddata->hpd_gpio);
 }
 
 static void hdmic_register_hpd_cb(struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index d6d08148a3e5..da97d357bde7 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -130,13 +130,8 @@ static int tpd_read_edid(struct omap_dss_device *dssdev,
 static bool tpd_detect(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
-   struct omap_dss_device *src = dssdev->src;
-   bool connected;
 
-   connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
-   if (!connected && src->ops->hdmi.lost_hotplug)
-   src->ops->hdmi.lost_hotplug(src);
-   return connected;
+   return gpiod_get_value_cansleep(ddata->hpd_gpio);
 }
 
 static void tpd_register_hpd_cb(struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index e77427d81eb9..344414ef3962 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -34,6 +34,22 @@ struct omap_connector {
bool hdmi_mode;
 };
 
+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);
+   }
+}
+
 static void omap_connector_hpd_cb(void *cb_data,
  enum drm_connector_status status)
 {
@@ -47,8 +63,12 @@ static void omap_connector_hpd_cb(void *cb_data,
connector->status = status;
mutex_unlock(&dev->mode_config.mutex);
 
-   if (old_status != status)
-   drm_kms_helper_hotplug_event(dev);
+   if (old_status == status)
+   return;
+
+   omap_connector_hpd_notify(connector, omap_connector->hpd, status);
+
+   drm_kms_helper_hotplug_event(dev);
 }
 
 void omap_connector_enable_hpd(struct drm_connector *connector)
@@ -103,10 +123,11 @@ static enum drm_connector_status omap_connector_detect(
OMAP_DSS_DEVICE_OP_DETECT);
 
if (dssdev) {
-   if (dssdev->ops->detect(dssdev))
-   status = connector_status_connected;
-   else
-   status = connector_status_disconnected;
+   status = dssdev->ops->detect(dssdev)
+  ? connector_status_connected
+  : connector_status_disconnected;
+
+   omap_connector_hpd_notify(connector, dssdev->src, status);
} else {
switch (omap_connector->dssdev->type) {
case OMAP_DISPLAY_TYPE_DPI:
-- 
Regards,

Laurent Pinchart

___
dri-devel mailing list
dri-devel@lists.freedesktop.or

[PATCH v2 19/21] drm/omap: Get from CRTC to display device directly

2018-08-06 Thread Laurent Pinchart
The CRTC mode set implementation needs to access the omap_dss_device for
the pipeline display. To do so, it iterates over all pipelines to find
the one that contains an encoder corresponding to the CRTC, and request
the display device from the encoder. That's a very complicated dance
when the CRTC has a direct pipeline pointer already, and the pipeline
contains a pointer to the display device.

Replace the convoluted code with direct access.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/omap_crtc.c| 25 -
 drivers/gpu/drm/omapdrm/omap_encoder.c |  7 ---
 drivers/gpu/drm/omapdrm/omap_encoder.h |  3 ---
 3 files changed, 4 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 197d05312306..6e7a777907f5 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -419,12 +419,12 @@ static enum drm_mode_status omap_crtc_mode_valid(struct 
drm_crtc *crtc,
 static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+   struct omap_dss_device *display = omap_crtc->pipe->display;
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
-   struct omap_drm_private *priv = crtc->dev->dev_private;
const u32 flags_mask = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_DE_LOW |
DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_PIXDATA_NEGEDGE |
DISPLAY_FLAGS_SYNC_POSEDGE | DISPLAY_FLAGS_SYNC_NEGEDGE;
-   unsigned int i;
+   struct videomode vm = {0};
 
DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
omap_crtc->name, mode->base.id, mode->name,
@@ -447,25 +447,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
 * has been changed to the DRM model.
 */
 
-   for (i = 0; i < priv->num_pipes; ++i) {
-   struct drm_encoder *encoder = priv->pipes[i].encoder;
-
-   if (encoder->crtc == crtc) {
-   struct omap_dss_device *dssdev;
-
-   dssdev = omap_encoder_get_dssdev(encoder);
-
-   if (dssdev) {
-   struct videomode vm = {0};
-
-   dssdev->ops->get_timings(dssdev, &vm);
-
-   omap_crtc->vm.flags |= vm.flags & flags_mask;
-   }
-
-   break;
-   }
-   }
+   display->ops->get_timings(display, &vm);
+   omap_crtc->vm.flags |= vm.flags & flags_mask;
 }
 
 static int omap_crtc_atomic_check(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 7bbf3700e393..87e2b3799a45 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -39,13 +39,6 @@ struct omap_encoder {
struct omap_dss_device *dssdev;
 };
 
-struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder)
-{
-   struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-
-   return omap_encoder->dssdev;
-}
-
 static void omap_encoder_destroy(struct drm_encoder *encoder)
 {
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.h 
b/drivers/gpu/drm/omapdrm/omap_encoder.h
index d2f308bec494..e8f1a35dce2f 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.h
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.h
@@ -27,7 +27,4 @@ struct omap_dss_device;
 struct drm_encoder *omap_encoder_init(struct drm_device *dev,
struct omap_dss_device *dssdev);
 
-/* map crtc to vblank mask */
-struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder);
-
 #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 15/21] drm/omap: Remove unneeded safety checks in the HPD operations

2018-08-06 Thread Laurent Pinchart
The HPD-related omap_dss_device operations are now only called when the
device supports HPD. There's no need to duplicate that check in the
omap_dss_device drivers. The .register_hpd_cb() operation can as a
result be turned into a void operation.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c |  9 +
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c| 14 +++---
 drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c |  8 +++-
 drivers/gpu/drm/omapdrm/dss/omapdss.h|  6 +++---
 drivers/gpu/drm/omapdrm/omap_connector.c | 17 -
 5 files changed, 14 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index e9353e4cd297..a53d5967e5a9 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -211,30 +211,23 @@ static bool dvic_detect(struct omap_dss_device *dssdev)
return r == 0;
 }
 
-static int dvic_register_hpd_cb(struct omap_dss_device *dssdev,
+static void dvic_register_hpd_cb(struct omap_dss_device *dssdev,
 void (*cb)(void *cb_data,
enum drm_connector_status status),
 void *cb_data)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
 
-   if (!ddata->hpd_gpio)
-   return -ENOTSUPP;
-
mutex_lock(&ddata->hpd_lock);
ddata->hpd_cb = cb;
ddata->hpd_cb_data = cb_data;
mutex_unlock(&ddata->hpd_lock);
-   return 0;
 }
 
 static void dvic_unregister_hpd_cb(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
 
-   if (!ddata->hpd_gpio)
-   return;
-
mutex_lock(&ddata->hpd_lock);
ddata->hpd_cb = NULL;
ddata->hpd_cb_data = NULL;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 8eae973474dd..c58bf64d1a9b 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -147,31 +147,23 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
return connected;
 }
 
-static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev,
-void (*cb)(void *cb_data,
+static void hdmic_register_hpd_cb(struct omap_dss_device *dssdev,
+ void (*cb)(void *cb_data,
enum drm_connector_status status),
-void *cb_data)
+ void *cb_data)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
 
-   if (!ddata->hpd_gpio)
-   return -ENOTSUPP;
-
mutex_lock(&ddata->hpd_lock);
ddata->hpd_cb = cb;
ddata->hpd_cb_data = cb_data;
mutex_unlock(&ddata->hpd_lock);
-
-   return 0;
 }
 
 static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
 
-   if (!ddata->hpd_gpio)
-   return;
-
mutex_lock(&ddata->hpd_lock);
ddata->hpd_cb = NULL;
ddata->hpd_cb_data = NULL;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index f6d4f90f2c08..508df4174c5e 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -140,10 +140,10 @@ static bool tpd_detect(struct omap_dss_device *dssdev)
return connected;
 }
 
-static int tpd_register_hpd_cb(struct omap_dss_device *dssdev,
-  void (*cb)(void *cb_data,
+static void tpd_register_hpd_cb(struct omap_dss_device *dssdev,
+   void (*cb)(void *cb_data,
  enum drm_connector_status status),
-  void *cb_data)
+   void *cb_data)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
 
@@ -151,8 +151,6 @@ static int tpd_register_hpd_cb(struct omap_dss_device 
*dssdev,
ddata->hpd_cb = cb;
ddata->hpd_cb_data = cb_data;
mutex_unlock(&ddata->hpd_lock);
-
-   return 0;
 }
 
 static void tpd_unregister_hpd_cb(struct omap_dss_device *dssdev)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 30ad9985776f..b05d47b34937 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -372,10 +372,10 @@ struct omap_dss_device_ops {
 
bool (*detect)(struct omap_dss_device *dssdev);
 
-   int (*register_hpd_cb)(struct omap_dss_device *dssdev,
-  void (*cb)(void

[PATCH v2 08/21] drm/omap: panel-sony-acx565akm: Convert to the GPIO descriptors API

2018-08-06 Thread Laurent Pinchart
The GPIO descriptor API is favoured over the plain GPIO API for consumer
drivers. Using it simplifies the driver code.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 .../drm/omapdrm/displays/panel-sony-acx565akm.c| 56 --
 1 file changed, 21 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c 
b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
index 036fd8e57074..3eca39821d79 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
@@ -20,17 +20,15 @@
  * this program.  If not, see .
  */
 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
+#include 
 
 #include "../dss/omapdss.h"
 
@@ -65,7 +63,7 @@
 struct panel_drv_data {
struct omap_dss_device  dssdev;
 
-   int reset_gpio;
+   struct gpio_desc *reset_gpio;
 
struct videomode vm;
 
@@ -536,8 +534,8 @@ static int acx565akm_panel_power_on(struct omap_dss_device 
*dssdev)
/*FIXME tweak me */
msleep(50);
 
-   if (gpio_is_valid(ddata->reset_gpio))
-   gpio_set_value(ddata->reset_gpio, 1);
+   if (ddata->reset_gpio)
+   gpiod_set_value(ddata->reset_gpio, 1);
 
if (ddata->enabled) {
dev_dbg(&ddata->spi->dev, "panel already enabled\n");
@@ -586,8 +584,8 @@ static void acx565akm_panel_power_off(struct 
omap_dss_device *dssdev)
 */
msleep(50);
 
-   if (gpio_is_valid(ddata->reset_gpio))
-   gpio_set_value(ddata->reset_gpio, 0);
+   if (ddata->reset_gpio)
+   gpiod_set_value(ddata->reset_gpio, 0);
 
/* FIXME need to tweak this delay */
msleep(100);
@@ -674,16 +672,6 @@ static const struct omap_dss_driver acx565akm_ops = {
.check_timings  = acx565akm_check_timings,
 };
 
-static int acx565akm_probe_of(struct spi_device *spi)
-{
-   struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
-   struct device_node *np = spi->dev.of_node;
-
-   ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
-
-   return 0;
-}
-
 static int acx565akm_probe(struct spi_device *spi)
 {
struct panel_drv_data *ddata;
@@ -691,6 +679,7 @@ static int acx565akm_probe(struct spi_device *spi)
struct backlight_device *bldev;
int max_brightness, brightness;
struct backlight_properties props;
+   struct gpio_desc *gpio;
int r;
 
dev_dbg(&spi->dev, "%s\n", __func__);
@@ -707,19 +696,16 @@ static int acx565akm_probe(struct spi_device *spi)
 
mutex_init(&ddata->mutex);
 
-   r = acx565akm_probe_of(spi);
-   if (r)
-   return r;
-
-   if (gpio_is_valid(ddata->reset_gpio)) {
-   r = devm_gpio_request_one(&spi->dev, ddata->reset_gpio,
-   GPIOF_OUT_INIT_LOW, "lcd reset");
-   if (r)
-   return r;
+   gpio = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW);
+   if (IS_ERR(gpio)) {
+   dev_err(&spi->dev, "failed to parse reset gpio\n");
+   return PTR_ERR(gpio);
}
 
-   if (gpio_is_valid(ddata->reset_gpio))
-   gpio_set_value(ddata->reset_gpio, 1);
+   ddata->reset_gpio = gpio;
+
+   if (ddata->reset_gpio)
+   gpiod_set_value(ddata->reset_gpio, 1);
 
/*
 * After reset we have to wait 5 msec before the first
@@ -731,8 +717,8 @@ static int acx565akm_probe(struct spi_device *spi)
 
r = panel_detect(ddata);
 
-   if (!ddata->enabled && gpio_is_valid(ddata->reset_gpio))
-   gpio_set_value(ddata->reset_gpio, 0);
+   if (!ddata->enabled && ddata->reset_gpio)
+   gpiod_set_value(ddata->reset_gpio, 0);
 
if (r) {
dev_err(&spi->dev, "%s panel detect error\n", __func__);
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 16/21] drm/omap: Merge HPD enable operation with HPD callback registration

2018-08-06 Thread Laurent Pinchart
The omap_dss_device .enable_hpd() and .disable_hpd() are used to enable
and disable hot-plug detection at omapdrm probe and remove time. This is
required to avoid reporting hot-plug detection events before the DRM
infrastructure is ready to accept them, as that could result in crashes
or other malfunction.

Hot-plug event reporting is conditioned by both HPD being enabled
through the .enable_hpd() operation and by the HPD callback being
registered though the .register_hpd_cb() operation. We thus don't need a
separate enable operation if we can guarantee that callbacks won't be
registered too early.

HPD callbacks are registered at connector initialization time, which is
too early to start reporting HPD events. There's however nothing
blocking a move of callback registration to a later time when the
omapdrm driver calls the HPD enable operations. Do so, and remove the
HPD enable operation completely from omap_dss_device drivers.

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

- Call omap_connector_disable_hpd() instead of
  omap_connector_enable_hpd() in omap_modeset_disable_external_hpd()
---
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   | 26 -
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  | 29 +-
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   | 23 +--
 drivers/gpu/drm/omapdrm/dss/omapdss.h  |  2 --
 drivers/gpu/drm/omapdrm/omap_connector.c   | 34 +-
 drivers/gpu/drm/omapdrm/omap_connector.h   |  2 ++
 drivers/gpu/drm/omapdrm/omap_drv.c | 16 +++---
 7 files changed, 35 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index a53d5967e5a9..6be260ff6458 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -234,30 +234,6 @@ static void dvic_unregister_hpd_cb(struct omap_dss_device 
*dssdev)
mutex_unlock(&ddata->hpd_lock);
 }
 
-static void dvic_enable_hpd(struct omap_dss_device *dssdev)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-
-   if (!ddata->hpd_gpio)
-   return;
-
-   mutex_lock(&ddata->hpd_lock);
-   ddata->hpd_enabled = true;
-   mutex_unlock(&ddata->hpd_lock);
-}
-
-static void dvic_disable_hpd(struct omap_dss_device *dssdev)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-
-   if (!ddata->hpd_gpio)
-   return;
-
-   mutex_lock(&ddata->hpd_lock);
-   ddata->hpd_enabled = false;
-   mutex_unlock(&ddata->hpd_lock);
-}
-
 static const struct omap_dss_device_ops dvic_ops = {
.connect= dvic_connect,
.disconnect = dvic_disconnect,
@@ -274,8 +250,6 @@ static const struct omap_dss_device_ops dvic_ops = {
 
.register_hpd_cb= dvic_register_hpd_cb,
.unregister_hpd_cb  = dvic_unregister_hpd_cb,
-   .enable_hpd = dvic_enable_hpd,
-   .disable_hpd= dvic_disable_hpd,
 };
 
 static irqreturn_t dvic_hpd_isr(int irq, void *data)
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index c58bf64d1a9b..84cc68388940 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -37,7 +37,6 @@ struct panel_drv_data {
struct omap_dss_device dssdev;
void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
void *hpd_cb_data;
-   bool hpd_enabled;
struct mutex hpd_lock;
 
struct device *dev;
@@ -170,30 +169,6 @@ static void hdmic_unregister_hpd_cb(struct omap_dss_device 
*dssdev)
mutex_unlock(&ddata->hpd_lock);
 }
 
-static void hdmic_enable_hpd(struct omap_dss_device *dssdev)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-
-   if (!ddata->hpd_gpio)
-   return;
-
-   mutex_lock(&ddata->hpd_lock);
-   ddata->hpd_enabled = true;
-   mutex_unlock(&ddata->hpd_lock);
-}
-
-static void hdmic_disable_hpd(struct omap_dss_device *dssdev)
-{
-   struct panel_drv_data *ddata = to_panel_data(dssdev);
-
-   if (!ddata->hpd_gpio)
-   return;
-
-   mutex_lock(&ddata->hpd_lock);
-   ddata->hpd_enabled = false;
-   mutex_unlock(&ddata->hpd_lock);
-}
-
 static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
 {
struct omap_dss_device *src = dssdev->src;
@@ -224,8 +199,6 @@ static const struct omap_dss_device_ops hdmic_ops = {
.detect = hdmic_detect,
.register_hpd_cb= hdmic_register_hpd_cb,
.unregister_hpd_cb  = hdmic_unregister_hpd_cb,
-   .enable_hpd = hdmic_enable_hpd,
-   .disable_hpd= hdmic_disable_hpd,
 
.hdmi = {
.set_hdmi_mode  = 

[PATCH v2 10/21] drm/omap: panel-tpo-td043mtea1: Convert to the GPIO descriptors API

2018-08-06 Thread Laurent Pinchart
The GPIO descriptor API is favoured over the plain GPIO API for consumer
drivers. Using it simplifies the driver code.

As the descriptor API handles the active-low flag internally we need to
invert the polarity of all GPIO operations in the driver. Rename the
nreset_gpio field to reset_gpio to reflect that.

The reset GPIO is mandatory, so drop conditional tests through the
driver.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 .../drm/omapdrm/displays/panel-tpo-td043mtea1.c| 52 ++
 1 file changed, 14 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c 
b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
index 34531169c166..1521812ab15b 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
@@ -10,14 +10,13 @@
  * (at your option) any later version.
  */
 
-#include 
 #include 
-#include 
-#include 
-#include 
 #include 
+#include 
+#include 
+#include 
 #include 
-#include 
+#include 
 
 #include "../dss/omapdss.h"
 
@@ -59,7 +58,7 @@ struct panel_drv_data {
 
struct spi_device *spi;
struct regulator *vcc_reg;
-   int nreset_gpio;
+   struct gpio_desc *reset_gpio;
u16 gamma[12];
u32 mode;
u32 vmirror:1;
@@ -282,8 +281,7 @@ static int tpo_td043_power_on(struct panel_drv_data *ddata)
/* wait for panel to stabilize */
msleep(160);
 
-   if (gpio_is_valid(ddata->nreset_gpio))
-   gpio_set_value(ddata->nreset_gpio, 1);
+   gpiod_set_value(ddata->reset_gpio, 0);
 
tpo_td043_write(ddata->spi, 2,
TPO_R02_MODE(ddata->mode) | TPO_R02_NCLK_RISING);
@@ -305,8 +303,7 @@ static void tpo_td043_power_off(struct panel_drv_data 
*ddata)
tpo_td043_write(ddata->spi, 3,
TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
 
-   if (gpio_is_valid(ddata->nreset_gpio))
-   gpio_set_value(ddata->nreset_gpio, 0);
+   gpiod_set_value(ddata->reset_gpio, 1);
 
/* wait for at least 2 vsyncs before cutting off power */
msleep(50);
@@ -419,26 +416,11 @@ static const struct omap_dss_driver tpo_td043_ops = {
.check_timings  = tpo_td043_check_timings,
 };
 
-static int tpo_td043_probe_of(struct spi_device *spi)
-{
-   struct device_node *node = spi->dev.of_node;
-   struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
-   int gpio;
-
-   gpio = of_get_named_gpio(node, "reset-gpios", 0);
-   if (!gpio_is_valid(gpio)) {
-   dev_err(&spi->dev, "failed to parse enable gpio\n");
-   return gpio;
-   }
-   ddata->nreset_gpio = gpio;
-
-   return 0;
-}
-
 static int tpo_td043_probe(struct spi_device *spi)
 {
struct panel_drv_data *ddata;
struct omap_dss_device *dssdev;
+   struct gpio_desc *gpio;
int r;
 
dev_dbg(&spi->dev, "%s\n", __func__);
@@ -460,10 +442,6 @@ static int tpo_td043_probe(struct spi_device *spi)
 
ddata->spi = spi;
 
-   r = tpo_td043_probe_of(spi);
-   if (r)
-   return r;
-
ddata->mode = TPO_R02_MODE_800x480;
memcpy(ddata->gamma, tpo_td043_def_gamma, sizeof(ddata->gamma));
 
@@ -473,16 +451,14 @@ static int tpo_td043_probe(struct spi_device *spi)
return PTR_ERR(ddata->vcc_reg);
}
 
-   if (gpio_is_valid(ddata->nreset_gpio)) {
-   r = devm_gpio_request_one(&spi->dev,
-   ddata->nreset_gpio, GPIOF_OUT_INIT_LOW,
-   "lcd reset");
-   if (r < 0) {
-   dev_err(&spi->dev, "couldn't request reset GPIO\n");
-   return r;
-   }
+   gpio = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_HIGH);
+   if (IS_ERR(gpio)) {
+   dev_err(&spi->dev, "failed to get reset gpio\n");
+   return PTR_ERR(gpio);
}
 
+   ddata->reset_gpio = gpio;
+
r = sysfs_create_group(&spi->dev.kobj, &tpo_td043_attr_group);
if (r) {
dev_err(&spi->dev, "failed to create sysfs files\n");
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 14/21] drm/omap: Don't call HPD registration operations recursively

2018-08-06 Thread Laurent Pinchart
Instead of calling the hot-plug detection callback registration
operations (.register_hpd_cb() and .unregister_hpd_cb()) recursively
from the display device back to the first device that provides hot plug
detection support, iterate over the devices manually in the DRM
connector code. This moves the complexity to a single central location
and simplifies the logic in omap_dss_device drivers.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  8 ++-
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  | 67 --
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   |  3 +-
 drivers/gpu/drm/omapdrm/omap_connector.c   | 79 ++
 4 files changed, 88 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index f1674b3eee50..e9353e4cd297 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -372,8 +372,12 @@ static int dvic_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_DVI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
-   dssdev->ops_flags = ddata->hpd_gpio || ddata->i2c_adapter
- ? OMAP_DSS_DEVICE_OP_DETECT : 0;
+
+   if (ddata->hpd_gpio)
+   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT
+ | OMAP_DSS_DEVICE_OP_HPD;
+   else if (ddata->i2c_adapter)
+   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT;
 
omapdss_display_init(dssdev);
omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 0d22d7004c98..8eae973474dd 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -153,62 +153,53 @@ static int hdmic_register_hpd_cb(struct omap_dss_device 
*dssdev,
 void *cb_data)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
-   struct omap_dss_device *src = dssdev->src;
 
-   if (ddata->hpd_gpio) {
-   mutex_lock(&ddata->hpd_lock);
-   ddata->hpd_cb = cb;
-   ddata->hpd_cb_data = cb_data;
-   mutex_unlock(&ddata->hpd_lock);
-   return 0;
-   } else if (src->ops->register_hpd_cb) {
-   return src->ops->register_hpd_cb(src, cb, cb_data);
-   }
+   if (!ddata->hpd_gpio)
+   return -ENOTSUPP;
 
-   return -ENOTSUPP;
+   mutex_lock(&ddata->hpd_lock);
+   ddata->hpd_cb = cb;
+   ddata->hpd_cb_data = cb_data;
+   mutex_unlock(&ddata->hpd_lock);
+
+   return 0;
 }
 
 static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
-   struct omap_dss_device *src = dssdev->src;
 
-   if (ddata->hpd_gpio) {
-   mutex_lock(&ddata->hpd_lock);
-   ddata->hpd_cb = NULL;
-   ddata->hpd_cb_data = NULL;
-   mutex_unlock(&ddata->hpd_lock);
-   } else if (src->ops->unregister_hpd_cb) {
-   src->ops->unregister_hpd_cb(src);
-   }
+   if (!ddata->hpd_gpio)
+   return;
+
+   mutex_lock(&ddata->hpd_lock);
+   ddata->hpd_cb = NULL;
+   ddata->hpd_cb_data = NULL;
+   mutex_unlock(&ddata->hpd_lock);
 }
 
 static void hdmic_enable_hpd(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
-   struct omap_dss_device *src = dssdev->src;
 
-   if (ddata->hpd_gpio) {
-   mutex_lock(&ddata->hpd_lock);
-   ddata->hpd_enabled = true;
-   mutex_unlock(&ddata->hpd_lock);
-   } else if (src->ops->enable_hpd) {
-   src->ops->enable_hpd(src);
-   }
+   if (!ddata->hpd_gpio)
+   return;
+
+   mutex_lock(&ddata->hpd_lock);
+   ddata->hpd_enabled = true;
+   mutex_unlock(&ddata->hpd_lock);
 }
 
 static void hdmic_disable_hpd(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
-   struct omap_dss_device *src = dssdev->src;
 
-   if (ddata->hpd_gpio) {
-   mutex_lock(&ddata->hpd_lock);
-   ddata->hpd_enabled = false;
-   mutex_unlock(&ddata->hpd_lock);
-   } else if (src->ops->disable_hpd) {
-   src->ops->disable_hpd(src);
-   }
+   if (!ddata->hpd_gpio)
+   return;
+
+   mutex_lock(&ddata->hpd_lock);
+   ddata->hpd_enabled = false;
+   mutex_unlock(&ddata->hpd_lock);
 }
 
 static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
@@ -314,7 +305,9 @@ static int hdmic_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
  

[PATCH v2 03/21] drm/omap: Remove unnecessary display output sanity checks

2018-08-06 Thread Laurent Pinchart
The omapdrm driver checks at suspend and resume time whether the
displays it operates on have their driver operations set. This check is
unneeded, as all display drivers set the driver operations field at
probe time and never touch it afterwards. This is furthermore proven by
the dereferencing of the driver field without checking it first in
several locations.

The omapdss driver performs a similar check at shutdown time. This is
unneeded as well, as the for_each_dss_display() macro it uses to iterate
over displays locates the displays by checking the driver field
internally.

As those checks are unnecessary, remove them.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/dss/dss.c  | 3 ---
 drivers/gpu/drm/omapdrm/omap_drv.c | 6 --
 2 files changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index b473aff466d7..14ffe23b5ecf 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -1552,9 +1552,6 @@ static void dss_shutdown(struct platform_device *pdev)
DSSDBG("shutdown\n");
 
for_each_dss_display(dssdev) {
-   if (!dssdev->driver)
-   continue;
-
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
dssdev->driver->disable(dssdev);
}
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index f2a69cfb6ebf..d0f6929857bb 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -723,9 +723,6 @@ static int omap_drm_suspend_all_displays(struct drm_device 
*ddev)
for (i = 0; i < priv->num_pipes; i++) {
struct omap_dss_device *display = priv->pipes[i].display;
 
-   if (!display->driver)
-   continue;
-
if (display->state == OMAP_DSS_DISPLAY_ACTIVE) {
display->driver->disable(display);
display->activate_after_resume = true;
@@ -745,9 +742,6 @@ static int omap_drm_resume_all_displays(struct drm_device 
*ddev)
for (i = 0; i < priv->num_pipes; i++) {
struct omap_dss_device *display = priv->pipes[i].display;
 
-   if (!display->driver)
-   continue;
-
if (display->activate_after_resume) {
display->driver->enable(display);
display->activate_after_resume = false;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 06/21] drm/omap: encoder-tfp410: Convert to the GPIO descriptors API

2018-08-06 Thread Laurent Pinchart
The GPIO descriptor API is favoured over the plain GPIO API for consumer
drivers. Using it simplifies the driver code.

As the descriptor API handles the active-low flag internally we need to
invert the polarity of all GPIO operations in the driver.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c | 51 ++-
 1 file changed, 13 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
index 7114ea672e69..29bda16afbdc 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
@@ -13,14 +13,13 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "../dss/omapdss.h"
 
 struct panel_drv_data {
struct omap_dss_device dssdev;
 
-   int pd_gpio;
+   struct gpio_desc *pd_gpio;
 
struct videomode vm;
 };
@@ -57,8 +56,8 @@ static int tfp410_enable(struct omap_dss_device *dssdev)
if (r)
return r;
 
-   if (gpio_is_valid(ddata->pd_gpio))
-   gpio_set_value_cansleep(ddata->pd_gpio, 1);
+   if (ddata->pd_gpio)
+   gpiod_set_value_cansleep(ddata->pd_gpio, 0);
 
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 
@@ -73,8 +72,8 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
if (!omapdss_device_is_enabled(dssdev))
return;
 
-   if (gpio_is_valid(ddata->pd_gpio))
-   gpio_set_value_cansleep(ddata->pd_gpio, 0);
+   if (ddata->pd_gpio)
+   gpiod_set_value_cansleep(ddata->pd_gpio, 0);
 
src->ops->disable(src);
 
@@ -119,30 +118,11 @@ static const struct omap_dss_device_ops tfp410_ops = {
.set_timings= tfp410_set_timings,
 };
 
-static int tfp410_probe_of(struct platform_device *pdev)
-{
-   struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-   struct device_node *node = pdev->dev.of_node;
-   int gpio;
-
-   gpio = of_get_named_gpio(node, "powerdown-gpios", 0);
-
-   if (gpio_is_valid(gpio) || gpio == -ENOENT) {
-   ddata->pd_gpio = gpio;
-   } else {
-   if (gpio != -EPROBE_DEFER)
-   dev_err(&pdev->dev, "failed to parse PD gpio\n");
-   return gpio;
-   }
-
-   return 0;
-}
-
 static int tfp410_probe(struct platform_device *pdev)
 {
struct panel_drv_data *ddata;
struct omap_dss_device *dssdev;
-   int r;
+   struct gpio_desc *gpio;
 
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
@@ -150,20 +130,15 @@ static int tfp410_probe(struct platform_device *pdev)
 
platform_set_drvdata(pdev, ddata);
 
-   r = tfp410_probe_of(pdev);
-   if (r)
-   return r;
-
-   if (gpio_is_valid(ddata->pd_gpio)) {
-   r = devm_gpio_request_one(&pdev->dev, ddata->pd_gpio,
-   GPIOF_OUT_INIT_LOW, "tfp410 PD");
-   if (r) {
-   dev_err(&pdev->dev, "Failed to request PD GPIO %d\n",
-   ddata->pd_gpio);
-   return r;
-   }
+   /* Powerdown GPIO */
+   gpio = devm_gpiod_get_optional(&pdev->dev, "powerdown", GPIOD_OUT_HIGH);
+   if (IS_ERR(gpio)) {
+   dev_err(&pdev->dev, "failed to parse powerdown gpio\n");
+   return PTR_ERR(gpio);
}
 
+   ddata->pd_gpio = gpio;
+
dssdev = &ddata->dssdev;
dssdev->ops = &tfp410_ops;
dssdev->dev = &pdev->dev;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 09/21] drm/omap: panel-tpo-td028ttec1: Drop unneeded linux/gpio.h header

2018-08-06 Thread Laurent Pinchart
The driver doesn't use GPIOs and thus doesn't need to include the
linux/gpio.h header.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c 
b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
index fc08f71b95a0..ecb903a93cf4 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
@@ -27,7 +27,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "../dss/omapdss.h"
 
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 12/21] drm/omap: dss: Add device operations flags

2018-08-06 Thread Laurent Pinchart
When an omap_dss_device operation can be implemented in multiple places
in a chain of devices, it is important to find out which device to
address to perfom the operation. This is currently done by calling the
operation on the display device at the end of the chain, and recursively
delagating the operation to the previous device if it can't be performed
locally. The drawback of this approach is an increased complexity in
omap_dss_device drivers.

In order to simplify the drivers, we will switch from a recursive model
to an interative model, centralizing the complexity in a single
location. This requires knowing which operations an omap_dss_device
supports at runtime. We can already test which operations are
implemented by checking the operation pointer, but implemented
operations can require resources whose availability varies between
systems. For instance a hot-plug signal from a connector can be wired to
a GPIO or to a bridge chip.

Add operation flags that can be set in the omap_dss_device structure by
drivers to signal support for operations.

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

diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 60e4269e6c88..30ad9985776f 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -388,6 +388,18 @@ struct omap_dss_device_ops {
};
 };
 
+/**
+ * enum omap_dss_device_ops_flag - Indicates which device ops are supported
+ * @OMAP_DSS_DEVICE_OP_DETECT: The device supports output connection detection
+ * @OMAP_DSS_DEVICE_OP_HPD: The device supports all hot-plug-related operations
+ * @OMAP_DSS_DEVICE_OP_EDID: The device supports readind EDID
+ */
+enum omap_dss_device_ops_flag {
+   OMAP_DSS_DEVICE_OP_DETECT = BIT(0),
+   OMAP_DSS_DEVICE_OP_HPD = BIT(1),
+   OMAP_DSS_DEVICE_OP_EDID = BIT(2),
+};
+
 enum omap_dss_device_type {
OMAP_DSS_DEVICE_TYPE_OUTPUT = (1 << 0),
OMAP_DSS_DEVICE_TYPE_DISPLAY = (1 << 1),
@@ -421,6 +433,7 @@ struct omap_dss_device {
 
const struct omap_dss_driver *driver;
const struct omap_dss_device_ops *ops;
+   unsigned long ops_flags;
 
/* helper variable for driver suspend/resume */
bool activate_after_resume;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 13/21] drm/omap: Don't call .detect() operation recursively

2018-08-06 Thread Laurent Pinchart
Instead of calling the .detect() operation recursively from the display
device back to the first device that provides hot plug detection
support, iterate over the devices manually in the DRM connector
.detect() implementation. This moves the complexity to a single central
location and simplifies the logic in omap_dss_device drivers.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  2 ++
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  |  6 ++--
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   |  4 ++-
 drivers/gpu/drm/omapdrm/omap_connector.c   | 36 ++
 4 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index a639a86cd47b..f1674b3eee50 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -372,6 +372,8 @@ static int dvic_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_DVI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
+   dssdev->ops_flags = ddata->hpd_gpio || ddata->i2c_adapter
+ ? OMAP_DSS_DEVICE_OP_DETECT : 0;
 
omapdss_display_init(dssdev);
omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 54bfd7156360..0d22d7004c98 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -141,10 +141,7 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
struct omap_dss_device *src = dssdev->src;
bool connected;
 
-   if (ddata->hpd_gpio)
-   connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
-   else
-   connected = src->ops->detect(src);
+   connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
if (!connected && src->ops->hdmi.lost_hotplug)
src->ops->hdmi.lost_hotplug(src);
return connected;
@@ -317,6 +314,7 @@ static int hdmic_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(0);
+   dssdev->ops_flags = ddata->hpd_gpio ? OMAP_DSS_DEVICE_OP_DETECT : 0;
 
omapdss_display_init(dssdev);
omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index 0cc7bd656473..e30ead0cacb7 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -132,8 +132,9 @@ static bool tpd_detect(struct omap_dss_device *dssdev)
 {
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
-   bool connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
+   bool connected;
 
+   connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
if (!connected && src->ops->hdmi.lost_hotplug)
src->ops->hdmi.lost_hotplug(src);
return connected;
@@ -288,6 +289,7 @@ static int tpd_probe(struct platform_device *pdev)
dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI;
dssdev->owner = THIS_MODULE;
dssdev->of_ports = BIT(1) | BIT(0);
+   dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT;
 
dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1);
if (IS_ERR(dssdev->next)) {
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index f9cc04c7c0fa..4729af395156 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -61,26 +61,36 @@ 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 = omap_connector->dssdev;
-   enum drm_connector_status ret;
+   struct omap_dss_device *dssdev;
+   enum drm_connector_status status;
+
+   for (dssdev = omap_connector->dssdev; dssdev; dssdev = dssdev->src) {
+   if (dssdev->ops_flags & OMAP_DSS_DEVICE_OP_DETECT)
+   break;
+   }
 
-   if (dssdev->ops->detect) {
+   if (dssdev) {
if (dssdev->ops->detect(dssdev))
-   ret = connector_status_connected;
+   status = connector_status_connected;
else
-   ret = connector_status_disconnected;
-   } else if (dssdev->type == OMAP_DISPLAY_TYPE_DPI ||
-   dssdev->type == OMAP_DISPLAY_TYPE_DBI ||
-   dssdev->type == OMAP_DISPLAY_TYPE_SDI ||
-   dss

[PATCH v2 04/21] drm/omap: Check omap_dss_device type based on the output_type field

2018-08-06 Thread Laurent Pinchart
Various functions that need to differentiate between omap_dss_device
instances corresponding to displays and to internal encoders use the
omap_dss_device.driver field, which is only set for display instances.
This gets in the way of the omap_dss_device operations refactoring.
Replace that with a check based on the output_type field which is set
for all omap_dss_device instances but displays.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/base.c| 4 ++--
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 6 ++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 2051bab30484..c5bfd51c735a 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -164,7 +164,7 @@ struct omap_dss_device *omapdss_device_get_next(struct 
omap_dss_device *from,
 * Accept display entities if the display type is requested,
 * and output entities if the output type is requested.
 */
-   if ((type & OMAP_DSS_DEVICE_TYPE_DISPLAY) && dssdev->driver)
+   if ((type & OMAP_DSS_DEVICE_TYPE_DISPLAY) && 
!dssdev->output_type)
goto done;
if ((type & OMAP_DSS_DEVICE_TYPE_OUTPUT) && dssdev->id &&
dssdev->next)
@@ -223,7 +223,7 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
dev_dbg(dst->dev, "disconnect\n");
 
if (!dst->id && !omapdss_device_is_connected(dst)) {
-   WARN_ON(!dst->driver);
+   WARN_ON(dst->output_type);
return;
}
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index c29633765898..6d22b38f2ce5 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -406,6 +406,12 @@ struct omap_dss_device {
unsigned int alias_id;
 
enum omap_display_type type;
+   /*
+* DSS output type that this device generates (for DSS internal devices)
+* or requires (for external encoders). Must be OMAP_DISPLAY_TYPE_NONE
+* for display devices (connectors and panels) and to non-zero value for
+* all other devices.
+*/
enum omap_display_type output_type;
 
const char *name;
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 11/21] drm/omap: Move most omap_dss_driver operations to omap_dss_device_ops

2018-08-06 Thread Laurent Pinchart
omap_dss_device instances have two ops structures, omap_dss_driver and
omap_dss_device_ops. The former is used for devices at the end of the
pipeline (a.k.a. display devices), and the latter for intermediate
devices.

Having two sets of operations isn't convenient as code that iterates
over omap_dss_device instances need to take them both into account.
There's currently a reasonably small amount of such code, but more will
be introduced to move the driver away from recursive operations. To
simplify current and future code, move all operations that are not
specific to the display device to the omap_dss_device_ops.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 .../gpu/drm/omapdrm/displays/connector-analog-tv.c |  4 +-
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  4 +-
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  | 31 +++--
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   | 14 +++---
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c   |  4 +-
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c| 12 +++--
 .../omapdrm/displays/panel-lgphilips-lb035q02.c|  4 +-
 .../drm/omapdrm/displays/panel-nec-nl8048hl11.c|  4 +-
 .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c |  4 +-
 .../drm/omapdrm/displays/panel-sony-acx565akm.c|  4 +-
 .../drm/omapdrm/displays/panel-tpo-td028ttec1.c|  4 +-
 .../drm/omapdrm/displays/panel-tpo-td043mtea1.c|  4 +-
 drivers/gpu/drm/omapdrm/dss/base.c | 12 +
 drivers/gpu/drm/omapdrm/dss/dss.c  |  2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4.c|  3 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c|  3 +-
 drivers/gpu/drm/omapdrm/dss/omapdss.h  | 54 ++
 drivers/gpu/drm/omapdrm/omap_connector.c   | 37 +++
 drivers/gpu/drm/omapdrm/omap_crtc.c|  2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c | 12 ++---
 drivers/gpu/drm/omapdrm/omap_encoder.c | 25 +-
 21 files changed, 106 insertions(+), 137 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index d59b4f2e22dc..563fc7e618b3 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -119,7 +119,7 @@ static int tvc_check_timings(struct omap_dss_device *dssdev,
return src->ops->check_timings(src, vm);
 }
 
-static const struct omap_dss_driver tvc_driver = {
+static const struct omap_dss_device_ops tvc_ops = {
.connect= tvc_connect,
.disconnect = tvc_disconnect,
 
@@ -146,7 +146,7 @@ static int tvc_probe(struct platform_device *pdev)
ddata->vm = tvc_pal_vm;
 
dssdev = &ddata->dssdev;
-   dssdev->driver = &tvc_driver;
+   dssdev->ops = &tvc_ops;
dssdev->dev = &pdev->dev;
dssdev->type = OMAP_DISPLAY_TYPE_VENC;
dssdev->owner = THIS_MODULE;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index 39e7d0be887f..a639a86cd47b 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -265,7 +265,7 @@ static void dvic_disable_hpd(struct omap_dss_device *dssdev)
mutex_unlock(&ddata->hpd_lock);
 }
 
-static const struct omap_dss_driver dvic_driver = {
+static const struct omap_dss_device_ops dvic_ops = {
.connect= dvic_connect,
.disconnect = dvic_disconnect,
 
@@ -367,7 +367,7 @@ static int dvic_probe(struct platform_device *pdev)
ddata->vm = dvic_default_vm;
 
dssdev = &ddata->dssdev;
-   dssdev->driver = &dvic_driver;
+   dssdev->ops = &dvic_ops;
dssdev->dev = &pdev->dev;
dssdev->type = OMAP_DISPLAY_TYPE_DVI;
dssdev->owner = THIS_MODULE;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index d39480b8cf6b..54bfd7156360 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -132,7 +132,7 @@ static int hdmic_read_edid(struct omap_dss_device *dssdev,
 {
struct omap_dss_device *src = dssdev->src;
 
-   return src->ops->hdmi.read_edid(src, edid, len);
+   return src->ops->read_edid(src, edid, len);
 }
 
 static bool hdmic_detect(struct omap_dss_device *dssdev)
@@ -144,7 +144,7 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
if (ddata->hpd_gpio)
connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
else
-   connected = src->ops->hdmi.detect(src);
+   connected = src->ops->detect(src);
if (!connected && src->ops->hdmi.lost_hotplug)
src->ops->hdmi.lost_hotplug(src);
return connected;
@@ -164,8 +164,8 @@ static int hdmic_register_hpd_cb(str

[PATCH v2 07/21] drm/omap: panel-nec-nl8048hl11: Convert to the GPIO descriptors API

2018-08-06 Thread Laurent Pinchart
The GPIO descriptor API is favoured over the plain GPIO API for consumer
drivers. Using it simplifies the driver code.

The reset GPIO is mandatory, so drop conditional tests through the
driver. The qvga GPIO is unused, so drop it completely.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 .../drm/omapdrm/displays/panel-nec-nl8048hl11.c| 54 +-
 1 file changed, 11 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c 
b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
index b4dba55b678b..767ffd2fa0f4 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
@@ -11,11 +11,10 @@
  * (at your option) any later version.
  */
 
-#include 
 #include 
-#include 
 #include 
-#include 
+#include 
+#include 
 
 #include "../dss/omapdss.h"
 
@@ -24,8 +23,7 @@ struct panel_drv_data {
 
struct videomode vm;
 
-   int res_gpio;
-   int qvga_gpio;
+   struct gpio_desc *res_gpio;
 
struct spi_device *spi;
 };
@@ -140,8 +138,7 @@ static int nec_8048_enable(struct omap_dss_device *dssdev)
if (r)
return r;
 
-   if (gpio_is_valid(ddata->res_gpio))
-   gpio_set_value_cansleep(ddata->res_gpio, 1);
+   gpiod_set_value_cansleep(ddata->res_gpio, 1);
 
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 
@@ -156,8 +153,7 @@ static void nec_8048_disable(struct omap_dss_device *dssdev)
if (!omapdss_device_is_enabled(dssdev))
return;
 
-   if (gpio_is_valid(ddata->res_gpio))
-   gpio_set_value_cansleep(ddata->res_gpio, 0);
+   gpiod_set_value_cansleep(ddata->res_gpio, 0);
 
src->ops->disable(src);
 
@@ -203,29 +199,11 @@ static const struct omap_dss_driver nec_8048_ops = {
.check_timings  = nec_8048_check_timings,
 };
 
-static int nec_8048_probe_of(struct spi_device *spi)
-{
-   struct device_node *node = spi->dev.of_node;
-   struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
-   int gpio;
-
-   gpio = of_get_named_gpio(node, "reset-gpios", 0);
-   if (!gpio_is_valid(gpio)) {
-   dev_err(&spi->dev, "failed to parse enable gpio\n");
-   return gpio;
-   }
-   ddata->res_gpio = gpio;
-
-   /* XXX the panel spec doesn't mention any QVGA pin?? */
-   ddata->qvga_gpio = -ENOENT;
-
-   return 0;
-}
-
 static int nec_8048_probe(struct spi_device *spi)
 {
struct panel_drv_data *ddata;
struct omap_dss_device *dssdev;
+   struct gpio_desc *gpio;
int r;
 
dev_dbg(&spi->dev, "%s\n", __func__);
@@ -249,23 +227,13 @@ static int nec_8048_probe(struct spi_device *spi)
 
ddata->spi = spi;
 
-   r = nec_8048_probe_of(spi);
-   if (r)
-   return r;
-
-   if (gpio_is_valid(ddata->qvga_gpio)) {
-   r = devm_gpio_request_one(&spi->dev, ddata->qvga_gpio,
-   GPIOF_OUT_INIT_HIGH, "lcd QVGA");
-   if (r)
-   return r;
+   gpio = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW);
+   if (IS_ERR(gpio)) {
+   dev_err(&spi->dev, "failed to get reset gpio\n");
+   return PTR_ERR(gpio);
}
 
-   if (gpio_is_valid(ddata->res_gpio)) {
-   r = devm_gpio_request_one(&spi->dev, ddata->res_gpio,
-   GPIOF_OUT_INIT_LOW, "lcd RES");
-   if (r)
-   return r;
-   }
+   ddata->res_gpio = gpio;
 
ddata->vm = nec_8048_panel_vm;
 
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 05/21] drm/omap: connector-hdmi: Convert to the GPIO descriptors API

2018-08-06 Thread Laurent Pinchart
The GPIO descriptor API is favoured over the plain GPIO API for consumer
drivers. Using it simplifies the driver code.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 57 ---
 1 file changed, 20 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index e9878da5bfdb..d39480b8cf6b 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -10,12 +10,10 @@
  */
 
 #include 
-#include 
 #include 
-#include 
-#include 
-#include 
 #include 
+#include 
+#include 
 
 #include 
 
@@ -46,7 +44,7 @@ struct panel_drv_data {
 
struct videomode vm;
 
-   int hpd_gpio;
+   struct gpio_desc *hpd_gpio;
 };
 
 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
@@ -143,8 +141,8 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
struct omap_dss_device *src = dssdev->src;
bool connected;
 
-   if (gpio_is_valid(ddata->hpd_gpio))
-   connected = gpio_get_value_cansleep(ddata->hpd_gpio);
+   if (ddata->hpd_gpio)
+   connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
else
connected = src->ops->hdmi.detect(src);
if (!connected && src->ops->hdmi.lost_hotplug)
@@ -160,7 +158,7 @@ static int hdmic_register_hpd_cb(struct omap_dss_device 
*dssdev,
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   if (gpio_is_valid(ddata->hpd_gpio)) {
+   if (ddata->hpd_gpio) {
mutex_lock(&ddata->hpd_lock);
ddata->hpd_cb = cb;
ddata->hpd_cb_data = cb_data;
@@ -178,7 +176,7 @@ static void hdmic_unregister_hpd_cb(struct omap_dss_device 
*dssdev)
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   if (gpio_is_valid(ddata->hpd_gpio)) {
+   if (ddata->hpd_gpio) {
mutex_lock(&ddata->hpd_lock);
ddata->hpd_cb = NULL;
ddata->hpd_cb_data = NULL;
@@ -193,7 +191,7 @@ static void hdmic_enable_hpd(struct omap_dss_device *dssdev)
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   if (gpio_is_valid(ddata->hpd_gpio)) {
+   if (ddata->hpd_gpio) {
mutex_lock(&ddata->hpd_lock);
ddata->hpd_enabled = true;
mutex_unlock(&ddata->hpd_lock);
@@ -207,7 +205,7 @@ static void hdmic_disable_hpd(struct omap_dss_device 
*dssdev)
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
 
-   if (gpio_is_valid(ddata->hpd_gpio)) {
+   if (ddata->hpd_gpio) {
mutex_lock(&ddata->hpd_lock);
ddata->hpd_enabled = false;
mutex_unlock(&ddata->hpd_lock);
@@ -272,26 +270,11 @@ static irqreturn_t hdmic_hpd_isr(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static int hdmic_probe_of(struct platform_device *pdev)
-{
-   struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-   struct device_node *node = pdev->dev.of_node;
-   int gpio;
-
-   /* HPD GPIO */
-   gpio = of_get_named_gpio(node, "hpd-gpios", 0);
-   if (gpio_is_valid(gpio))
-   ddata->hpd_gpio = gpio;
-   else
-   ddata->hpd_gpio = -ENODEV;
-
-   return 0;
-}
-
 static int hdmic_probe(struct platform_device *pdev)
 {
struct panel_drv_data *ddata;
struct omap_dss_device *dssdev;
+   struct gpio_desc *gpio;
int r;
 
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
@@ -301,20 +284,20 @@ static int hdmic_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ddata);
ddata->dev = &pdev->dev;
 
-   r = hdmic_probe_of(pdev);
-   if (r)
-   return r;
-
mutex_init(&ddata->hpd_lock);
 
-   if (gpio_is_valid(ddata->hpd_gpio)) {
-   r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio,
-   GPIOF_DIR_IN, "hdmi_hpd");
-   if (r)
-   return r;
+   /* HPD GPIO */
+   gpio = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN);
+   if (IS_ERR(gpio)) {
+   dev_err(&pdev->dev, "failed to parse HPD gpio\n");
+   return PTR_ERR(gpio);
+   }
+
+   ddata->hpd_gpio = gpio;
 
+   if (ddata->hpd_gpio) {
r = devm_request_threaded_irq(&pdev->dev,
-   gpio_to_irq(ddata->hpd_gpio),
+   gpiod_to_irq(ddata->hpd_gpio),
NULL, hdmic_hpd_isr,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
 

[PATCH v2 02/21] drm/omap: dss: Remove omap_dss_driver .[gs]et_mirror operations

2018-08-06 Thread Laurent Pinchart
The .get_mirror() and .set_mirror() omap_dss_driver operations are
implemented by the panel-tpo-td043mtea1 driver but are never used.
Remove them.

Signed-off-by: Laurent Pinchart 
Reviewed-by: Sebastian Reichel 
---
 .../drm/omapdrm/displays/panel-tpo-td043mtea1.c| 25 ++
 drivers/gpu/drm/omapdrm/dss/omapdss.h  |  3 ---
 2 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c 
b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
index cb6f19f8a0da..34531169c166 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
@@ -62,7 +62,6 @@ struct panel_drv_data {
int nreset_gpio;
u16 gamma[12];
u32 mode;
-   u32 hmirror:1;
u32 vmirror:1;
u32 powered_on:1;
u32 spi_suspended:1;
@@ -151,22 +150,6 @@ static int tpo_td043_write_mirror(struct spi_device *spi, 
bool h, bool v)
return tpo_td043_write(spi, 4, reg4);
 }
 
-static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
-{
-   struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
-
-   ddata->hmirror = enable;
-   return tpo_td043_write_mirror(ddata->spi, ddata->hmirror,
-   ddata->vmirror);
-}
-
-static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
-{
-   struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev);
-
-   return ddata->hmirror;
-}
-
 static ssize_t tpo_td043_vmirror_show(struct device *dev,
struct device_attribute *attr, char *buf)
 {
@@ -188,7 +171,7 @@ static ssize_t tpo_td043_vmirror_store(struct device *dev,
 
val = !!val;
 
-   ret = tpo_td043_write_mirror(ddata->spi, ddata->hmirror, val);
+   ret = tpo_td043_write_mirror(ddata->spi, false, val);
if (ret < 0)
return ret;
 
@@ -307,8 +290,7 @@ static int tpo_td043_power_on(struct panel_drv_data *ddata)
tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_NORMAL);
tpo_td043_write(ddata->spi, 0x20, 0xf0);
tpo_td043_write(ddata->spi, 0x21, 0xf0);
-   tpo_td043_write_mirror(ddata->spi, ddata->hmirror,
-   ddata->vmirror);
+   tpo_td043_write_mirror(ddata->spi, false, ddata->vmirror);
tpo_td043_write_gamma(ddata->spi, ddata->gamma);
 
ddata->powered_on = 1;
@@ -435,9 +417,6 @@ static const struct omap_dss_driver tpo_td043_ops = {
.set_timings= tpo_td043_set_timings,
.get_timings= tpo_td043_get_timings,
.check_timings  = tpo_td043_check_timings,
-
-   .set_mirror = tpo_td043_set_hmirror,
-   .get_mirror = tpo_td043_get_hmirror,
 };
 
 static int tpo_td043_probe_of(struct spi_device *spi)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 01ba919e34df..c29633765898 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -449,9 +449,6 @@ struct omap_dss_driver {
int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
int (*get_te)(struct omap_dss_device *dssdev);
 
-   bool (*get_mirror)(struct omap_dss_device *dssdev);
-   int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
-
int (*memory_read)(struct omap_dss_device *dssdev,
void *buf, size_t size,
u16 x, u16 y, u16 w, u16 h);
-- 
Regards,

Laurent Pinchart

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


[PATCH v2 00/21] omapdrm: Rework the HPD-related operations

2018-08-06 Thread Laurent Pinchart
Hello,

This patch series reworks all the HPD-related operations (detection, EDID
read, HPD callback (un)registration and HPD enable/disable) as a step toward
moving from omap_dss_device to drm_bridge.

All HPD-related operations are called by the omapdrm driver on the
omap_dss_device at the end of display pipeline, and the operations are then
handled directly or forwarded to the previous omap_dss_device in the pipeline.
This causes an issue in our quest to move to drm_bridge: there are currently
no HPD-related operations in the drm_bridge API, as they are implemented
internally by bridge drivers for the drm_connector created by the bridges.

To solve this, we will need to extend the drm_bridge API with HPD-related
operations. This patch series is a prototype of such an API, still local to
omap_dss_device for now.

HPD operations can be implemented by multiple components in a display
pipeline. For instance, the DDC bus of an HDMI connector can be wired to an
I2C bus of the SoC, or to the DDC pins of an HDMI encoder. In the first case
the HDMI connector component will provide EDID access, while in the second
case EDID will be read through the HDMI encoder component. Both components
will thus implement the EDID read operation, but on a particular system only
one of them will be able to provide the feature.

Determining which component provides a feature at runtime is thus required,
and is currently performed through recursive calls. This requires all
components to cooperate in a way that can be implemented locally in the
omapdrm driver but would be too complex for the more generic drm_bridge API.
Our solution is to use flags in the omap_dss_device structure to tell, at
runtime, which features are available. The top-level code can then locate the
component providing a particular feature and then use that component directly.

The series starts with removal of dead or unneeded code in patches 01/21 to
03/21. Patch 04/21 prepares for the merge of the omap_dss_driver and
omap_dss_device_ops structures. Patches then 05/21 to 10/21 convert the driver
from the GPIO API to the GPIO descriptors API (drive-by cleanup).

Patch 11/21 is where the real refactoring starts. It moves most operations
from the omap_dss_driver structure to the omap_dss_device_ops structure in
order to simplify code iterating over pipelines. Patch 12/21 defines the
operation flags, and patches 13/21 and 14/21 make use of them to rework the
.detect(), .register_hpd_cb() and .unregister_hpd_cb() operations. Patches
15/21 and 16/21 remove the unneeded .enable_hpd() and .disable_hpd()
operations. Patch 17/21 moves DSS-specific HPD-related code from
omap_dss_device instances to the omapdrm driver, and patch 18/21 reworks the
.read_edid() operation. Patch 19/21 simplifies the component handling in the
CRTC mode set code, and patches 20/21 and 21/21 finally rework the
.set_hdmi_mode() and .set_infoframe() operations.

The series has been tested on the TI AM57xx EVM with kmstest. Module loading
and removal has been tested as well.

For convenience the patches are available at

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

Compared to v1, the series has been rebased on top of the latest version of
the base series ("[PATCH v3 00/61] omapdrm: Reverse direction of DSS device
(dis)connect operations"). Please see individual patches for detailed
changelogs.

Laurent Pinchart (21):
  drm/omap: dss: Remove unused omap_dss_driver operations
  drm/omap: dss: Remove omap_dss_driver .[gs]et_mirror operations
  drm/omap: Remove unnecessary display output sanity checks
  drm/omap: Check omap_dss_device type based on the output_type field
  drm/omap: connector-hdmi: Convert to the GPIO descriptors API
  drm/omap: encoder-tfp410: Convert to the GPIO descriptors API
  drm/omap: panel-nec-nl8048hl11: Convert to the GPIO descriptors API
  drm/omap: panel-sony-acx565akm: Convert to the GPIO descriptors API
  drm/omap: panel-tpo-td028ttec1: Drop unneeded linux/gpio.h header
  drm/omap: panel-tpo-td043mtea1: Convert to the GPIO descriptors API
  drm/omap: Move most omap_dss_driver operations to omap_dss_device_ops
  drm/omap: dss: Add device operations flags
  drm/omap: Don't call .detect() operation recursively
  drm/omap: Don't call HPD registration operations recursively
  drm/omap: Remove unneeded safety checks in the HPD operations
  drm/omap: Merge HPD enable operation with HPD callback registration
  drm/omap: Move HPD disconnection handling to omap_connector
  drm/omap: Don't call EDID read operation recursively
  drm/omap: Get from CRTC to display device directly
  drm/omap: Pass both output and display omap_dss_device to encoder init
  drm/omap: Don't call HDMI mode and infoframe operations recursively

 .../gpu/drm/omapdrm/displays/connector-analog-tv.c |   4 +-
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  52 +---
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  | 160 +++--
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c

[PATCH v2 01/21] drm/omap: dss: Remove unused omap_dss_driver operations

2018-08-06 Thread Laurent Pinchart
The .probe(), .remove(), .run_test(), .get_rotate() and .set_rotate()
omap_dss_driver operations are not used. Remove them.

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

diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index c00572ecb9d6..01ba919e34df 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -434,9 +434,6 @@ struct omap_dss_device {
 };
 
 struct omap_dss_driver {
-   int (*probe)(struct omap_dss_device *);
-   void (*remove)(struct omap_dss_device *);
-
int (*connect)(struct omap_dss_device *src,
   struct omap_dss_device *dst);
void (*disconnect)(struct omap_dss_device *src,
@@ -444,7 +441,6 @@ struct omap_dss_driver {
 
int (*enable)(struct omap_dss_device *display);
void (*disable)(struct omap_dss_device *display);
-   int (*run_test)(struct omap_dss_device *display, int test);
 
int (*update)(struct omap_dss_device *dssdev,
   u16 x, u16 y, u16 w, u16 h);
@@ -453,9 +449,6 @@ struct omap_dss_driver {
int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
int (*get_te)(struct omap_dss_device *dssdev);
 
-   u8 (*get_rotate)(struct omap_dss_device *dssdev);
-   int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
-
bool (*get_mirror)(struct omap_dss_device *dssdev);
int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
 
-- 
Regards,

Laurent Pinchart

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


Re: SLAB_TYPESAFE_BY_RCU without constructors (was Re: [PATCH v4 13/17] khwasan: add hooks implementation)

2018-08-06 Thread Jan Kara
On Wed 01-08-18 10:46:35, Dmitry Vyukov wrote:
> I guess it would be useful to have such extensive comment for each
> SLAB_TYPESAFE_BY_RCU use explaining why it is needed and how all the
> tricky aspects are handled.
> 
> For example, the one in jbd2 is interesting because it memsets the
> whole object before freeing it into SLAB_TYPESAFE_BY_RCU slab:
> 
> memset(jh, JBD2_POISON_FREE, sizeof(*jh));
> kmem_cache_free(jbd2_journal_head_cache, jh);
> 
> I guess there are also tricky ways how it can all work in the end
> (type-stable state is only a byte, or we check for all possible
> combinations of being overwritten with JBD2_POISON_FREE). But at first
> sight it does look fishy.

The RCU access is used from a single place:

fs/jbd2/transaction.c: jbd2_write_access_granted()

There are also quite some comments explaining why what it does is safe. The
overwrite by JBD2_POISON_FREE is much older than this RCU stuff (honestly I
didn't know about it until this moment) and has nothing to do with the
safety of RCU access.

Honza

-- 
Jan Kara 
SUSE Labs, CR
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 1/5] drm/vc4: Fix TILE_Y_OFFSET definitions

2018-08-06 Thread Boris Brezillon
On Mon, 06 Aug 2018 13:02:48 -0700
Eric Anholt  wrote:

> Boris Brezillon  writes:
> 
> > From: Eric Anholt 
> >
> > Y_OFFSET field starts at bit 8 not 7.
> >
> > Signed-off-by: Eric Anholt 
> > Signed-off-by: Boris Brezillon   
> 
> Your changes in this series have my r-b.  Time to add your ack to my

Adding SoB implicitly means A-b for me, but I can add them if you
prefer. 

> changes in this series and push?

Sure, I was just waiting for your green light after the changes I've
done in patch 3.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 1/5] drm/vc4: Fix TILE_Y_OFFSET definitions

2018-08-06 Thread Eric Anholt
Boris Brezillon  writes:

> From: Eric Anholt 
>
> Y_OFFSET field starts at bit 8 not 7.
>
> Signed-off-by: Eric Anholt 
> Signed-off-by: Boris Brezillon 

Your changes in this series have my r-b.  Time to add your ack to my
changes in this series and push?


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


Re: [PATCH v3 09/10] drm/vc4: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-06 Thread Eric Anholt
Alexandru Gheorghe  writes:

> A new helper function(__drm_atomic_helper_plane_reset) has been added
> for linking a plane with its state and resetting the core
> properties(alpha, rotation, etc.) to their default values.
> Use that instead of duplicating the logic.
>
> __drm_atomic_helper_plane_reset initializes the alpha property to its
> max value, which is defined by the drm core as DRM_BLEND_ALPHA_OPAQUE,
> so nothing changes regarding the alpha value.
>
> Signed-off-by: Alexandru Gheorghe 

Acked-by: Eric Anholt 


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


Re: [PATCH v3 3/8] drm/fb_helper: Introduce hotplug_suspend/resume()

2018-08-06 Thread Alex Deucher
On Mon, Aug 6, 2018 at 3:34 PM, Lukas Wunner  wrote:
> On Mon, Aug 06, 2018 at 03:15:31PM -0400, Lyude Paul wrote:
>> You did mention in the review of one of my other patches that we should avoid
>> disabling polling during runtime suspend, and you're definitely right. I feel
>> a bit silly for not remembering that since I was the one who made it so that
>> i915 does polling in runtime suspend for chips without RPM HPD detection in
>> the first place because it was causing people's displays not to come up on
>> vlv...
>> Anyway: I think if we just leave output polling enabled during runtime 
>> suspend
>> that might actually fix all of the fb_helper locking issues since we won't
>> need to wait on any of the output poll workers to finish, at least I think it
>> should: I'll confirm this when I get into the office
>
> Quoth Imre Deak:
>
>"In i915 polling is on during runtime suspend only if there are outputs
> without hotplug interrupt support. A special case is when an output has
> working HPD interrupts when in D0, but no interrupts when runtime
> suspended. For these we start polling (from a scheduled work) in the
> runtime suspend hook and stop it in the runtime resume hook (again from
> a scheduled work)."
> https://lkml.org/lkml/2018/2/12/330
>
> nouveau only uses runtime PM on discrete GPUs in dual GPU laptops.
> Resuming the GPU from D3cold to D0 every few seconds to poll the
> outputs would waste too much power on such machines.
>
> The question is, why is polling running at all, since all modern
> laptops have HPD-capable ports such as DP?
>

At least on AMD GPUs, the GPU has to be powered up for HPD interrupts
to work.  On hybrid graphics laptops, depending on the OEM
configuration, the hotplug events are caught by the ACPI controller on
the motherboard when the GPU is powered down and an ACPI event is
generated which the driver can listen for and then tell userspace.
I'm not sure how nvidia handles this.  Also, some display connections
(e.g., analog DACs) don't support hotplug interrupts in the first
place so the only way to go is polling.

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


Re: [PATCH v3 3/8] drm/fb_helper: Introduce hotplug_suspend/resume()

2018-08-06 Thread Daniel Vetter
On Mon, Aug 06, 2018 at 09:34:57PM +0200, Lukas Wunner wrote:
> On Mon, Aug 06, 2018 at 03:15:31PM -0400, Lyude Paul wrote:
> > You did mention in the review of one of my other patches that we should 
> > avoid
> > disabling polling during runtime suspend, and you're definitely right. I 
> > feel
> > a bit silly for not remembering that since I was the one who made it so that
> > i915 does polling in runtime suspend for chips without RPM HPD detection in
> > the first place because it was causing people's displays not to come up on
> > vlv...
> > Anyway: I think if we just leave output polling enabled during runtime 
> > suspend
> > that might actually fix all of the fb_helper locking issues since we won't
> > need to wait on any of the output poll workers to finish, at least I think 
> > it
> > should: I'll confirm this when I get into the office
> 
> Quoth Imre Deak:
> 
>"In i915 polling is on during runtime suspend only if there are outputs
> without hotplug interrupt support. A special case is when an output has
> working HPD interrupts when in D0, but no interrupts when runtime
> suspended. For these we start polling (from a scheduled work) in the
> runtime suspend hook and stop it in the runtime resume hook (again from
> a scheduled work)."
> https://lkml.org/lkml/2018/2/12/330
> 
> nouveau only uses runtime PM on discrete GPUs in dual GPU laptops.
> Resuming the GPU from D3cold to D0 every few seconds to poll the
> outputs would waste too much power on such machines.
> 
> The question is, why is polling running at all, since all modern
> laptops have HPD-capable ports such as DP?

Note we don't fully sync with the poll worker here, we just update the
polling flags and let the poll worker lazily notice the change (and stop
itsefl). That avoids the deadlock. It also means that the poll worker must
call pm_runtime_get() in all the right places though.

On resume we need to kick it again, but that doesn't have a deadlock
potential.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 3/8] drm/fb_helper: Introduce hotplug_suspend/resume()

2018-08-06 Thread Lukas Wunner
On Mon, Aug 06, 2018 at 03:15:31PM -0400, Lyude Paul wrote:
> You did mention in the review of one of my other patches that we should avoid
> disabling polling during runtime suspend, and you're definitely right. I feel
> a bit silly for not remembering that since I was the one who made it so that
> i915 does polling in runtime suspend for chips without RPM HPD detection in
> the first place because it was causing people's displays not to come up on
> vlv...
> Anyway: I think if we just leave output polling enabled during runtime suspend
> that might actually fix all of the fb_helper locking issues since we won't
> need to wait on any of the output poll workers to finish, at least I think it
> should: I'll confirm this when I get into the office

Quoth Imre Deak:

   "In i915 polling is on during runtime suspend only if there are outputs
without hotplug interrupt support. A special case is when an output has
working HPD interrupts when in D0, but no interrupts when runtime
suspended. For these we start polling (from a scheduled work) in the
runtime suspend hook and stop it in the runtime resume hook (again from
a scheduled work)."
https://lkml.org/lkml/2018/2/12/330

nouveau only uses runtime PM on discrete GPUs in dual GPU laptops.
Resuming the GPU from D3cold to D0 every few seconds to poll the
outputs would waste too much power on such machines.

The question is, why is polling running at all, since all modern
laptops have HPD-capable ports such as DP?

Thanks,

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


Re: [PATCH v4 7/8] drm/nouveau: Fix deadlocks in nouveau_connector_detect()

2018-08-06 Thread Lyude Paul
On Mon, 2018-08-06 at 11:15 +0200, Daniel Vetter wrote:
> On Wed, Aug 01, 2018 at 05:14:57PM -0400, Lyude Paul wrote:
> > When we disable hotplugging on the GPU, we need to be able to
> > synchronize with each connector's hotplug interrupt handler before the
> > interrupt is finally disabled. This can be a problem however, since
> > nouveau_connector_detect() currently grabs a runtime power reference
> > when handling connector probing. This will deadlock the runtime suspend
> > handler like so:
> > 
> > [  861.480896] INFO: task kworker/0:2:61 blocked for more than 120
> > seconds.
> > [  861.483290]   Tainted: G   O  4.18.0-rc6Lyude-Test+ #1
> > [  861.485158] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables
> > this message.
> > [  861.486332] kworker/0:2 D061  2 0x8000
> > [  861.487044] Workqueue: events nouveau_display_hpd_work [nouveau]
> > [  861.487737] Call Trace:
> > [  861.488394]  __schedule+0x322/0xaf0
> > [  861.489070]  schedule+0x33/0x90
> > [  861.489744]  rpm_resume+0x19c/0x850
> > [  861.490392]  ? finish_wait+0x90/0x90
> > [  861.491068]  __pm_runtime_resume+0x4e/0x90
> > [  861.491753]  nouveau_display_hpd_work+0x22/0x60 [nouveau]
> > [  861.492416]  process_one_work+0x231/0x620
> > [  861.493068]  worker_thread+0x44/0x3a0
> > [  861.493722]  kthread+0x12b/0x150
> > [  861.494342]  ? wq_pool_ids_show+0x140/0x140
> > [  861.494991]  ? kthread_create_worker_on_cpu+0x70/0x70
> > [  861.495648]  ret_from_fork+0x3a/0x50
> > [  861.496304] INFO: task kworker/6:2:320 blocked for more than 120
> > seconds.
> > [  861.496968]   Tainted: G   O  4.18.0-rc6Lyude-Test+ #1
> > [  861.497654] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables
> > this message.
> > [  861.498341] kworker/6:2 D0   320  2 0x8080
> > [  861.499045] Workqueue: pm pm_runtime_work
> > [  861.499739] Call Trace:
> > [  861.500428]  __schedule+0x322/0xaf0
> > [  861.501134]  ? wait_for_completion+0x104/0x190
> > [  861.501851]  schedule+0x33/0x90
> > [  861.502564]  schedule_timeout+0x3a5/0x590
> > [  861.503284]  ? mark_held_locks+0x58/0x80
> > [  861.503988]  ? _raw_spin_unlock_irq+0x2c/0x40
> > [  861.504710]  ? wait_for_completion+0x104/0x190
> > [  861.505417]  ? trace_hardirqs_on_caller+0xf4/0x190
> > [  861.506136]  ? wait_for_completion+0x104/0x190
> > [  861.506845]  wait_for_completion+0x12c/0x190
> > [  861.507555]  ? wake_up_q+0x80/0x80
> > [  861.508268]  flush_work+0x1c9/0x280
> > [  861.508990]  ? flush_workqueue_prep_pwqs+0x1b0/0x1b0
> > [  861.509735]  nvif_notify_put+0xb1/0xc0 [nouveau]
> > [  861.510482]  nouveau_display_fini+0xbd/0x170 [nouveau]
> > [  861.511241]  nouveau_display_suspend+0x67/0x120 [nouveau]
> > [  861.511969]  nouveau_do_suspend+0x5e/0x2d0 [nouveau]
> > [  861.512715]  nouveau_pmops_runtime_suspend+0x47/0xb0 [nouveau]
> > [  861.513435]  pci_pm_runtime_suspend+0x6b/0x180
> > [  861.514165]  ? pci_has_legacy_pm_support+0x70/0x70
> > [  861.514897]  __rpm_callback+0x7a/0x1d0
> > [  861.515618]  ? pci_has_legacy_pm_support+0x70/0x70
> > [  861.516313]  rpm_callback+0x24/0x80
> > [  861.517027]  ? pci_has_legacy_pm_support+0x70/0x70
> > [  861.517741]  rpm_suspend+0x142/0x6b0
> > [  861.518449]  pm_runtime_work+0x97/0xc0
> > [  861.519144]  process_one_work+0x231/0x620
> > [  861.519831]  worker_thread+0x44/0x3a0
> > [  861.520522]  kthread+0x12b/0x150
> > [  861.521220]  ? wq_pool_ids_show+0x140/0x140
> > [  861.521925]  ? kthread_create_worker_on_cpu+0x70/0x70
> > [  861.522622]  ret_from_fork+0x3a/0x50
> > [  861.523299] INFO: task kworker/6:0:1329 blocked for more than 120
> > seconds.
> > [  861.523977]   Tainted: G   O  4.18.0-rc6Lyude-Test+ #1
> > [  861.524644] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables
> > this message.
> > [  861.525349] kworker/6:0 D0  1329  2 0x8000
> > [  861.526073] Workqueue: events nvif_notify_work [nouveau]
> > [  861.526751] Call Trace:
> > [  861.527411]  __schedule+0x322/0xaf0
> > [  861.528089]  schedule+0x33/0x90
> > [  861.528758]  rpm_resume+0x19c/0x850
> > [  861.529399]  ? finish_wait+0x90/0x90
> > [  861.530073]  __pm_runtime_resume+0x4e/0x90
> > [  861.530798]  nouveau_connector_detect+0x7e/0x510 [nouveau]
> > [  861.531459]  ? ww_mutex_lock+0x47/0x80
> > [  861.532097]  ? ww_mutex_lock+0x47/0x80
> > [  861.532819]  ? drm_modeset_lock+0x88/0x130 [drm]
> > [  861.533481]  drm_helper_probe_detect_ctx+0xa0/0x100 [drm_kms_helper]
> > [  861.534127]  drm_helper_hpd_irq_event+0xa4/0x120 [drm_kms_helper]
> > [  861.534940]  nouveau_connector_hotplug+0x98/0x120 [nouveau]
> > [  861.535556]  nvif_notify_work+0x2d/0xb0 [nouveau]
> > [  861.536221]  process_one_work+0x231/0x620
> > [  861.536994]  worker_thread+0x44/0x3a0
> > [  861.537757]  kthread+0x12b/0x150
> > [  861.538463]  ? wq_pool_ids_show+0x140/0x140
> > [  861.539102]  ? kthread_create_worker_on_cpu+0x70/0x70
> > [  861.539815]  ret_from_fork+0x3a/0x50
> > [  8

Re: [PATCH v3 3/8] drm/fb_helper: Introduce hotplug_suspend/resume()

2018-08-06 Thread Lyude Paul
On Mon, 2018-08-06 at 10:43 +0200, Daniel Vetter wrote:
> On Mon, Jul 30, 2018 at 08:39:48PM -0400, Lyude Paul wrote:
> > I'm sure I don't need to tell you that fb_helper's locking is a mess.
> > That being said; fb_helper's locking mess can seriously complicate the
> > runtime suspend/resume operations of drivers because it can invoke
> > atomic commits and connector probing from anywhere that calls
> > drm_fb_helper_hotplug_event(). Since most drivers use
> > drm_fb_helper_output_poll_changed() as their output_poll_changed
> > handler, this can happen in every single context that can fire off a
> > hotplug event. An example:
> 
> Uh, I think this ever more looks like a serious rabbit hole between
> nouveau and rpm. It looks like nouveau tries to use rpm as the outermost
> lock, surrounding every other drm lock there is. That doesn't really work,
> and means you'll keep fighting drm core locking forever.
> 
> All other rpm supporting drivers (i915, and the pile of armsoc ones) push
> their rpm_get/put dance way down into the low-level callbacks. That then
> allows you to fix all the trouble with probing, i2x, dp_aux and stuff
> abitrarily nesting (since rpm itself is refcounted).
> 
> But I'm not really sure why nouveau is different here.
A quick note: this isn't a problem unique to nouveau; I already have
(apparently incorrect according to pm runtime maintainers) hacks that fix
these in amdgpu that I'm planning on reapproaching with a proper fix.

That being said: i915 is also more of a special case compared to other
drivers, mainly because i915 does still have to deal with all these problems
but has it's own handlers that simplify dealing with it. For runtime resume,
you guys call down to disable_rpm_wakeref_asserts() during a portion of the
runtime suspend process to avoid the potential of something trying to grab a
runtime power reference and deadlocking the process, and additionally do the
same thing in your irq handler in i915_irq.c:

/* IRQs are synced during runtime_suspend, we don't require a wakeref
*/
disable_rpm_wakeref_asserts(dev_priv);

This essentially translates to the same thing that we're doing here with
nouveau: preventing any calls that would potentially call down to
pm_runtime_resume() so that the runtime suspend handler won't deadlock while
trying to disable HPD irqs. Likewise-this also ensures that you can call
intel_pm_runtime_get()/intel_pm_runtime_put() much lower on the stack without
having to worry about the potential for deadlocks.

While I haven't addressed it in this patchset yet, I pretty much want to do
the same thing for handling nouveau's current issues with i2c and dp aux: grab
runtime power references deeper, and avoid resuming the device in runtime
suspend/resume callbacks.

You did mention in the review of one of my other patches that we should avoid
disabling polling during runtime suspend, and you're definitely right. I feel
a bit silly for not remembering that since I was the one who made it so that
i915 does polling in runtime suspend for chips without RPM HPD detection in
the first place because it was causing people's displays not to come up on
vlv...
Anyway: I think if we just leave output polling enabled during runtime suspend
that might actually fix all of the fb_helper locking issues since we won't
need to wait on any of the output poll workers to finish, at least I think it
should: I'll confirm this when I get into the office

> -Daniel
> 
> > 
> > [  246.669625] INFO: task kworker/4:0:37 blocked for more than 120
> > seconds.
> > [  246.673398]   Not tainted 4.18.0-rc5Lyude-Test+ #2
> > [  246.675271] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables
> > this message.
> > [  246.676527] kworker/4:0 D037  2 0x8000
> > [  246.677580] Workqueue: events output_poll_execute [drm_kms_helper]
> > [  246.678704] Call Trace:
> > [  246.679753]  __schedule+0x322/0xaf0
> > [  246.680916]  schedule+0x33/0x90
> > [  246.681924]  schedule_preempt_disabled+0x15/0x20
> > [  246.683023]  __mutex_lock+0x569/0x9a0
> > [  246.684035]  ? kobject_uevent_env+0x117/0x7b0
> > [  246.685132]  ? drm_fb_helper_hotplug_event.part.28+0x20/0xb0
> > [drm_kms_helper]
> > [  246.686179]  mutex_lock_nested+0x1b/0x20
> > [  246.687278]  ? mutex_lock_nested+0x1b/0x20
> > [  246.688307]  drm_fb_helper_hotplug_event.part.28+0x20/0xb0
> > [drm_kms_helper]
> > [  246.689420]  drm_fb_helper_output_poll_changed+0x23/0x30
> > [drm_kms_helper]
> > [  246.690462]  drm_kms_helper_hotplug_event+0x2a/0x30 [drm_kms_helper]
> > [  246.691570]  output_poll_execute+0x198/0x1c0 [drm_kms_helper]
> > [  246.692611]  process_one_work+0x231/0x620
> > [  246.693725]  worker_thread+0x214/0x3a0
> > [  246.694756]  kthread+0x12b/0x150
> > [  246.695856]  ? wq_pool_ids_show+0x140/0x140
> > [  246.696888]  ? kthread_create_worker_on_cpu+0x70/0x70
> > [  246.697998]  ret_from_fork+0x3a/0x50
> > [  246.699034] INFO: task kworker/0:1:60 blocked for more than 120
> > seco

[Bug 107153] 4.18-rc3 crash on hdmi (0010:dm_update_crtcs_state+0x41e/0x4a0)

2018-08-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=107153

--- Comment #25 from Patrik Kullman  ---
Any idea when this will go upstream?
Anywhere to track it?

-- 
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: [RFC] drm: Allow DRM_IOCTL_MODE_MAP_DUMB for render nodes

2018-08-06 Thread Rob Herring
On Fri, Aug 3, 2018 at 1:50 PM Sean Paul  wrote:
>
> On Fri, Aug 03, 2018 at 06:03:50PM +0100, Emil Velikov wrote:
> > On 3 August 2018 at 16:06, Martin Fuzzey  
> > wrote:
> > > Hi Emil,
> > >
> > > On 03/08/18 14:35, Emil Velikov wrote:
> > >>
> > >> Hi Martin,
> > >>
> > >> On 1 August 2018 at 15:24, Martin Fuzzey 
> > >> wrote:
> > >>
> > >> Let's start with the not-so obvious question:
> > >> Why does one open the imx as render node?
> > >>
> > >> Of the top of my head:
> > >> There is nothing in egl/android that should require an authenticated
> > >> device.
> > >> Hence, using a card node should be fine - the etnaviv code opens the
> > >> render node it needs.
> > >
> > >
> > > Yes, the problem is not in egl/android but in the scanout buffer 
> > > allocation
> > > code.
> > >
> > > etnaviv opens the render node on the *GPU* (for submitting GPU commands),
> > > that part is fine.
> > >
> > > But scanout buffers need to be allocated from imx-drm not etnaviv.
> > >
> > > This done by renderonly_create_kms_dumb_buffer_for_resource()
> > > [src/gallium/auxiliary/renderonly/renderonly.c]
> > > Which uses DRM_IOCTL_MODE_CREATE_DUMB followed by
> > > DRM_IOCTL_PRIME_FD_TO_HANDLE
> > > on the "kms_fd" (probably poorly named because it's not actually used for
> > > modesetting)
> > > see imx_drm_screen_create()[ src/gallium/winsys/imx/drm/imx_drm_winsys.c]
> > >
> > >
> > > If the card node is used DRM_IOCTL_MODE_CREATE_DUMB works but
> > > DRM_IOCTL_PRIME_FD_TO_HANDLE fails, because the permissions are
> > > DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW
> > >
> > Right I missed the DRM_AUTH, in the fd <> handle IOCTLs.
> > So in order for things to work, we'd need to either:
> >  - allow dumb buffers for render nodes, or
> >  - drop the DRM_AUTH for fd <> handle imports
> >
> > Pointing an alternative solution, for kernel developers to analyse and
> > make a decision.
> >
> > >
> > > In android 8.1 the hardware composer runs in a seperate process and it has
> > > to use the card node and be drm master (to use the KMS API),
> > > therefore, when the surface flinger calls
> > > renderonly_create_kms_dumb_buffer_for_resource() it is not authenticated.
> > >
> > > Making surface flinger use a render node fixes the problem for
> > > DRM_IOCTL_PRIME_FD_TO_HANDLE (because that already has DRM_RENDER_ALLOW),
> > > but DRM_IOCTL_MODE_CREATE_DUMB now fails without the patch.
> > >
> > >
> > > This probably worked in previous versions of Android where surface flinger
> > > and hwc were all in the same process.
> > >
> > There has been varying hacks for Android through the years. Bringing
> > details into the discussion will result in a significant diversion.
> > Something we could avoid, for the time being ;-)
>
> Did someone say diversion?!? The way this was handled prior to using
> render/control nodes in drm_hwc/[drm/gbm]_gralloc is that all modesetting was
> done via gralloc which was master. The hwc implementation was basically a 
> proxy
> backchanneling all of the work to gralloc.
>
> Anyways, we probably don't want to go back there.
>
> Fwiw, I'd lean towards allowing DUMB allocation from the render nodes. I
> understand it limits use cases that are undesirable, but it is also limiting
> usecases that are desirable. So, given that people are going to get "creative"
> regardless of how many safety railings we put up, we shouldn't make things
> unnecessarily hard on other trying to Get Work Done.

The problem with using render nodes is what if there isn't one? We
require VGEM (and make VGEM allow dumb buffers) in that case?

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


[Bug 107493] Screen goes blank while loading drm driver

2018-08-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=107493

--- Comment #3 from Sebastian Luncan  ---
Created attachment 140985
  --> https://bugs.freedesktop.org/attachment.cgi?id=140985&action=edit
dmesg

The mainboard has two video ports, DVI and HDMI. I use the DVI port. I can test
the HDMI port too if that helps.

-- 
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 107432] Periodic complete system lockup with Vega M and Kernel 4.18-rc6+

2018-08-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=107432

--- Comment #8 from Robert Strube  ---
(In reply to Michel Dänzer from comment #6)
> Well, https://bugs.freedesktop.org/attachment.cgi?id=140903 definitely shows
> an amdgpu issue exacerbating the memory pressure situation — it tries to
> allocate 4M of physically contiguous memory. My patch fixes that. Can you
> confirm that the patch at least doesn't cause any additional issues of its
> own?

I've now moved to 4.18-rc8.  Would you like me to apply your patch to this
release and report back?

Thanks!
Rob

-- 
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 107493] Screen goes blank while loading drm driver

2018-08-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=107493

--- Comment #2 from Sebastian Luncan  ---
Created attachment 140984
  --> https://bugs.freedesktop.org/attachment.cgi?id=140984&action=edit
xorg log

-- 
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: [Freedreno] [v7 PATCH 0/5] Add support for Adreno a6xx

2018-08-06 Thread Rob Clark
On Mon, Aug 6, 2018 at 1:35 PM Jordan Crouse  wrote:
>
> This is an initial version of support for the Adreno a6xx GPU family starting
> with the a630 from the sdm845 SoC. This code is ahead of much of the sdm845
> code that would be needed to actually bring up a device and it is also in
> advance of any user side support for the a6xx GPU so this is mainly just a
> chance to look over the code structure and get a feel for the
> direction that the hardware is going in.

Note that, we have WIP freedreno support here:

  https://gitlab.freedesktop.org/krh/mesa/commits/wip/a6xx

I'm still working on some cleanup, but at this point glmark2 and CrOS
boots to UI (ie. chromium browser works).. so I think I'll be ready to
push initial round of mesa support this week.

BR,
-R

> The a6xx GPU is an iteration of a5xx so most of the GPU side code looks pretty
> identical except for the usual register differences. The big different is in
> power control. On the a5xx there was a rudimentary device called the GPMU that
> did some basic power stuff but left most of the complexity to the kernel.
>
> On the a6xx the power complexity is being moved to a component
> called the GMU (graphics management unit) which handles the power control of 
> the
> GPU and shuts it down quickly after it goes idle.
>
> This stack has one run time dependency that shifts the power responsibility
> for the SMMU to the SMMU driver instead of the current workaround of 
> implicitly
> powering the SMMU by powering the GPU:
>
> https://patchwork.kernel.org/patch/10301163/ - pm_runtime ops for arm-smmu
>
> [v7 - Make sure the GMU sets the GPU clock to something reasonable. Force the
> GPU/GMU on during state capture to avoid errors.  Fix checkpatch errors]
>
> [v6 - set nr_clocks to 0 when parsing fails and minor cleanup in msm_iommu for
> Vivek. Fix compile error in the load firmware patch ]
>
> [v5 - Move firmware loading to adreno_load_gpu() so it is easier to fail if 
> the
> firmware isn't found ]
>
> [v4 - Add clock parsing helper function and use it for GPU and GMU. Update
> recommended clock gating settings. Fix a bug in the CMD DB parser. Update
> register values from updated database ]
>
> [v3 - fix inverted register definition for GMU_SPTPRAC_CLK_STATUS; fix 
> incorrect
> register check in a5xx_gmu_gx_is_on(), use dev_pm_opp_get_of_node() from
> Rajendra and Viresh to read the qcom,level from the device tree; read 
> qcom,level
> from the DT to get the voltage level to pass to the GMU, fix issues
> identified by smatch]
>
> [v2 - addressed comments from Lucas Stach; added pm_runtime_get_supplier calls
> for accesses to the GMU IOMMU; moved to SPDX headers for new files]
>
> Jordan Crouse (4):
>   drm/msm: Remove pm_runtime operations from msm_iommu
>   drm/msm: Add a helper function to parse clock names
>   drm/msm/adreno: Load the firmware before bringing up the hardware
>   drm/msm: Add A6XX device support
>
> Sharat Masetty (1):
>   drm/msm: Add generated headers for A6XX
>
>  drivers/gpu/drm/msm/Makefile   |3 +
>  drivers/gpu/drm/msm/adreno/a6xx.xml.h  | 1784 
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.c  | 1207 +
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.h  |  162 ++
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h  |  382 +
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c  |  818 +
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.h  |   60 +
>  drivers/gpu/drm/msm/adreno/a6xx_hfi.c  |  435 +
>  drivers/gpu/drm/msm/adreno/a6xx_hfi.h  |  127 ++
>  drivers/gpu/drm/msm/adreno/adreno_device.c |   35 +-
>  drivers/gpu/drm/msm/adreno/adreno_gpu.c|2 +-
>  drivers/gpu/drm/msm/adreno/adreno_gpu.h|5 +-
>  drivers/gpu/drm/msm/msm_drv.c  |   57 +
>  drivers/gpu/drm/msm/msm_drv.h  |4 +
>  drivers/gpu/drm/msm/msm_gpu.c  |   62 +-
>  drivers/gpu/drm/msm/msm_gpu.h  |2 +-
>  drivers/gpu/drm/msm/msm_iommu.c|   13 +-
>  17 files changed, 5091 insertions(+), 67 deletions(-)
>  create mode 100644 drivers/gpu/drm/msm/adreno/a6xx.xml.h
>  create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gmu.c
>  create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gmu.h
>  create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
>  create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>  create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gpu.h
>  create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_hfi.c
>  create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_hfi.h
>
> --
> 2.18.0
>
> ___
> Freedreno mailing list
> freedr...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[v7 PATCH 0/5] Add support for Adreno a6xx

2018-08-06 Thread Jordan Crouse
This is an initial version of support for the Adreno a6xx GPU family starting
with the a630 from the sdm845 SoC. This code is ahead of much of the sdm845
code that would be needed to actually bring up a device and it is also in
advance of any user side support for the a6xx GPU so this is mainly just a
chance to look over the code structure and get a feel for the
direction that the hardware is going in.

The a6xx GPU is an iteration of a5xx so most of the GPU side code looks pretty
identical except for the usual register differences. The big different is in
power control. On the a5xx there was a rudimentary device called the GPMU that
did some basic power stuff but left most of the complexity to the kernel.

On the a6xx the power complexity is being moved to a component
called the GMU (graphics management unit) which handles the power control of the
GPU and shuts it down quickly after it goes idle.

This stack has one run time dependency that shifts the power responsibility
for the SMMU to the SMMU driver instead of the current workaround of implicitly
powering the SMMU by powering the GPU:

https://patchwork.kernel.org/patch/10301163/ - pm_runtime ops for arm-smmu

[v7 - Make sure the GMU sets the GPU clock to something reasonable. Force the
GPU/GMU on during state capture to avoid errors.  Fix checkpatch errors]

[v6 - set nr_clocks to 0 when parsing fails and minor cleanup in msm_iommu for
Vivek. Fix compile error in the load firmware patch ]

[v5 - Move firmware loading to adreno_load_gpu() so it is easier to fail if the
firmware isn't found ]

[v4 - Add clock parsing helper function and use it for GPU and GMU. Update
recommended clock gating settings. Fix a bug in the CMD DB parser. Update
register values from updated database ]

[v3 - fix inverted register definition for GMU_SPTPRAC_CLK_STATUS; fix incorrect
register check in a5xx_gmu_gx_is_on(), use dev_pm_opp_get_of_node() from
Rajendra and Viresh to read the qcom,level from the device tree; read qcom,level
from the DT to get the voltage level to pass to the GMU, fix issues
identified by smatch]

[v2 - addressed comments from Lucas Stach; added pm_runtime_get_supplier calls
for accesses to the GMU IOMMU; moved to SPDX headers for new files]

Jordan Crouse (4):
  drm/msm: Remove pm_runtime operations from msm_iommu
  drm/msm: Add a helper function to parse clock names
  drm/msm/adreno: Load the firmware before bringing up the hardware
  drm/msm: Add A6XX device support

Sharat Masetty (1):
  drm/msm: Add generated headers for A6XX

 drivers/gpu/drm/msm/Makefile   |3 +
 drivers/gpu/drm/msm/adreno/a6xx.xml.h  | 1784 
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c  | 1207 +
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h  |  162 ++
 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h  |  382 +
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c  |  818 +
 drivers/gpu/drm/msm/adreno/a6xx_gpu.h  |   60 +
 drivers/gpu/drm/msm/adreno/a6xx_hfi.c  |  435 +
 drivers/gpu/drm/msm/adreno/a6xx_hfi.h  |  127 ++
 drivers/gpu/drm/msm/adreno/adreno_device.c |   35 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.c|2 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.h|5 +-
 drivers/gpu/drm/msm/msm_drv.c  |   57 +
 drivers/gpu/drm/msm/msm_drv.h  |4 +
 drivers/gpu/drm/msm/msm_gpu.c  |   62 +-
 drivers/gpu/drm/msm/msm_gpu.h  |2 +-
 drivers/gpu/drm/msm/msm_iommu.c|   13 +-
 17 files changed, 5091 insertions(+), 67 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx.xml.h
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gmu.c
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gmu.h
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gpu.c
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gpu.h
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_hfi.c
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_hfi.h

-- 
2.18.0

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


[PATCH 3/5] drm/msm/adreno: Load the firmware before bringing up the hardware

2018-08-06 Thread Jordan Crouse
Failure to load firmware is the primary reason to fail adreno_load_gpu().
Try to load it first before going into the hardware initialization code and
unwinding it. This is important for a6xx because the GMU gets loaded from
the runtime power code and it is more costly to fail in that path because
of missing firmware.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 23 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.c|  2 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.h|  2 +-
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 44813624a286..37746f1d54cf 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -155,6 +155,7 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
struct msm_drm_private *priv = dev->dev_private;
struct platform_device *pdev = priv->gpu_pdev;
struct msm_gpu *gpu = NULL;
+   struct adreno_gpu *adreno_gpu;
int ret;
 
if (pdev)
@@ -165,7 +166,27 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
return NULL;
}
 
-   pm_runtime_get_sync(&pdev->dev);
+   adreno_gpu = to_adreno_gpu(gpu);
+
+   /*
+* The number one reason for HW init to fail is if the firmware isn't
+* loaded yet. Try that first and don't bother continuing on
+* otherwise
+*/
+
+   ret = adreno_load_fw(adreno_gpu);
+   if (ret)
+   return NULL;
+
+   /* Make sure pm runtime is active and reset any previous errors */
+   pm_runtime_set_active(&pdev->dev);
+
+   ret = pm_runtime_get_sync(&pdev->dev);
+   if (ret < 0) {
+   dev_err(dev->dev, "Couldn't power up the GPU: %d\n", ret);
+   return NULL;
+   }
+
mutex_lock(&dev->struct_mutex);
ret = msm_gpu_hw_init(gpu);
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 65c0ae7d8ad1..da1363a0c54d 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -149,7 +149,7 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char 
*fwname)
return fw;
 }
 
-static int adreno_load_fw(struct adreno_gpu *adreno_gpu)
+int adreno_load_fw(struct adreno_gpu *adreno_gpu)
 {
int i;
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 4406776597fd..d391ff377612 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -228,7 +228,7 @@ int adreno_gpu_init(struct drm_device *drm, struct 
platform_device *pdev,
struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs,
int nr_rings);
 void adreno_gpu_cleanup(struct adreno_gpu *gpu);
-
+int adreno_load_fw(struct adreno_gpu *adreno_gpu);
 
 void adreno_gpu_state_destroy(struct msm_gpu_state *state);
 
-- 
2.18.0

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


[PATCH 1/5] drm/msm: Remove pm_runtime operations from msm_iommu

2018-08-06 Thread Jordan Crouse
Now that the IOMMU is the master of it's own power we don't need to bring
up the GPU to do IOMMU operations. This is good because bringing up a6xx
requires the GMU so calling pm_runtime_get_sync() too early in the process
gets us into some nasty circular dependency situations.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/msm_iommu.c | 13 +
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index b23d33622f37..e80c79b3bb5c 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -38,13 +38,8 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char 
* const *names,
int cnt)
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
-   int ret;
 
-   pm_runtime_get_sync(mmu->dev);
-   ret = iommu_attach_device(iommu->domain, mmu->dev);
-   pm_runtime_put_sync(mmu->dev);
-
-   return ret;
+   return iommu_attach_device(iommu->domain, mmu->dev);
 }
 
 static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names,
@@ -52,9 +47,7 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const char 
* const *names,
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
 
-   pm_runtime_get_sync(mmu->dev);
iommu_detach_device(iommu->domain, mmu->dev);
-   pm_runtime_put_sync(mmu->dev);
 }
 
 static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
@@ -63,9 +56,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
struct msm_iommu *iommu = to_msm_iommu(mmu);
size_t ret;
 
-// pm_runtime_get_sync(mmu->dev);
ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
-// pm_runtime_put_sync(mmu->dev);
WARN_ON(ret < 0);
 
return (ret == len) ? 0 : -EINVAL;
@@ -76,9 +67,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova,
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
 
-   pm_runtime_get_sync(mmu->dev);
iommu_unmap(iommu->domain, iova, len);
-   pm_runtime_put_sync(mmu->dev);
 
return 0;
 }
-- 
2.18.0

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


[PATCH 4/5] drm/msm: Add generated headers for A6XX

2018-08-06 Thread Jordan Crouse
From: Sharat Masetty 

Add initial register headers for A6XX targets.

Signed-off-by: Sharat Masetty 
Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/adreno/a6xx.xml.h | 1784 +
 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h |  382 +
 2 files changed, 2166 insertions(+)
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx.xml.h
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h

diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h 
b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
new file mode 100644
index ..5af12fe3f95c
--- /dev/null
+++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h
@@ -0,0 +1,1784 @@
+#ifndef A6XX_XML
+#define A6XX_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git 
repository:
+http://github.com/freedreno/envytools/
+git clone https://github.com/freedreno/envytools.git
+
+The rules-ng-ng source files this header was generated from are:
+- ./adreno.xml   (501 bytes, from 2018-05-23 16:51:57)
+- ./freedreno_copyright.xml  (   1572 bytes, from 2016-10-24 21:12:27)
+- ./adreno/a2xx.xml  (  36805 bytes, from 2018-05-23 16:51:57)
+- ./adreno/adreno_common.xml (  13634 bytes, from 2018-05-23 16:51:57)
+- ./adreno/adreno_pm4.xml(  38703 bytes, from 2018-05-23 16:51:57)
+- ./adreno/a3xx.xml  (  83840 bytes, from 2017-12-05 18:20:27)
+- ./adreno/a4xx.xml  ( 112086 bytes, from 2018-05-23 16:51:57)
+- ./adreno/a5xx.xml  ( 146494 bytes, from 2018-05-23 16:51:57)
+- ./adreno/a6xx.xml  (  69957 bytes, from 2018-05-23 17:09:08)
+- ./adreno/a6xx_gmu.xml  (  10431 bytes, from 2018-05-23 16:52:19)
+- ./adreno/ocmem.xml (   1773 bytes, from 2016-10-24 21:12:27)
+
+Copyright (C) 2013-2018 by the following authors:
+- Rob Clark  (robclark)
+- Ilia Mirkin  (imirkin)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+
+enum a6xx_cp_perfcounter_select {
+   PERF_CP_ALWAYS_COUNT = 0,
+};
+
+enum a6xx_event_write {
+   PC_CCU_INVALIDATE_DEPTH = 24,
+   PC_CCU_INVALIDATE_COLOR = 25,
+};
+
+#define A6XX_RBBM_INT_0_MASK_RBBM_GPU_IDLE 0x0001
+#define A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR  0x0002
+#define A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW   0x0040
+#define A6XX_RBBM_INT_0_MASK_RBBM_GPC_ERROR0x0080
+#define A6XX_RBBM_INT_0_MASK_CP_SW 0x0100
+#define A6XX_RBBM_INT_0_MASK_CP_HW_ERROR   0x0200
+#define A6XX_RBBM_INT_0_MASK_CP_CCU_FLUSH_DEPTH_TS 0x0400
+#define A6XX_RBBM_INT_0_MASK_CP_CCU_FLUSH_COLOR_TS 0x0800
+#define A6XX_RBBM_INT_0_MASK_CP_CCU_RESOLVE_TS 0x1000
+#define A6XX_RBBM_INT_0_MASK_CP_IB20x2000
+#define A6XX_RBBM_INT_0_MASK_CP_IB10x4000
+#define A6XX_RBBM_INT_0_MASK_CP_RB 0x8000
+#define A6XX_RBBM_INT_0_MASK_CP_RB_DONE_TS 0x0002
+#define A6XX_RBBM_INT_0_MASK_CP_WT_DONE_TS 0x0004
+#define A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS 0x0010
+#define A6XX_RBBM_INT_0_MASK_RBBM_ATB_BUS_OVERFLOW 0x0040
+#define A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT  0x0080
+#define A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS   0x0100
+#define A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR0x0200
+#define A6XX_RBBM_INT_0_MASK_DEBBUS_INTR_0 0x0400
+#define A6XX_RBBM_INT_0_MASK_DEBBUS_INTR_1 0x0800
+#define A6XX_RBBM_INT_0_MASK_ISDB_CPU_IRQ  0x4000
+#define A6XX_RBBM_INT_0_MASK_ISDB_UNDER_DEBUG  0x8000
+#define A6XX_CP_INT_CP_OPCODE_ERROR0x0001
+#define A6XX_CP_INT_CP_UCODE_ERROR   

[PATCH 2/5] drm/msm: Add a helper function to parse clock names

2018-08-06 Thread Jordan Crouse
Add a helper function to parse the clock names and set up
the bulk data so we can take advantage of the bulk clock
functions instead of rolling our own. This is added
as a helper function so the upcoming a6xx GMU code can
also take advantage of it.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/msm_drv.c | 57 +
 drivers/gpu/drm/msm/msm_drv.h |  4 +++
 drivers/gpu/drm/msm/msm_gpu.c | 60 ++-
 drivers/gpu/drm/msm/msm_gpu.h |  2 +-
 4 files changed, 72 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 46876bc8b707..c1abad8a8612 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -81,6 +81,63 @@ module_param(modeset, bool, 0600);
  * Util/helpers:
  */
 
+int msm_clk_bulk_get(struct device *dev, struct clk_bulk_data **bulk)
+{
+   struct property *prop;
+   const char *name;
+   struct clk_bulk_data *local;
+   int i = 0, ret, count;
+
+   count = of_property_count_strings(dev->of_node, "clock-names");
+   if (count < 1)
+   return 0;
+
+   local = devm_kcalloc(dev, sizeof(struct clk_bulk_data *),
+   count, GFP_KERNEL);
+   if (!local)
+   return -ENOMEM;
+
+   of_property_for_each_string(dev->of_node, "clock-names", prop, name) {
+   local[i].id = devm_kstrdup(dev, name, GFP_KERNEL);
+   if (!local[i].id) {
+   devm_kfree(dev, local);
+   return -ENOMEM;
+   }
+
+   i++;
+   }
+
+   ret = devm_clk_bulk_get(dev, count, local);
+
+   if (ret) {
+   for (i = 0; i < count; i++)
+   devm_kfree(dev, (void *) local[i].id);
+   devm_kfree(dev, local);
+
+   return ret;
+   }
+
+   *bulk = local;
+   return count;
+}
+
+struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
+   const char *name)
+{
+   int i;
+   char n[32];
+
+   snprintf(n, sizeof(n), "%s_clk", name);
+
+   for (i = 0; bulk && i < count; i++) {
+   if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n))
+   return bulk[i].clk;
+   }
+
+
+   return NULL;
+}
+
 struct clk *msm_clk_get(struct platform_device *pdev, const char *name)
 {
struct clk *clk;
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index b611484866d6..8e510d5c758a 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -387,6 +387,10 @@ static inline void msm_perf_debugfs_cleanup(struct 
msm_drm_private *priv) {}
 #endif
 
 struct clk *msm_clk_get(struct platform_device *pdev, const char *name);
+int msm_clk_bulk_get(struct device *dev, struct clk_bulk_data **bulk);
+
+struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
+   const char *name);
 void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
const char *dbgname);
 void msm_writel(u32 data, void __iomem *addr);
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index f388944c93e2..ca368490b3ee 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -142,8 +142,6 @@ static int disable_pwrrail(struct msm_gpu *gpu)
 
 static int enable_clk(struct msm_gpu *gpu)
 {
-   int i;
-
if (gpu->core_clk && gpu->fast_rate)
clk_set_rate(gpu->core_clk, gpu->fast_rate);
 
@@ -151,28 +149,12 @@ static int enable_clk(struct msm_gpu *gpu)
if (gpu->rbbmtimer_clk)
clk_set_rate(gpu->rbbmtimer_clk, 1920);
 
-   for (i = gpu->nr_clocks - 1; i >= 0; i--)
-   if (gpu->grp_clks[i])
-   clk_prepare(gpu->grp_clks[i]);
-
-   for (i = gpu->nr_clocks - 1; i >= 0; i--)
-   if (gpu->grp_clks[i])
-   clk_enable(gpu->grp_clks[i]);
-
-   return 0;
+   return clk_bulk_prepare_enable(gpu->nr_clocks, gpu->grp_clks);
 }
 
 static int disable_clk(struct msm_gpu *gpu)
 {
-   int i;
-
-   for (i = gpu->nr_clocks - 1; i >= 0; i--)
-   if (gpu->grp_clks[i])
-   clk_disable(gpu->grp_clks[i]);
-
-   for (i = gpu->nr_clocks - 1; i >= 0; i--)
-   if (gpu->grp_clks[i])
-   clk_unprepare(gpu->grp_clks[i]);
+   clk_bulk_disable_unprepare(gpu->nr_clocks, gpu->grp_clks);
 
/*
 * Set the clock to a deliberately low rate. On older targets the clock
@@ -785,44 +767,22 @@ static irqreturn_t irq_handler(int irq, void *data)
return gpu->funcs->irq(gpu);
 }
 
-static struct clk *get_clock(struct device *dev, const char *name)
-{
-   struct clk *clk = devm_clk_get(dev, name);
-
-   return IS_ERR(clk) ? NULL : clk;
-}
-
 static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu)
 {
-

[PATCH 5/5] drm/msm: Add A6XX device support

2018-08-06 Thread Jordan Crouse
Add support for the A6XX family of Adreno GPUs. The biggest addition
is the GMU (Graphics Management Unit) which takes over most of the
power management of the GPU itself but in a ironic twist of fate
needs a goodly amount of management itself. Add support for the
A6XX core code, the GMU and the HFI (hardware firmware interface)
queue that the CPU uses to communicate with the GMU.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/Makefile   |3 +
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c  | 1207 
 drivers/gpu/drm/msm/adreno/a6xx_gmu.h  |  162 +++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c  |  818 +
 drivers/gpu/drm/msm/adreno/a6xx_gpu.h  |   60 +
 drivers/gpu/drm/msm/adreno/a6xx_hfi.c  |  435 +++
 drivers/gpu/drm/msm/adreno/a6xx_hfi.h  |  127 ++
 drivers/gpu/drm/msm/adreno/adreno_device.c |   12 +
 drivers/gpu/drm/msm/adreno/adreno_gpu.h|3 +
 drivers/gpu/drm/msm/msm_gpu.c  |2 +-
 10 files changed, 2828 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gmu.c
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gmu.h
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gpu.c
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gpu.h
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_hfi.c
 create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_hfi.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 7c773e003663..261fa79d456d 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -11,6 +11,9 @@ msm-y := \
adreno/a5xx_gpu.o \
adreno/a5xx_power.o \
adreno/a5xx_preempt.o \
+   adreno/a6xx_gpu.o \
+   adreno/a6xx_gmu.o \
+   adreno/a6xx_hfi.o \
hdmi/hdmi.o \
hdmi/hdmi_audio.o \
hdmi/hdmi_bridge.o \
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
new file mode 100644
index ..fbb501986720
--- /dev/null
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -0,0 +1,1207 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "a6xx_gpu.h"
+#include "a6xx_gmu.xml.h"
+
+static irqreturn_t a6xx_gmu_irq(int irq, void *data)
+{
+   struct a6xx_gmu *gmu = data;
+   u32 status;
+
+   status = gmu_read(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_STATUS);
+   gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, status);
+
+   if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_WDOG_BITE) {
+   dev_err_ratelimited(gmu->dev, "GMU watchdog expired\n");
+
+   /* Temporary until we can recover safely */
+   BUG();
+   }
+
+   if (status &  A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR)
+   dev_err_ratelimited(gmu->dev, "GMU AHB bus error\n");
+
+   if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_FENCE_ERR)
+   dev_err_ratelimited(gmu->dev, "GMU fence error: 0x%x\n",
+   gmu_read(gmu, REG_A6XX_GMU_AHB_FENCE_STATUS));
+
+   return IRQ_HANDLED;
+}
+
+static irqreturn_t a6xx_hfi_irq(int irq, void *data)
+{
+   struct a6xx_gmu *gmu = data;
+   u32 status;
+
+   status = gmu_read(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO);
+   gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, status);
+
+   if (status & A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ)
+   tasklet_schedule(&gmu->hfi_tasklet);
+
+   if (status & A6XX_GMU_GMU2HOST_INTR_INFO_CM3_FAULT) {
+   dev_err_ratelimited(gmu->dev, "GMU firmware fault\n");
+
+   /* Temporary until we can recover safely */
+   BUG();
+   }
+
+   return IRQ_HANDLED;
+}
+
+/* Check to see if the GX rail is still powered */
+static bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
+{
+   u32 val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);
+
+   return !(val &
+   (A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_GDSC_POWER_OFF |
+   A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
+}
+
+static int a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
+{
+   gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0);
+
+   gmu_write(gmu, REG_A6XX_GMU_DCVS_PERF_SETTING,
+   ((index << 24) & 0xff) | (3 & 0xf));
+
+   /*
+* Send an invalid index as a vote for the bus bandwidth and let the
+* firmware decide on the right vote
+*/
+   gmu_write(gmu, REG_A6XX_GMU_DCVS_BW_SETTING, 0xff);
+
+   /* Set and clear the OOB for DCVS to trigger the GMU */
+   a6xx_gmu_set_oob(gmu, GMU_OOB_DCVS_SET);
+   a6xx_gmu_clear_oob(gmu, GMU_OOB_DCVS_SET);
+
+   return gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN);
+}
+
+static bool a6xx_gmu_check_idle_level(struct a6xx_gmu *gmu)
+{
+   u32 val;
+   int local = gmu->idle_level;
+
+   /* SPTP and IFPC both report as IFPC */
+   if (gmu->i

Re: [PATCH 2/3] drm: rcar-du: Rename var to a more precise name

2018-08-06 Thread Laurent Pinchart
Hi Kieran,

On Monday, 6 August 2018 18:49:12 EEST Kieran Bingham wrote:
> On 30/07/18 18:20, Jacopo Mondi wrote:
> > Rename the 'value' variable, only used to for writing to DMSR register to
> > a more precise 'dmsr' name.
> > 
> > Signed-off-by: Laurent Pinchart
> > 
> > Signed-off-by: Jacopo Mondi 
> > ---
> > 
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 12 ++--
> >  1 file changed, 6 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 6d55cec..4d7907c 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > @@ -208,7 +208,7 @@ static void rcar_du_crtc_set_display_timing(struct
> > rcar_du_crtc *rcrtc)> 
> > const struct drm_display_mode *mode = &rcrtc->crtc.state-
>adjusted_mode;
> > struct rcar_du_device *rcdu = rcrtc->group->dev;
> > unsigned long mode_clock = mode->clock * 1000;
> > 
> > -   u32 value;
> > +   u32 dsmr;
> > 
> > u32 escr;
> > 
> > if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
> > 
> > @@ -299,11 +299,11 @@ static void rcar_du_crtc_set_display_timing(struct
> > rcar_du_crtc *rcrtc)> 
> > rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);
> > 
> > /* Signal polarities */
> > 
> > -   value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
> > - | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
> > - | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? DSMR_ODEV : 0)
> > - | DSMR_DIPM_DISP | DSMR_CSPM;
> > -   rcar_du_crtc_write(rcrtc, DSMR, value);
> > +   dsmr = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
> > +  | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
> > +  | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? DSMR_ODEV : 0)
> > +  | DSMR_DIPM_DISP | DSMR_CSPM;
> 
> Quite nit-picky I'm afraid, but here, you have increased the indent such
> that the '|' operator is now aligned with the first '(', rather than the
> '=' as used by the rest of the driver.
> 
> Was this intentional ?
> 
> I think it should be brought forwards to align under the '=' to match.

Agreed.

For the record, this change was part of patch 1/3 that I provided on its own 
to Jacopo, who then split it out. I'd be inclined to squash the two changes 
back together, I don't think this rename requires a patch of its own.

> > +   rcar_du_crtc_write(rcrtc, DSMR, dsmr);
> > 
> > /* Display timings */
> > rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start - 19);

-- 
Regards,

Laurent Pinchart



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


Re: [PATCH v3 10/10] drm/vmwgfx: Use __drm_atomic_helper_plane_reset instead of copying the logic

2018-08-06 Thread Sinclair Yeh
Acked-by: Sinclair Yeh 

On Sat, Aug 04, 2018 at 05:15:30PM +0100, Alexandru Gheorghe wrote:
> A new helper function(__drm_atomic_helper_plane_reset) has been added
> for linking a plane with its state and resetting the core
> properties(alpha, rotation, etc.) to their default values.
> Use that instead of duplicating the logic.
> 
> Reviewed-by: Sinclair Yeh 
> Reviewed-by: Deepak Rawat 
> Signed-off-by: Alexandru Gheorghe 
> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
> b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> index 4a0f0f41afa1..61824e360619 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> @@ -720,9 +720,7 @@ void vmw_du_plane_reset(struct drm_plane *plane)
>   return;
>   }
>  
> - plane->state = &vps->base;
> - plane->state->plane = plane;
> - plane->state->rotation = DRM_MODE_ROTATE_0;
> + __drm_atomic_helper_plane_reset(plane, &vps->base);
>  }
>  
>  
> -- 
> 2.18.0
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 107493] Screen goes blank while loading drm driver

2018-08-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=107493

--- Comment #1 from Alex Deucher  ---
Please attach your xorg log and dmesg output.  What display connectors are on
your system and which are you using?  Are you using DVI and HDMI at the same
time?

-- 
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 107498] Southern Islands pp_od_clk_voltage is empty

2018-08-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=107498

Alex Deucher  changed:

   What|Removed |Added

   Severity|normal  |enhancement

--- Comment #1 from Alex Deucher  ---
No support for SI chips planned.

-- 
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 106519] Is it normal that the 4K video on the Vega 56 GPU played with loud turbine noise, 200% load of the desktop Core i7 CPU and at the same time playable with jerks and dropping frames?

2018-08-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=106519

--- Comment #23 from mikhail.v.gavri...@gmail.com ---
Created attachment 140983
  --> https://bugs.freedesktop.org/attachment.cgi?id=140983&action=edit
Xorg.0.log

-- 
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 fix for 4.19] fbcon: Do not takeover the console from atomic context

2018-08-06 Thread Hans de Goede
Taking over the console involves allocating mem with GFP_KERNEL, talking
to drm drivers, etc. So this should not be done from an atomic context.

But the console-output trigger deferred console takeover may happen from an
atomic context, which leads to "BUG: sleeping function called from invalid
context" errors.

This commit fixes these errors by doing the deferred takeover from a
workqueue when the notifier runs from an atomic context.

Signed-off-by: Hans de Goede 
---
 drivers/video/fbdev/core/fbcon.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index ef8b2d0b7071..4e5997d53fc4 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -3592,7 +3592,20 @@ static int fbcon_init_device(void)
 }
 
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
+static void fbcon_register_existing_fbs(struct work_struct *work)
+{
+   int i;
+
+   console_lock();
+
+   for_each_registered_fb(i)
+   fbcon_fb_registered(registered_fb[i]);
+
+   console_unlock();
+}
+
 static struct notifier_block fbcon_output_nb;
+static DECLARE_WORK(fbcon_deferred_takeover_work, fbcon_register_existing_fbs);
 
 static int fbcon_output_notifier(struct notifier_block *nb,
 unsigned long action, void *data)
@@ -3607,8 +3620,12 @@ static int fbcon_output_notifier(struct notifier_block 
*nb,
deferred_takeover = false;
logo_shown = FBCON_LOGO_DONTSHOW;
 
-   for_each_registered_fb(i)
-   fbcon_fb_registered(registered_fb[i]);
+   if (in_atomic() || irqs_disabled()) {
+   schedule_work(&fbcon_deferred_takeover_work);
+   } else {
+   for_each_registered_fb(i)
+   fbcon_fb_registered(registered_fb[i]);
+   }
 
return NOTIFY_OK;
 }
-- 
2.18.0

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


Re: [PATCH v3 00/10] Add helper for plane reset

2018-08-06 Thread Daniel Vetter
On Mon, Aug 06, 2018 at 03:28:06PM +0300, Laurent Pinchart wrote:
> Hi Alex,
> 
> On Monday, 6 August 2018 15:20:38 EEST Alexandru-Cosmin Gheorghe wrote:
> > On Mon, Aug 06, 2018 at 02:45:42PM +0300, Laurent Pinchart wrote:
> > > On Monday, 6 August 2018 14:07:27 EEST Alexandru-Cosmin Gheorghe wrote:
> > >> On Sat, Aug 04, 2018 at 05:15:20PM +0100, Alexandru Gheorghe wrote:
> > >>> No significant change since v2, fixed a spelling mistake and
> > >>> added/removed some newlines in 01 and 07 patches.
> > >>> 
> > >>> I plan to apply the first patch of the series and the patches for
> > >>> the drivers maintained through drm-misc(that go Reviewed/Ack) in
> > >>> drm-misc-next on Monday.
> > >>> 
> > >>> For the other drivers please let me know if you want me to push them
> > >>> in drm-misc-next as well.
> > >> 
> > >> Pushed the following patch to drm-misc-next:
> > >> 
> > >> drm/atomic: Add __drm_atomic_helper_plane_reset
> > >> drm: mali-dp: Use __drm_atomic_helper_plane_reset instead of copying the
> > >> logic
> > >> drm: atmel-hlcdc: Use __drm_atomic_helper_plane_reset instead of copying
> > >> the logic
> > >> drm/imx: Use __drm_atomic_helper_plane_reset instead of copying the
> > >> logic
> > >> drm/sun4i: Use __drm_atomic_helper_plane_reset instead of copying the
> > >> logic
> > > 
> > > I've acked the rcar-du part, could it be merged with the rest of the code
> > > ?
> > 
> > Done, it's in drm-misc-next now. I didn't know how to handle this for
> > drivers that have their own tree, so I just pushed the patches where I was
> > explicitly asked.
> 
> No worries. It's actually better to ask than pushing changes directly, as 
> maintainers could have conflicting patches queued up. I should have made this 
> clear in my review, thank you for handling it.

Poke them a few times, if no response then just get someone to review the
remaining ones and push them all into drm-misc-next. This is needed all
the time because many drivers aren't group maintained and the single
maintainer swamped/absent. Worst case there's a conflict or a
double-merge, which isn't really all that bad.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/3] drm: rcar-du: Rename var to a more precise name

2018-08-06 Thread Kieran Bingham
Hi Jacopo,

Thankyou for the patch,

On 30/07/18 18:20, Jacopo Mondi wrote:
> Rename the 'value' variable, only used to for writing to DMSR register to a
> more precise 'dmsr' name.
> 
> Signed-off-by: Laurent Pinchart 
> Signed-off-by: Jacopo Mondi 
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 6d55cec..4d7907c 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -208,7 +208,7 @@ static void rcar_du_crtc_set_display_timing(struct 
> rcar_du_crtc *rcrtc)
>   const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
>   struct rcar_du_device *rcdu = rcrtc->group->dev;
>   unsigned long mode_clock = mode->clock * 1000;
> - u32 value;
> + u32 dsmr;
>   u32 escr;
>  
>   if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
> @@ -299,11 +299,11 @@ static void rcar_du_crtc_set_display_timing(struct 
> rcar_du_crtc *rcrtc)
>   rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);
>  
>   /* Signal polarities */
> - value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
> -   | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
> -   | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? DSMR_ODEV : 0)
> -   | DSMR_DIPM_DISP | DSMR_CSPM;
> - rcar_du_crtc_write(rcrtc, DSMR, value);
> + dsmr = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
> +| ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
> +| ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? DSMR_ODEV : 0)
> +| DSMR_DIPM_DISP | DSMR_CSPM;

Quite nit-picky I'm afraid, but here, you have increased the indent such
that the '|' operator is now aligned with the first '(', rather than the
'=' as used by the rest of the driver.

Was this intentional ?

I think it should be brought forwards to align under the '=' to match.


> + rcar_du_crtc_write(rcrtc, DSMR, dsmr);
>  
>   /* Display timings */
>   rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start - 19);
> 

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


[PATCH 1/4] MAINTAINERS: rcar-du: Add co-maintainer

2018-08-06 Thread Kieran Bingham
From: Kieran Bingham 

Add myself as a co-maintainer for the Renesas DRM drivers.

Signed-off-by: Kieran Bingham 
---
Cc: Laurent Pinchart 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-renesas-...@vger.kernel.org

 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7cebd5bba8a8..c7cecb9201b3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4764,6 +4764,7 @@ F:
Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
 
 DRM DRIVERS FOR RENESAS
 M: Laurent Pinchart 
+M: Kieran Bingham 
 L: dri-devel@lists.freedesktop.org
 L: linux-renesas-...@vger.kernel.org
 T: git git://linuxtv.org/pinchartl/fbdev
-- 
2.17.1

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


Re: [PATCH] drm/scheduler: Remove entity->rq NULL check

2018-08-06 Thread Nayan Deshmukh
I forgot about this since we started discussing possible scenarios of
processes and threads.

In any case, this check is redundant. Acked-by: Nayan Deshmukh <
nayan26deshm...@gmail.com>

Nayan

On Mon, Aug 6, 2018 at 7:43 PM Christian König <
ckoenig.leichtzumer...@gmail.com> wrote:

> Ping. Any objections to that?
>
> Christian.
>
> Am 03.08.2018 um 13:08 schrieb Christian König:
> > That is superflous now.
> >
> > Signed-off-by: Christian König 
> > ---
> >   drivers/gpu/drm/scheduler/gpu_scheduler.c | 5 -
> >   1 file changed, 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c
> b/drivers/gpu/drm/scheduler/gpu_scheduler.c
> > index 85908c7f913e..65078dd3c82c 100644
> > --- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
> > +++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
> > @@ -590,11 +590,6 @@ void drm_sched_entity_push_job(struct drm_sched_job
> *sched_job,
> >   if (first) {
> >   /* Add the entity to the run queue */
> >   spin_lock(&entity->rq_lock);
> > - if (!entity->rq) {
> > - DRM_ERROR("Trying to push to a killed entity\n");
> > - spin_unlock(&entity->rq_lock);
> > - return;
> > - }
> >   drm_sched_rq_add_entity(entity->rq, entity);
> >   spin_unlock(&entity->rq_lock);
> >   drm_sched_wakeup(entity->rq->sched);
>
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/scheduler: Remove entity->rq NULL check

2018-08-06 Thread Christian König

Ping. Any objections to that?

Christian.

Am 03.08.2018 um 13:08 schrieb Christian König:

That is superflous now.

Signed-off-by: Christian König 
---
  drivers/gpu/drm/scheduler/gpu_scheduler.c | 5 -
  1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c 
b/drivers/gpu/drm/scheduler/gpu_scheduler.c
index 85908c7f913e..65078dd3c82c 100644
--- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
@@ -590,11 +590,6 @@ void drm_sched_entity_push_job(struct drm_sched_job 
*sched_job,
if (first) {
/* Add the entity to the run queue */
spin_lock(&entity->rq_lock);
-   if (!entity->rq) {
-   DRM_ERROR("Trying to push to a killed entity\n");
-   spin_unlock(&entity->rq_lock);
-   return;
-   }
drm_sched_rq_add_entity(entity->rq, entity);
spin_unlock(&entity->rq_lock);
drm_sched_wakeup(entity->rq->sched);


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


Re: [PATCH 2/2] drm/scheduler: add last_scheduled dependency handling

2018-08-06 Thread Christian König

Am 06.08.2018 um 15:23 schrieb Nayan Deshmukh:

Hi Christian,

Good patch. But it might lead to bad performance when we reschedule 
when the hardware queue of the engine on which the last job was pushed 
is not full.


On Mon, Aug 6, 2018 at 5:49 PM Christian König 
> wrote:


This fixes accessing the last_scheduled fence from multiple threads as
well as makes it easier to move entities between schedulers.

Signed-off-by: Christian König mailto:christian.koe...@amd.com>>
---
 drivers/gpu/drm/scheduler/gpu_scheduler.c | 34
+--
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c
b/drivers/gpu/drm/scheduler/gpu_scheduler.c
index 029863726c99..e4b71a543481 100644
--- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
@@ -523,6 +523,29 @@ static bool
drm_sched_entity_add_dependency_cb(struct drm_sched_entity *entity)
        return false;
 }

+static bool drm_sched_entity_last_scheduled_dep(struct
drm_sched_entity *entity)
+{
+       struct drm_sched_fence *s_fence;
+
+       if (!entity->last_scheduled)
+               return false;
+
+       /*
+        * Check if the last submission was handled by a different
scheduler
+        */
+       s_fence = to_drm_sched_fence(entity->last_scheduled);
+       if (s_fence && s_fence->sched != entity->rq->sched) {
+               entity->dependency =
dma_fence_get(entity->last_scheduled);
+               if (!dma_fence_add_callback(entity->dependency,
&entity->cb,
+  drm_sched_entity_wakeup))
+                       return true;
+
+               dma_fence_put(entity->dependency);
+               entity->dependency = NULL;
+       }
+       return false;
+}
+
 static struct drm_sched_job *
 drm_sched_entity_pop_job(struct drm_sched_entity *entity)
 {
@@ -537,6 +560,9 @@ drm_sched_entity_pop_job(struct
drm_sched_entity *entity)
                if (drm_sched_entity_add_dependency_cb(entity))
                        return NULL;

+       if (drm_sched_entity_last_scheduled_dep(entity))
+               return NULL;
+
        /* skip jobs from entity that marked guilty */
        if (entity->guilty && atomic_read(entity->guilty))
dma_fence_set_error(&sched_job->s_fence->finished, -ECANCELED);
@@ -564,14 +590,10 @@ void drm_sched_entity_push_job(struct
drm_sched_job *sched_job,
                               struct drm_sched_entity *entity)
 {
        struct drm_sched_rq *rq = entity->rq;
-       bool first, reschedule, idle;
+       bool first;

-       idle = entity->last_scheduled == NULL ||
-  dma_fence_is_signaled(entity->last_scheduled);
        first = spsc_queue_count(&entity->job_queue) == 0;
-       reschedule = idle && first && (entity->num_rq_list > 1);
-
-       if (reschedule) {
+       if (first && (entity->num_rq_list > 1)) {

Something like this might be better:

if (first  && (entity->num_rq_list > 1) &&
    (hw_rq_count == hw_submission_limit))

                rq = drm_sched_entity_get_free_sched(entity);
                spin_lock(&entity->rq_lock);
                drm_sched_rq_remove_entity(entity->rq, entity);
-- 
2.14.1




Hey, good idea. Going to take that into account.

Christian.


Regards,
Nayan


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


[Bug 107498] Southern Islands pp_od_clk_voltage is empty

2018-08-06 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=107498

Bug ID: 107498
   Summary: Southern Islands pp_od_clk_voltage is empty
   Product: DRI
   Version: unspecified
  Hardware: x86-64 (AMD64)
OS: Linux (All)
Status: NEW
  Severity: normal
  Priority: medium
 Component: DRM/AMDgpu
  Assignee: dri-devel@lists.freedesktop.org
  Reporter: n-...@live.com

I have a gcn 1.0 firepro 4000m (7700m) card that I would like to have overdrive
capabilities.

The issue is with amdgpu.ppfeaturemask=0x,
/sys/class/drm/card0/device/pp_od_clk_voltage is empty and does not accept
commands.

-- 
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] etnaviv-next for 4.19

2018-08-06 Thread Lucas Stach
Hi Dave,

not much to de-stage this time. Changes from Philipp and Souptick to
use memset32 more and switch the fault handler to the new vm_fault_t
and two small fixes for issues that can be hit in rare corner cases
from me.

Regards,
Lucas

The following changes since commit 9d3cce1e8b8561fed5f383d22a4d6949db4eadbe:

  Linux 4.18-rc5 (2018-07-15 12:49:31 -0700)

are available in the Git repository at:

  https://git.pengutronix.de/git/lst/linux etnaviv/next

for you to fetch changes up to 5b147465532365dc4e2fee8499d6ca1f52dd0d16:

  drm/etnaviv: fix crash in GPU suspend when init failed due to buffer 
placement (2018-08-06 15:24:33 +0200)


Lucas Stach (2):
  drm/etnaviv: protect sched job submission with fence mutex
  drm/etnaviv: fix crash in GPU suspend when init failed due to buffer 
placement

Philipp Zabel (1):
  drm/etnaviv: mmuv2: use memset32 to init scratch page

Souptick Joarder (1):
  drm/etnaviv: change return type to vm_fault_t

 drivers/gpu/drm/etnaviv/etnaviv_drv.h|  3 ++-
 drivers/gpu/drm/etnaviv/etnaviv_gem.c| 37 
+
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c |  4 ++--
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c|  3 ++-
 drivers/gpu/drm/etnaviv/etnaviv_gpu.h|  2 +-
 drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c   |  9 -
 drivers/gpu/drm/etnaviv/etnaviv_sched.c  | 24 +---
 7 files changed, 37 insertions(+), 45 deletions(-)
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/2] drm/scheduler: add last_scheduled dependency handling

2018-08-06 Thread Nayan Deshmukh
Hi Christian,

Good patch. But it might lead to bad performance when we reschedule when
the hardware queue of the engine on which the last job was pushed is not
full.

On Mon, Aug 6, 2018 at 5:49 PM Christian König <
ckoenig.leichtzumer...@gmail.com> wrote:

> This fixes accessing the last_scheduled fence from multiple threads as
> well as makes it easier to move entities between schedulers.
>
> Signed-off-by: Christian König 
> ---
>  drivers/gpu/drm/scheduler/gpu_scheduler.c | 34
> +--
>  1 file changed, 28 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c
> b/drivers/gpu/drm/scheduler/gpu_scheduler.c
> index 029863726c99..e4b71a543481 100644
> --- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
> +++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
> @@ -523,6 +523,29 @@ static bool drm_sched_entity_add_dependency_cb(struct
> drm_sched_entity *entity)
> return false;
>  }
>
> +static bool drm_sched_entity_last_scheduled_dep(struct drm_sched_entity
> *entity)
> +{
> +   struct drm_sched_fence *s_fence;
> +
> +   if (!entity->last_scheduled)
> +   return false;
> +
> +   /*
> +* Check if the last submission was handled by a different
> scheduler
> +*/
> +   s_fence = to_drm_sched_fence(entity->last_scheduled);
> +   if (s_fence && s_fence->sched != entity->rq->sched) {
> +   entity->dependency = dma_fence_get(entity->last_scheduled);
> +   if (!dma_fence_add_callback(entity->dependency,
> &entity->cb,
> +   drm_sched_entity_wakeup))
> +   return true;
> +
> +   dma_fence_put(entity->dependency);
> +   entity->dependency = NULL;
> +   }
> +   return false;
> +}
> +
>  static struct drm_sched_job *
>  drm_sched_entity_pop_job(struct drm_sched_entity *entity)
>  {
> @@ -537,6 +560,9 @@ drm_sched_entity_pop_job(struct drm_sched_entity
> *entity)
> if (drm_sched_entity_add_dependency_cb(entity))
> return NULL;
>
> +   if (drm_sched_entity_last_scheduled_dep(entity))
> +   return NULL;
> +
> /* skip jobs from entity that marked guilty */
> if (entity->guilty && atomic_read(entity->guilty))
> dma_fence_set_error(&sched_job->s_fence->finished,
> -ECANCELED);
> @@ -564,14 +590,10 @@ void drm_sched_entity_push_job(struct drm_sched_job
> *sched_job,
>struct drm_sched_entity *entity)
>  {
> struct drm_sched_rq *rq = entity->rq;
> -   bool first, reschedule, idle;
> +   bool first;
>
> -   idle = entity->last_scheduled == NULL ||
> -   dma_fence_is_signaled(entity->last_scheduled);
> first = spsc_queue_count(&entity->job_queue) == 0;
> -   reschedule = idle && first && (entity->num_rq_list > 1);
> -
> -   if (reschedule) {
> +   if (first && (entity->num_rq_list > 1)) {
>
Something like this might be better:

if (first  && (entity->num_rq_list > 1) &&
(hw_rq_count == hw_submission_limit))

> rq = drm_sched_entity_get_free_sched(entity);
> spin_lock(&entity->rq_lock);
> drm_sched_rq_remove_entity(entity->rq, entity);
> --
> 2.14.1
>
> Regards,
Nayan
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] drm/scheduler: bind job earlier to scheduler

2018-08-06 Thread Nayan Deshmukh
On Mon, Aug 6, 2018 at 6:45 PM Christian König <
ckoenig.leichtzumer...@gmail.com> wrote:

> Am 06.08.2018 um 15:11 schrieb Nayan Deshmukh:
>
> Hi Christian,
>
> On Mon, Aug 6, 2018 at 5:49 PM Christian König <
> ckoenig.leichtzumer...@gmail.com> wrote:
>
>> Update job earlier with the scheduler it is supposed to be scheduled on.
>>
>> Otherwise we could incorrectly optimize dependencies when moving an
>> entity from one scheduler to another.
>>
> I don't think change is really required, the old code should work fine.
> Read below for more comments.
>
>
>>
>> Signed-off-by: Christian König 
>> ---
>>  drivers/gpu/drm/scheduler/gpu_scheduler.c | 4 ++--
>>  drivers/gpu/drm/scheduler/sched_fence.c   | 2 +-
>>  2 files changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c
>> b/drivers/gpu/drm/scheduler/gpu_scheduler.c
>> index 65078dd3c82c..029863726c99 100644
>> --- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
>> +++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
>> @@ -533,8 +533,6 @@ drm_sched_entity_pop_job(struct drm_sched_entity
>> *entity)
>> if (!sched_job)
>> return NULL;
>>
>> -   sched_job->sched = sched;
>> -   sched_job->s_fence->sched = sched;
>> while ((entity->dependency = sched->ops->dependency(sched_job,
>> entity)))
>>
> The job should have the correct scheduler before the
> sched->oops->dependency() function is called for the first time. Hence I
> placed the assignment here.
>
> It might also be that I am missing some case so please let me know if such
> a case exists where this might lead to wrong optimization.
>
>
> The problem is that the scheduler fence of job A could be the dependency
> of another job B
>
> Job B then makes an incorrect optimization because it sees the wrong
> scheduler in the scheduler fence of job A.
>
> Ah..I missed this case.  This make sense now. Reviewed-by: Nayan Deshmukh <
nayan26deshm...@gmail.com>

> Regards,
> Christian.
>
>
> Regards,
> Nayan
>
>> if (drm_sched_entity_add_dependency_cb(entity))
>> return NULL;
>> @@ -581,6 +579,8 @@ void drm_sched_entity_push_job(struct drm_sched_job
>> *sched_job,
>> spin_unlock(&entity->rq_lock);
>> }
>>
>> +   sched_job->sched = entity->rq->sched;
>> +   sched_job->s_fence->sched = entity->rq->sched;
>> trace_drm_sched_job(sched_job, entity);
>> atomic_inc(&entity->rq->sched->num_jobs);
>> WRITE_ONCE(entity->last_user, current->group_leader);
>> diff --git a/drivers/gpu/drm/scheduler/sched_fence.c
>> b/drivers/gpu/drm/scheduler/sched_fence.c
>> index 4029312fdd81..6dab18d288d7 100644
>> --- a/drivers/gpu/drm/scheduler/sched_fence.c
>> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
>> @@ -172,7 +172,7 @@ struct drm_sched_fence *drm_sched_fence_create(struct
>> drm_sched_entity *entity,
>> return NULL;
>>
>> fence->owner = owner;
>> -   fence->sched = entity->rq->sched;
>> +   fence->sched = NULL;
>> spin_lock_init(&fence->lock);
>>
>> seq = atomic_inc_return(&entity->fence_seq);
>> --
>> 2.14.1
>>
>>
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2] drm/scheduler: fix timeout worker setup for out of order job completions

2018-08-06 Thread Lucas Stach
Am Montag, den 06.08.2018, 10:12 +0200 schrieb Christian König:
> Am 03.08.2018 um 19:31 schrieb Lucas Stach:
> > Am Montag, den 06.08.2018, 14:57 +0200 schrieb Christian König:
> > > Am 03.08.2018 um 16:29 schrieb Lucas Stach:
> > > > drm_sched_job_finish() is a work item scheduled for each finished job on
> > > > a unbound system workqueue. This means the workers can execute out of 
> > > > order
> > > > with regard to the real hardware job completions.
> > > > 
> > > > If this happens queueing a timeout worker for the first job on the ring
> > > > mirror list is wrong, as this may be a job which has already finished
> > > > executing. Fix this by reorganizing the code to always queue the worker
> > > > for the next job on the list, if this job hasn't finished yet. This is
> > > > robust against a potential reordering of the finish workers.
> > > > 
> > > > Also move out the timeout worker cancelling, so that we don't need to
> > > > take the job list lock twice. As a small optimization list_del is used
> > > > to remove the job from the ring mirror list, as there is no need to
> > > > reinit the list head in the job we are about to free.
> > > > 
> > > > > > Signed-off-by: Lucas Stach 
> > > > 
> > > > ---
> > > > v2: - properly handle last job in the ring
> > > >   - check correct fence for compeletion
> > > > ---
> > > >    drivers/gpu/drm/scheduler/gpu_scheduler.c | 22 ++
> > > >    1 file changed, 10 insertions(+), 12 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c 
> > > > b/drivers/gpu/drm/scheduler/gpu_scheduler.c
> > > > index 44d480768dfe..574875e2c206 100644
> > > > --- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
> > > > +++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
> > > > @@ -452,24 +452,22 @@ static void drm_sched_job_finish(struct 
> > > > work_struct *work)
> > > > > > > > > > > >        
> > > > > > > > > > > > finish_work);
> > > > > >     struct drm_gpu_scheduler *sched = s_job->sched;
> > > > 
> > > >    
> > > > > > > > > > > > -   /* remove job from ring_mirror_list */
> > > > > > > > > > > > -   spin_lock(&sched->job_list_lock);
> > > > > > > > > > > > -   list_del_init(&s_job->node);
> > > > > > > > > > > > -   if (sched->timeout != MAX_SCHEDULE_TIMEOUT) {
> > > > > > -   struct drm_sched_job *next;
> > > > 
> > > > -
> > > > > > > > > > > > -   spin_unlock(&sched->job_list_lock);
> > > > > > +   if (sched->timeout != MAX_SCHEDULE_TIMEOUT)
> > > > 
> > > >     cancel_delayed_work_sync(&s_job->work_tdr);
> > > 
> > > That is unfortunately still racy here.
> > > 
> > > Between canceling the job and removing it from the list someone could
> > > actually start the time (in theory) :)
> > > 
> > > Cancel it, remove it from the list and cancel it again.
> > 
> > I don't see how. If we end up in this worker the finished fence of the
> > job is already certainly signaled (as this is what triggers queueing of
> > the worker). So even if some other worker manages to find this job as
> > the next job in the list, the dma_fence_is_signaled check should
> > prevent the timeout worker from getting scheduled again.
> 
> Well that makes sense, but is a bit hard to understand.

I agree, all the possible parallelism and possible re-ordering makes
this seemingly simple part of the scheduler code a bit mind-breaking.
I've added a comment in v3 to capture the line of thought for future
reference.

Regards,
Lucas

> Anyway, please remove the extra "if" check. With that done the patch is 
> > Reviewed-by: Christian König .
> 
> Thanks,
> Christian.
> 
> 
> > 
> > > BTW: You could completely drop the "if (sched->timeout !=
> > > MAX_SCHEDULE_TIMEOUT)" here cause canceling is harmless as long as the
> > > structure is initialized.
> > 
> > Right.
> > 
> > Regards,
> > Lucas
> > 
> > > Christian.
> > > 
> > > > > > -   spin_lock(&sched->job_list_lock);
> > > > 
> > > >    
> > > > > > > > > > > > -   /* queue TDR for next job */
> > > > > > > > > > > > -   next = 
> > > > > > > > > > > > list_first_entry_or_null(&sched->ring_mirror_list,
> > > > > > > > > > > > -   struct 
> > > > > > > > > > > > drm_sched_job, node);
> > > > > > > > > > > > +   spin_lock(&sched->job_list_lock);
> > > > > > > > > > > > +   /* queue TDR for next job */
> > > > > > > > > > > > +   if (sched->timeout != MAX_SCHEDULE_TIMEOUT &&
> > > > > > > > > > > > +   !list_is_last(&s_job->node, 
> > > > > > > > > > > > &sched->ring_mirror_list)) {
> > > > > > +   struct drm_sched_job *next = list_next_entry(s_job, 
> > > > > > node);
> > > > 
> > > >    
> > > > > > > > > > > > -   if (next)
> > > > > > > > > > > > +   if 
> > > > > > > > > > > > (!dma_fence_is_signaled(&next->s_fence->finished))
> > > > > > > > > > > >     
> > > > > > > > 

  1   2   3   >