Re: [PATCH v3 2/4] drm: bridge: dw_hdmi: Enable GCP only for Deep Color

2022-04-15 Thread Neil Armstrong

On 15/04/2022 04:42, sandor...@nxp.com wrote:

From: Sandor Yu 

HDMI1.4b specification section 6.5.3:
Source shall only send GCPs with non-zero CD to sinks
that indicate support for Deep Color.

DW HDMI GCP default enabled, but only transmit CD
and do not handle AVMUTE, PP norDefault_Phase (yet).
Disable Auto GCP when 24-bit color for sinks that not support Deep Color.

Signed-off-by: Sandor Yu 
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 +
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.h |  3 +++
  2 files changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 02d8f7e08814..312500921754 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1108,6 +1108,8 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
u8 val, vp_conf;
+   u8 clear_gcp_auto = 0;
+
  
  	if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) ||

hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format) ||
@@ -1117,6 +1119,7 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
case 8:
color_depth = 4;
output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
+   clear_gcp_auto = 1;
break;
case 10:
color_depth = 5;
@@ -1136,6 +1139,7 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
case 0:
case 8:
remap_size = HDMI_VP_REMAP_YCC422_16bit;
+   clear_gcp_auto = 1;
break;
case 10:
remap_size = HDMI_VP_REMAP_YCC422_20bit;
@@ -1160,6 +1164,19 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
hdmi_writeb(hdmi, val, HDMI_VP_PR_CD);
  
+	/* HDMI1.4b specification section 6.5.3:

+* Source shall only send GCPs with non-zero CD to sinks
+* that indicate support for Deep Color.
+* GCP only transmit CD and do not handle AVMUTE, PP norDefault_Phase 
(yet).
+* Disable Auto GCP when 24-bit color for sinks that not support Deep 
Color.
+*/
+   val = hdmi_readb(hdmi, HDMI_FC_DATAUTO3);
+   if (clear_gcp_auto == 1)
+   val &= ~HDMI_FC_DATAUTO3_GCP_AUTO;
+   else
+   val |= HDMI_FC_DATAUTO3_GCP_AUTO;
+   hdmi_writeb(hdmi, val, HDMI_FC_DATAUTO3);
+
hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE,
  HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF);
  
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h

index 1999db05bc3b..18df3e119553 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -850,6 +850,9 @@ enum {
HDMI_FC_DATAUTO0_VSD_MASK = 0x08,
HDMI_FC_DATAUTO0_VSD_OFFSET = 3,
  
+/* FC_DATAUTO3 field values */

+   HDMI_FC_DATAUTO3_GCP_AUTO = 0x04,
+
  /* PHY_CONF0 field values */
HDMI_PHY_CONF0_PDZ_MASK = 0x80,
HDMI_PHY_CONF0_PDZ_OFFSET = 7,


Reviewed-by: Neil Armstrong 


Re: [PATCH 9/9] vfio: Remove calls to vfio_group_add_container_user()

2022-04-15 Thread Matthew Rosato

On 4/12/22 11:53 AM, Jason Gunthorpe wrote:

When the open_device() op is called the container_users is incremented and
held incremented until close_device(). Thus, so long as drivers call
functions within their open_device()/close_device() region they do not
need to worry about the container_users.

These functions can all only be called between
open_device()/close_device():

   vfio_pin_pages()
   vfio_unpin_pages()
   vfio_dma_rw()
   vfio_register_notifier()
   vfio_unregister_notifier()

So eliminate the calls to vfio_group_add_container_user() and add a simple
WARN_ON to detect mis-use by drivers.



vfio_device_fops_release decrements dev->open_count immediately before 
calling dev->ops->close_device, which means we could enter close_device 
with a dev_count of 0.


Maybe vfio_device_fops_release should handle the same way as 
vfio_group_get_device_fd?


if (device->open_count == 1 && device->ops->close_device)
device->ops->close_device(device);
device->open_count--;



Re: [PATCH v2 1/2] dt-bindings: display: bridge: Document RZ/G2L MIPI DSI TX bindings

2022-04-15 Thread Laurent Pinchart
Hi Biju,

Thank you for the patch.

On Mon, Mar 28, 2022 at 07:49:30AM +0100, Biju Das wrote:
> The RZ/G2L MIPI DSI TX is embedded in the Renesas RZ/G2L family SoC's. It
> can operate in DSI mode, with up to four data lanes.
> 
> Signed-off-by: Biju Das 
> ---
> v1->v2:
>  * Added full path for dsi-controller.yaml
>  * Modeled DSI + D-PHY as single block and updated reg property
>  * Fixed typo D_PHY->D-PHY
>  * Updated description
>  * Added interrupts and interrupt-names and updated the example 
> RFC->v1:
>  * Added a ref to dsi-controller.yaml.
> RFC:-
>  * 
> https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-22-biju.das...@bp.renesas.com/
> ---
>  .../bindings/display/bridge/renesas,dsi.yaml  | 175 ++
>  1 file changed, 175 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml 
> b/Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml
> new file mode 100644
> index ..eebbf617c484
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml
> @@ -0,0 +1,175 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/bridge/renesas,dsi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Renesas RZ/G2L MIPI DSI Encoder
> +
> +maintainers:
> +  - Biju Das 
> +
> +description: |
> +  This binding describes the MIPI DSI encoder embedded in the Renesas
> +  RZ/G2L alike family of SoC's. The encoder can operate in DSI mode, with
> +  up to four data lanes.
> +
> +allOf:
> +  - $ref: /schemas/display/dsi-controller.yaml#
> +
> +properties:
> +  compatible:
> +enum:
> +  - renesas,rzg2l-mipi-dsi # RZ/G2L and RZ/V2L
> +
> +  reg:
> +maxItems: 1
> +
> +  interrupts:
> +items:
> +  - description: Sequence operation channel 0 interrupt
> +  - description: Sequence operation channel 1 interrupt
> +  - description: Video-Input operation channel 1 interrupt
> +  - description: DSI Packet Receive interrupt
> +  - description: DSI Fatal Error interrupt
> +  - description: DSI D-PHY PPI interrupt
> +  - description: Debug interrupt
> +
> +  interrupt-names:
> +items:
> +  - const: seq0
> +  - const: seq1
> +  - const: vin1
> +  - const: rcv
> +  - const: ferr
> +  - const: ppi
> +  - const: debug
> +
> +  clocks:
> +items:
> +  - description: DSI D-PHY PLL multiplied clock
> +  - description: DSI D-PHY system clock
> +  - description: DSI AXI bus clock
> +  - description: DSI Register access clock
> +  - description: DSI Video clock
> +  - description: DSI D-PHY Escape mode Receive clock

Isn't this the escape mode *transmit* clock ?

> +
> +  clock-names:
> +items:
> +  - const: pllclk
> +  - const: sysclk
> +  - const: aclk
> +  - const: pclk
> +  - const: vclk
> +  - const: lpclk
> +
> +  resets:
> +items:
> +  - description: MIPI_DSI_CMN_RSTB
> +  - description: MIPI_DSI_ARESET_N
> +  - description: MIPI_DSI_PRESET_N
> +
> +  reset-names:
> +items:
> +  - const: rst
> +  - const: arst
> +  - const: prst
> +
> +  power-domains:
> +maxItems: 1
> +
> +  ports:
> +$ref: /schemas/graph.yaml#/properties/ports
> +
> +properties:
> +  port@0:
> +$ref: /schemas/graph.yaml#/properties/port
> +description: Parallel input port
> +
> +  port@1:
> +$ref: /schemas/graph.yaml#/$defs/port-base
> +unevaluatedProperties: false
> +description: DSI output port
> +
> +properties:
> +  endpoint:
> +$ref: /schemas/media/video-interfaces.yaml#
> +unevaluatedProperties: false
> +
> +properties:
> +  data-lanes:
> +minItems: 1
> +maxItems: 4

You should specify the acceptable values, especially given that the
hardware doesn't seem to support lane reordering.

> +
> +required:
> +  - data-lanes
> +
> +required:
> +  - port@0
> +  - port@1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - interrupt-names
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - power-domains
> +  - ports
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +#include 
> +#include 

Could you please swap those two lines to get them sorted alphabetically
?

With these comments addressed,

Reviewed-by: Laurent Pinchart 

> +
> +dsi0: dsi@1085 {
> +compatible = "renesas,rzg2l-mipi-dsi";
> +reg = <0x1085 0x2>;
> +interrupts = ,
> + ,
> + ,
> + ,
> + ,
> + ,
> + ;
> +interr

Re: [PATCH v19 03/10] soc: mediatek: add mtk-mmsys support for mt8195 vdosys0

2022-04-15 Thread AngeloGioacchino Del Regno

Il 15/04/22 10:39, jason-jh.lin ha scritto:

1. Add mt8195 mmsys compatible for 2 vdosys.
2. Add io_start into each driver data of mt8195 vdosys.
3. Add get match data function to identify mmsys by io_start.
4. Add mt8195 routing table settings of vdosys0.

Signed-off-by: jason-jh.lin 


Unless anyone wants this commit to be split in two, one for the match data
and one for the mt8195 addition, it looks almost good to me, apart one small
change that has to be done, check below:



--- >   drivers/soc/mediatek/mt8195-mmsys.h| 370 +
  drivers/soc/mediatek/mtk-mmsys.c   | 152 +-
  drivers/soc/mediatek/mtk-mmsys.h   |   6 +
  include/linux/soc/mediatek/mtk-mmsys.h |  11 +
  4 files changed, 528 insertions(+), 11 deletions(-)
  create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h



..snip..


diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 77f37f8c715b..21cf300ba864 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -87,12 +87,18 @@ struct mtk_mmsys_routes {
  };
  
  struct mtk_mmsys_driver_data {

+   const u32 io_start;


I agree with you that this iostart is in 32bits boundaries, and that this will
practically never change... and I was in doubt whether this would be acceptable
or not, because of saving some memory.

Even though I would really love to have the savings, in order to avoid having 
any
"surprises" in the future (any future breakage for "reasons"), we shall comply
with the kernel types, so, this has to be...

const resource_size_t io_start;

...and this is the same for both this file and mtk_drm_drv.h, which you modify 
in
patch 07/10.

After fixing that:

Reviewed-by: AngeloGioacchino Del Regno 



Cheers,
Angelo


Re: [PATCH v19 07/10] drm/mediatek: add mediatek-drm of vdosys0 support for mt8195

2022-04-15 Thread AngeloGioacchino Del Regno

Il 15/04/22 10:39, jason-jh.lin ha scritto:

1. Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver.
2. Add get driver data function to identify which vdosys by io_start.

Signed-off-by: jason-jh.lin 
---
  drivers/gpu/drm/mediatek/mtk_disp_rdma.c |   6 +
  drivers/gpu/drm/mediatek/mtk_drm_drv.c   | 141 +--
  drivers/gpu/drm/mediatek/mtk_drm_drv.h   |   6 +
  3 files changed, 145 insertions(+), 8 deletions(-)



..snip..


diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index a58cebd01d35..e1a37ca091f3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -21,6 +21,7 @@ struct drm_property;
  struct regmap;
  
  struct mtk_mmsys_driver_data {

+   const unsigned int io_start;


As mentioned in patch 03/10, this has to be

const resource_size_t io_start;

Thanks!



Re: [PATCH v19 10/10] soc: mediatek: remove DDP_DOMPONENT_DITHER enum

2022-04-15 Thread AngeloGioacchino Del Regno

Il 15/04/22 10:39, jason-jh.lin ha scritto:

After mmsys and drm change DITHER enum to DDP_COMPONENT_DITHER0,
mmsys header can remove the useless DDP_COMPONENT_DITHER enum.

Signed-off-by: jason-jh.lin 


Can you please fix the commit title with:
soc: mediatek: remove DDP_DOMPONENT_DITHER from enum

that "from" is important, as you're not removing *an enum*, but *from an enum*.

After that:

Reviewed-by: AngeloGioacchino Del Regno 


Thanks!
Angelo


Re: [PATCH v19 09/10] drm/mediatek: add postfix 0 to DDP_COMPONENT_DITHER for mt8195 vdosys0

2022-04-15 Thread AngeloGioacchino Del Regno

Il 15/04/22 10:39, jason-jh.lin ha scritto:

Because mt8195 vdosys0 has 2 DITHER components,
so the postfix 0 need to be added to DDP_COMPONENT_DITHER.

Then DITHER enum will become:
DDP_COMPONENT_DITHER0 and DDP_COMPONENT_DITHER1.

Signed-off-by: jason-jh.lin 


I think that "postfix" should be "suffix" instead :)))

In any case:

Reviewed-by: AngeloGioacchino Del Regno 




Re: [PATCH v19 08/10] soc: mediatek: add DDP_DOMPONENT_DITHER0 enum for mt8195 vdosys0

2022-04-15 Thread AngeloGioacchino Del Regno

Il 15/04/22 10:39, jason-jh.lin ha scritto:

The mmsys routing table of mt8195 vdosys0 has 2 DITHER components,
so mmsys need to add DDP_COMPONENT_DITHER1 and change all usages of
DITHER enum form DDP_COMPONENT_DITHER to DDP_COMPONENT_DITHER0.

But its header need to keep DDP_COMPONENT_DITHER enum
until drm/mediatek also changed it.

Signed-off-by: jason-jh.lin 


Reviewed-by: AngeloGioacchino Del Regno 




Re: [PATCH v2 2/2] drm: rcar-du: Add RZ/G2L DSI driver

2022-04-15 Thread Laurent Pinchart
Hi Biju,

Thank you for the patch.

On Mon, Mar 28, 2022 at 07:51:15AM +0100, Biju Das wrote:
> This driver supports the MIPI DSI encoder found in the RZ/G2L
> SoC. It currently supports DSI mode only.
> 
> Signed-off-by: Biju Das 
> ---
> v1->v2:
>  * Rework based on dt-binding change (DSI + D-PHY) as single block
>  * Replaced link_mmio and phy_mmio with mmio in struct rzg2l_mipi_dsi
>  * Replaced rzg2l_mipi_phy_write with rzg2l_mipi_dsi_phy_write
>and rzg2l_mipi_dsi_link_write
>  * Replaced rzg2l_mipi_phy_read->rzg2l_mipi_dsi_link_read
> RFC->v1:
>  * Added "depends on ARCH_RENESAS || COMPILE_TEST" on KCONFIG
>and dropped DRM as it is implied by DRM_BRIDGE
>  * Used devm_reset_control_get_exclusive() for reset handle
>  * Removed bool hsclkmode from struct rzg2l_mipi_dsi
>  * Added error check for pm, using pm_runtime_resume_and_get() instead of
>pm_runtime_get_sync()
>  * Added check for unsupported formats in rzg2l_mipi_dsi_host_attach()
>  * Avoided read-modify-write stopping hsclock
>  * Used devm_platform_ioremap_resource for resource allocation
>  * Removed unnecessary assert call from probe and remove.
>  * wrap the line after the PTR_ERR() in probe()
>  * Updated reset failure messages in probe
>  * Fixed the typo arstc->prstc
>  * Made hex constants to lower case.
> RFC:
>  * 
> https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-23-biju.das...@bp.renesas.com/
> ---
>  drivers/gpu/drm/rcar-du/Kconfig   |   8 +
>  drivers/gpu/drm/rcar-du/Makefile  |   1 +
>  drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c  | 686 ++
>  drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi_regs.h | 149 
>  4 files changed, 844 insertions(+)
>  create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
>  create mode 100644 drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi_regs.h
> 
> diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
> index e40fb0c53f9b..83d7d28214a0 100644
> --- a/drivers/gpu/drm/rcar-du/Kconfig
> +++ b/drivers/gpu/drm/rcar-du/Kconfig
> @@ -64,6 +64,14 @@ config DRM_RCAR_MIPI_DSI
>   help
> Enable support for the R-Car Display Unit embedded MIPI DSI encoders.
>  
> +config DRM_RZG2L_MIPI_DSI
> + tristate "RZ/G2L MIPI DSI Encoder Support"
> + depends on DRM_BRIDGE && OF
> + depends on ARCH_RENESAS || COMPILE_TEST
> + select DRM_MIPI_DSI
> + help
> +   Enable support for the RZ/G2L Display Unit embedded MIPI DSI encoders.
> +
>  config DRM_RCAR_VSP
>   bool "R-Car DU VSP Compositor Support" if ARM
>   default y if ARM64
> diff --git a/drivers/gpu/drm/rcar-du/Makefile 
> b/drivers/gpu/drm/rcar-du/Makefile
> index 01ba78e56b53..7fb4f8717fc4 100644
> --- a/drivers/gpu/drm/rcar-du/Makefile
> +++ b/drivers/gpu/drm/rcar-du/Makefile
> @@ -27,6 +27,7 @@ obj-$(CONFIG_DRM_RCAR_LVDS) += rcar_lvds.o
>  obj-$(CONFIG_DRM_RCAR_MIPI_DSI)  += rcar_mipi_dsi.o
>  
>  obj-$(CONFIG_DRM_RZG2L_DU)   += rzg2l-du-drm.o
> +obj-$(CONFIG_DRM_RZG2L_MIPI_DSI) += rzg2l_mipi_dsi.o
>  
>  # 'remote-endpoint' is fixed up at run-time
>  DTC_FLAGS_rcar_du_of_lvds_r8a7790 += -Wno-graph_endpoint
> diff --git a/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c 
> b/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
> new file mode 100644
> index ..3b785041ba5e
> --- /dev/null
> +++ b/drivers/gpu/drm/rcar-du/rzg2l_mipi_dsi.c
> @@ -0,0 +1,686 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * RZ/G2L MIPI DSI Encoder Driver
> + *
> + * Copyright (C) 2022 Renesas Electronics Corporation
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "rzg2l_mipi_dsi_regs.h"
> +
> +struct rzg2l_mipi_dsi {
> + struct device *dev;
> + void __iomem *mmio;
> +
> + struct reset_control *rstc;
> + struct reset_control *arstc;
> + struct reset_control *prstc;
> +
> + struct mipi_dsi_host host;
> + struct drm_bridge bridge;
> + struct drm_bridge *next_bridge;
> +
> + struct clk *vclk;
> +
> + enum mipi_dsi_pixel_format format;
> + unsigned int num_data_lanes;
> + unsigned int lanes;
> + unsigned long mode_flags;
> +};
> +
> +static inline struct rzg2l_mipi_dsi *
> +bridge_to_rzg2l_mipi_dsi(struct drm_bridge *bridge)
> +{
> + return container_of(bridge, struct rzg2l_mipi_dsi, bridge);
> +}
> +
> +static inline struct rzg2l_mipi_dsi *
> +host_to_rzg2l_mipi_dsi(struct mipi_dsi_host *host)
> +{
> + return container_of(host, struct rzg2l_mipi_dsi, host);
> +}
> +
> +static void rzg2l_mipi_dsi_phy_write(void __iomem *mem, u32 reg, u32 data)

You can pass a rzg2l_mipi_dsi pointer to this function instead of the
memory pointer. Same for the two functions below.

> +{
> + iowrite32(data, mem + reg);
> +}
> +
> +static void rzg2l_mipi_

Re: [PATCH v9 00/23] drm/rockchip: RK356x VOP2 support

2022-04-15 Thread Piotr Oniszczuk



> Wiadomość napisana przez Daniel Stone  w dniu 
> 12.04.2022, o godz. 13:30:
> 
>> Testing Sacha patch (see today's email from Sascha) i'm getting
>> 
>> Qt: EGL Error : Could not create the egl surface: error = 0x3009
>> 
>> i'm reading this as: Qt tries allocate EGL surface and EGL returns error.
>> or i'm wrong?
> 
> Correct, that's EGL_BAD_MATCH. There are very few ways that can
> happen; by far the most likely is that Qt has chosen an EGLConfig
> which does not correctly correspond to the format. (If it was an
> impossible format/modifier combination, then this would be already
> caught when allocating the gbm_surface.)
> 
> Either way, it seems quite clear that the VOP2 driver is totally fine
> here, and that you have a Qt (likely) or Mesa (tbh less likely) issue
> to debug to get the app working.
> 
> Cheers,
> Daniel

Thx Daniel!

Indeed - this is probably another case where I see: writing DRM planes 
rendering mediaplayer with help of Qt is (too)corner case for Qt


@all

Looking on Qt sources it looks to me this format should be supported:

https://code.qt.io/cgit/qt/qtbase.git/tree/src/platformsupport/kmsconvenience/qkmsdevice.cpp?h=5.15.2#n380

Interesting that with custom Qt config1: "format": "argb",
DRI state shows: format=AR24 little-endian (0x34325241)

UI is OK, playback is OK. OSD not visible (*)

custom config2: "format": "abgr" 
Qt crashes with EGL_BAD_MATCH

So it looks forcing some Qt formats works while other - not. 

Looking why this:

Qt logging says nothing.
export MESA_DEBUG=1 gives no any message. I'm a lost here a bit...



But from a bit more distant perspective:

1. Sascha concludes in (*) that issue is most probably in format negotiation by 
app.

2. imho app probably correctly negotiates accordingly to inputs it gets from 
providers (DRM) and clients (mesa). 
Test with patch excluding
DRM_FORMAT_XRGB,
DRM_FORMAT_ARGB,
shows imho proper app reaction on this (new format elected; but Qt fails with 
this format). Indirectly i conclude app logic is ok

3. Sum of p1 & p2 tells me:
i need to add extra logic in format election to specifically deal with 
constrains of rk356x (see explanation in (*))

4. Even if i implement p3 - then user world - (this using Qt) - will be not 
happy as:
- majority users are using pre-build Qt
- I don't believe Trolltech will fix this soon

So i see following path:
  
we will verify is issue of Qt with abgr an Qt root cause issue,

If Yes - then:
- Investigate is there reasonable way to workaround with this outside 
of Qt?
If not - then:
- conclude: vop2 - due Qt bug - will not work ok with Qt until Qt will 
be fixed.

 
If you think this make sense - i need some help with: verify is issue of Qt 
with abgr an Qt root cause issue

let me know what you think



(*)
Sascha mentioned:
> Somehow negotiation of the format goes wrong. Applications shouldn't
> pick these formats when the GPU is used for rendering. I don't know how
> and where this should be fixed properly, but your application should use
> DRM_FORMAT_ABGR aka AB24 aka PIPE_FORMAT_R8G8B8A8_UNORM instead of
> DRM_FORMAT_ARGB aka AR24 aka PIPE_FORMAT_B8G8R8A8_UNORM.




Re: [PATCH v2 1/7] dt-bindings: display: renesas,du: Document r9a07g044l bindings

2022-04-15 Thread Laurent Pinchart
Hi Biju,

Thank you for the patch.

On Wed, Mar 16, 2022 at 01:10:54PM +, Biju Das wrote:
> Extend the Renesas DU display bindings to support the r9a07g044l
> DU module found on RZ/G2L LCDC.

Stupid question, but as this DU and the R-Car DU are completely
different pieces of hardware, wouldn't a separate bindings file make
sense ?

The DT description in this patch looks good to me.

> Signed-off-by: Biju Das 
> ---
> v1->v2:
>  * Updated commit description.
>  * Removed LCDC references
>  * Changed clock name from du.0->aclk
>  * Changed reset name from du.0->du
> RFC->v1:
>  * Changed  minItems->maxItems for renesas,vsps.
> RFC:
>  
> https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-18-biju.das...@bp.renesas.com/
> ---
>  .../bindings/display/renesas,du.yaml  | 54 +++
>  1 file changed, 54 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/renesas,du.yaml 
> b/Documentation/devicetree/bindings/display/renesas,du.yaml
> index 13efea574584..f560608bf4e8 100644
> --- a/Documentation/devicetree/bindings/display/renesas,du.yaml
> +++ b/Documentation/devicetree/bindings/display/renesas,du.yaml
> @@ -40,6 +40,7 @@ properties:
>- renesas,du-r8a77990 # for R-Car E3 compatible DU
>- renesas,du-r8a77995 # for R-Car D3 compatible DU
>- renesas,du-r8a779a0 # for R-Car V3U compatible DU
> +  - renesas,du-r9a07g044l # for RZ/G2L compatible DU
>  
>reg:
>  maxItems: 1
> @@ -824,6 +825,59 @@ allOf:
>  - reset-names
>  - renesas,vsps
>  
> +  - if:
> +  properties:
> +compatible:
> +  contains:
> +enum:
> +  - renesas,du-r9a07g044l
> +then:
> +  properties:
> +clocks:
> +  items:
> +- description: Main clock
> +- description: Register access clock
> +- description: Video clock
> +
> +clock-names:
> +  items:
> +- const: aclk
> +- const: pclk
> +- const: vclk
> +
> +interrupts:
> +  maxItems: 1
> +
> +resets:
> +  maxItems: 1
> +
> +reset-names:
> +  items:
> +- const: du
> +
> +ports:
> +  properties:
> +port@0:
> +  description: DPAD 0
> +port@1:
> +  description: DSI 0
> +port@2: false
> +port@3: false
> +
> +  required:
> +- port@0
> +- port@1
> +
> +renesas,vsps:
> +  maxItems: 1
> +
> +  required:
> +- clock-names
> +- interrupts
> +- resets
> +- reset-names
> +- renesas,vsps
> +
>  additionalProperties: false
>  
>  examples:

-- 
Regards,

Laurent Pinchart


Re: [PATCH v2 2/7] drm: rcar-du: Add num_rpf to struct rcar_du_device_info

2022-04-15 Thread Laurent Pinchart
Hi Biju,

Thank you for the patch.

On Wed, Mar 16, 2022 at 01:10:55PM +, Biju Das wrote:
> Number of RPF's VSP is different on R-Car and RZ/G2L
>  R-Car Gen3 -> 5 RPFs
>  R-Car Gen2 -> 4 RPFs
>  RZ/G2L -> 2 RPFs
> 
> Add num_rpf to struct rcar_du_device_info to support later
> SoC without any code changes.
> 
> Signed-off-by: Biju Das 
> ---
> v1->v2:
>  * No change
> RFC->v1:
>  * Fixed the comment for num_rpf s/rpf's/RPFs/ and s/vsp/VSP/
> RFC:
>  * 
> https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-12-biju.das...@bp.renesas.com/
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c | 17 +
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h |  2 ++
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c |  6 +-
>  3 files changed, 20 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 957ea97541d5..1bc7325aa356 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -55,6 +55,7 @@ static const struct rcar_du_device_info 
> rzg1_du_r8a7743_info = {
>   },
>   },
>   .num_lvds = 1,
> + .num_rpf = 4,
>  };
>  
>  static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
> @@ -77,6 +78,7 @@ static const struct rcar_du_device_info 
> rzg1_du_r8a7745_info = {
>   .port = 1,
>   },
>   },
> + .num_rpf = 4,
>  };
>  
>  static const struct rcar_du_device_info rzg1_du_r8a77470_info = {
> @@ -104,6 +106,7 @@ static const struct rcar_du_device_info 
> rzg1_du_r8a77470_info = {
>   .port = 2,
>   },
>   },
> + .num_rpf = 4,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a774a1_info = {
> @@ -133,6 +136,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774a1_info = {
>   },
>   },
>   .num_lvds = 1,
> + .num_rpf = 5,
>   .dpll_mask =  BIT(1),
>  };
>  
> @@ -163,6 +167,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774b1_info = {
>   },
>   },
>   .num_lvds = 1,
> + .num_rpf = 5,
>   .dpll_mask =  BIT(1),
>  };
>  
> @@ -190,6 +195,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774c0_info = {
>   },
>   },
>   .num_lvds = 2,
> + .num_rpf = 4,
>   .lvds_clk_mask =  BIT(1) | BIT(0),
>  };
>  
> @@ -220,6 +226,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774e1_info = {
>   },
>   },
>   .num_lvds = 1,
> + .num_rpf = 5,
>   .dpll_mask =  BIT(1),
>  };
>  
> @@ -272,6 +279,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7790_info = {
>   },
>   },
>   .num_lvds = 2,
> + .num_rpf = 4,
>  };
>  
>  /* M2-W (r8a7791) and M2-N (r8a7793) are identical */
> @@ -297,6 +305,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7791_info = {
>   },
>   },
>   .num_lvds = 1,
> + .num_rpf = 4,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7792_info = {
> @@ -317,6 +326,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7792_info = {
>   .port = 1,
>   },
>   },
> + .num_rpf = 4,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7794_info = {
> @@ -340,6 +350,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7794_info = {
>   .port = 1,
>   },
>   },
> + .num_rpf = 4,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7795_info = {
> @@ -373,6 +384,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7795_info = {
>   },
>   },
>   .num_lvds = 1,
> + .num_rpf = 5,
>   .dpll_mask =  BIT(2) | BIT(1),
>  };
>  
> @@ -403,6 +415,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7796_info = {
>   },
>   },
>   .num_lvds = 1,
> + .num_rpf = 5,
>   .dpll_mask =  BIT(1),
>  };
>  
> @@ -433,6 +446,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a77965_info = {
>   },
>   },
>   .num_lvds = 1,
> + .num_rpf = 5,
>   .dpll_mask =  BIT(1),
>  };
>  
> @@ -459,6 +473,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a77970_info = {
>   },
>   },
>   .num_lvds = 1,
> + .num_rpf = 5,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7799x_info = {
> @@ -486,6 +501,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7799x_info = {
>   },
>   },
>   .num_lvds = 2,
> + .num_rpf = 5,
>   .lvds_clk_mask =  BIT(1) | BIT(0),
>  };
>  
> @@ -505,6 +521,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a779a0_info = {
>   .port = 1,
>   },
>   },
> + .num_rpf = 5,
>   .dsi_clk_mask =  BIT(1) | BIT(0),
>  };
>  
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h 
> b/drivers/gpu/d

Re: [PATCH v2 3/7] drm: rcar-du: Add max_width and max_height to struct rcar_du_device_info

2022-04-15 Thread Laurent Pinchart
Hi Biju,

Thank you for the patch.

On Wed, Mar 16, 2022 at 01:10:56PM +, Biju Das wrote:
> There are some differences related to max frame size supported by different
> R-Car/RZ-G family of SoC's
> 
> Max frame size supported by R-Car Gen1 & R-Car Gen2 is 4095x2047
> Max frame size supported by R-Car Gen3 is 8190x8190
> Max frame size supported by RZ/G2L is 1920x1080
> 
> Add max_width and max_height to struct rcar_du_device_info to support later
> SoC without any code changes.
> 
> Signed-off-by: Biju Das 
> ---
> v1->v2:
>  * No Change
> RFC->V1:
>  * No Change
> RFC:
>  * 
> https://patchwork.kernel.org/project/linux-renesas-soc/patch/20220112174612.10773-13-biju.das...@bp.renesas.com/
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c | 36 +++
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h |  4 +++
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c | 17 +
>  3 files changed, 46 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 1bc7325aa356..4640c356a532 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -56,6 +56,8 @@ static const struct rcar_du_device_info 
> rzg1_du_r8a7743_info = {
>   },
>   .num_lvds = 1,
>   .num_rpf = 4,
> + .max_width = 4095,
> + .max_height = 2047,
>  };
>  
>  static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
> @@ -79,6 +81,8 @@ static const struct rcar_du_device_info 
> rzg1_du_r8a7745_info = {
>   },
>   },
>   .num_rpf = 4,
> + .max_width = 4095,
> + .max_height = 2047,
>  };
>  
>  static const struct rcar_du_device_info rzg1_du_r8a77470_info = {
> @@ -107,6 +111,8 @@ static const struct rcar_du_device_info 
> rzg1_du_r8a77470_info = {
>   },
>   },
>   .num_rpf = 4,
> + .max_width = 4095,
> + .max_height = 2047,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a774a1_info = {
> @@ -137,6 +143,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774a1_info = {
>   },
>   .num_lvds = 1,
>   .num_rpf = 5,
> + .max_width = 8190,
> + .max_height = 8190,
>   .dpll_mask =  BIT(1),
>  };
>  
> @@ -168,6 +176,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774b1_info = {
>   },
>   .num_lvds = 1,
>   .num_rpf = 5,
> + .max_width = 8190,
> + .max_height = 8190,
>   .dpll_mask =  BIT(1),
>  };
>  
> @@ -196,6 +206,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774c0_info = {
>   },
>   .num_lvds = 2,
>   .num_rpf = 4,
> + .max_width = 8190,
> + .max_height = 8190,
>   .lvds_clk_mask =  BIT(1) | BIT(0),
>  };
>  
> @@ -227,6 +239,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774e1_info = {
>   },
>   .num_lvds = 1,
>   .num_rpf = 5,
> + .max_width = 8190,
> + .max_height = 8190,
>   .dpll_mask =  BIT(1),
>  };
>  
> @@ -249,6 +263,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7779_info = {
>   .port = 1,
>   },
>   },
> + .max_width = 4095,
> + .max_height = 2047,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7790_info = {
> @@ -280,6 +296,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7790_info = {
>   },
>   .num_lvds = 2,
>   .num_rpf = 4,
> + .max_width = 4095,
> + .max_height = 2047,
>  };
>  
>  /* M2-W (r8a7791) and M2-N (r8a7793) are identical */
> @@ -306,6 +324,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7791_info = {
>   },
>   .num_lvds = 1,
>   .num_rpf = 4,
> + .max_width = 4095,
> + .max_height = 2047,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7792_info = {
> @@ -327,6 +347,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7792_info = {
>   },
>   },
>   .num_rpf = 4,
> + .max_width = 4095,
> + .max_height = 2047,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7794_info = {
> @@ -351,6 +373,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7794_info = {
>   },
>   },
>   .num_rpf = 4,
> + .max_width = 4095,
> + .max_height = 2047,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7795_info = {
> @@ -385,6 +409,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7795_info = {
>   },
>   .num_lvds = 1,
>   .num_rpf = 5,
> + .max_width = 8190,
> + .max_height = 8190,
>   .dpll_mask =  BIT(2) | BIT(1),
>  };
>  
> @@ -416,6 +442,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7796_info = {
>   },
>   .num_lvds = 1,
>   .num_rpf = 5,
> + .max_width = 8190,
> + .max_height = 8190,
>   .dpll_mask =  BIT(1),
>  };
>  
> @@ -447,6 +475,8 @@ static const struct rcar_du_device_info 
> rcar_du_r8a77965_info = {
>   },
>   .num_lvds = 1,
>   .

Re: [PATCH v2 4/7] drm: rcar-du: Move rcar_du_output_name() to rcar_du_common.c

2022-04-15 Thread Laurent Pinchart
Hi Biju,

Thank you for the patch.

On Wed, Mar 16, 2022 at 01:10:57PM +, Biju Das wrote:
> RZ/G2L SoC's does not have group/plane registers compared to RCar, hence it
> needs a different CRTC implementation.
> 
> Move rcar_du_output_name() to a new common file rcar_du_common.c, So that
> the same function can be reused by RZ/G2L SoC later.
> 
> Signed-off-by: Biju Das 
> ---
> v1->v2:
>  * No change
> RFC->v1:
>  New patch
> ---
>  drivers/gpu/drm/rcar-du/Makefile |  1 +
>  drivers/gpu/drm/rcar-du/rcar_du_common.c | 30 
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c| 20 
>  3 files changed, 31 insertions(+), 20 deletions(-)
>  create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_common.c
> 
> diff --git a/drivers/gpu/drm/rcar-du/Makefile 
> b/drivers/gpu/drm/rcar-du/Makefile
> index e7275b5e7ec8..331e12d65a6b 100644
> --- a/drivers/gpu/drm/rcar-du/Makefile
> +++ b/drivers/gpu/drm/rcar-du/Makefile
> @@ -1,5 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
>  rcar-du-drm-y := rcar_du_crtc.o \
> +  rcar_du_common.o \
>rcar_du_drv.o \
>rcar_du_encoder.o \
>rcar_du_group.o \
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_common.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_common.c
> new file mode 100644
> index ..f9f9908cda6d
> --- /dev/null
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_common.c
> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * rcar_du_common.c  --  R-Car Display Unit Common
> + *
> + * Copyright (C) 2013-2022 Renesas Electronics Corporation
> + *
> + * Contact: Laurent Pinchart (laurent.pinch...@ideasonboard.com)
> + */
> +
> +#include "rcar_du_drv.h"
> +
> +const char *rcar_du_output_name(enum rcar_du_output output)
> +{
> + static const char * const names[] = {
> + [RCAR_DU_OUTPUT_DPAD0] = "DPAD0",
> + [RCAR_DU_OUTPUT_DPAD1] = "DPAD1",
> + [RCAR_DU_OUTPUT_DSI0] = "DSI0",
> + [RCAR_DU_OUTPUT_DSI1] = "DSI1",
> + [RCAR_DU_OUTPUT_HDMI0] = "HDMI0",
> + [RCAR_DU_OUTPUT_HDMI1] = "HDMI1",
> + [RCAR_DU_OUTPUT_LVDS0] = "LVDS0",
> + [RCAR_DU_OUTPUT_LVDS1] = "LVDS1",
> + [RCAR_DU_OUTPUT_TCON] = "TCON",
> + };
> +
> + if (output >= ARRAY_SIZE(names) || !names[output])
> + return "UNKNOWN";
> +
> + return names[output];
> +}

As we have nothing else than this function in this file, how about
moving it to rcar_du_drv.c instead, to avoid adding a new file ?

You also need to add a declaration for rcar_du_output_name() in the
appropriate header.

> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 4640c356a532..f6e234dafb72 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -591,26 +591,6 @@ static const struct of_device_id rcar_du_of_table[] = {
>  
>  MODULE_DEVICE_TABLE(of, rcar_du_of_table);
>  
> -const char *rcar_du_output_name(enum rcar_du_output output)
> -{
> - static const char * const names[] = {
> - [RCAR_DU_OUTPUT_DPAD0] = "DPAD0",
> - [RCAR_DU_OUTPUT_DPAD1] = "DPAD1",
> - [RCAR_DU_OUTPUT_DSI0] = "DSI0",
> - [RCAR_DU_OUTPUT_DSI1] = "DSI1",
> - [RCAR_DU_OUTPUT_HDMI0] = "HDMI0",
> - [RCAR_DU_OUTPUT_HDMI1] = "HDMI1",
> - [RCAR_DU_OUTPUT_LVDS0] = "LVDS0",
> - [RCAR_DU_OUTPUT_LVDS1] = "LVDS1",
> - [RCAR_DU_OUTPUT_TCON] = "TCON",
> - };
> -
> - if (output >= ARRAY_SIZE(names) || !names[output])
> - return "UNKNOWN";
> -
> - return names[output];
> -}
> -
>  /* 
> -
>   * DRM operations
>   */

-- 
Regards,

Laurent Pinchart


Re: [RFC PATCH 02/16] dt-bindings: display: rockchip: Add EBC binding

2022-04-15 Thread Andreas Kemnade
On Thu, 14 Apr 2022 22:00:09 -0500
Samuel Holland  wrote:

> Hi Andreas,
> 
> Thanks for the comments.
> 
> On 4/14/22 3:15 AM, Andreas Kemnade wrote:
> > Hi Samuel,
> > 
> > for comparison, here is my submission for the IMX EPDC bindings:
> > 
> > https://lore.kernel.org/linux-devicetree/20220206080016.796556-2-andr...@kemnade.info/
> > 
> > On Wed, 13 Apr 2022 17:19:02 -0500
> > Samuel Holland  wrote:
> > 
> > [...]
> > we have sy7636a driver in kernel which should be suitable for powering a EPD
> > and temperature measurement. So I would expect that to be   
> >> +  io-channels:
> >> +maxItems: 1
> >> +description: I/O channel for panel temperature measurement
> >> +  
> > so how would I reference the hwmon/thermal(-zone) of the sy7636a here?  
> 
> It seems the consensus is to use a thermal zone for panel temperature, so I 
> will
> need to change this.
> 
I am open to anything here as long as it fits together.

> I think it's best to reference the thermal zone by phandle, not by name, even 
> if
> it requires extending the thermal zone API to support this.
> 
maybe referencing the hwmon might be interesting, or we add a hwmon_iio
adaptor. The other way round it is there. The thermal zone stuff is
only needed because hwmon cannot referenced directly.

Regards,
Andreas


Re: [PATCH 9/9] vfio: Remove calls to vfio_group_add_container_user()

2022-04-15 Thread Jason Gunthorpe
On Fri, Apr 15, 2022 at 02:32:08AM +, Tian, Kevin wrote:

> While it's a welcomed fix is it actually related to this series? The point
> of this patch is that those functions are called when container_users
> is non-zero. This is true even without this fix given container_users
> is decremented after calling device->ops->close_device().

It isn't, it is decremented before which causes it to be 0 when the
assertions are called.

Jason


[pull] amdgpu, amdkfd, radeon drm-next-5.19

2022-04-15 Thread Alex Deucher
Hi Dave, Daniel,

New features for 5.19.  There is a new DP define added in drm_dp_helper.h
to support some new DC code.  That file has moved in drm-misc.  Just
a heads up there when you merge.

The following changes since commit 15f9cd4334c83716fa32647652a609e3ba6c998d:

  drm/amdgpu/gfx10: enable gfx1037 clock counter retrieval function (2022-03-25 
12:40:25 -0400)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-next-5.19-2022-04-15

for you to fetch changes up to d68cf992ded575928cf4ddf7c64faff0d8dcce14:

  drm/amd/amdgpu: Remove static from variable in RLCG Reg RW (2022-04-14 
15:29:20 -0400)


amd-drm-next-5.19-2022-04-15:

amdgpu:
- USB-C updates
- GPUVM updates
- TMZ fixes for RV
- DCN 3.1 pstate fixes
- Display z state fixes
- RAS fixes
- Misc code cleanups and spelling fixes
- More DC FP rework
- GPUVM TLB handling rework
- Power management sysfs code cleanup
- Add RAS support for VCN
- Backlight fix
- Add unique id support for more asics
- Misc display updates
- SR-IOV fixes
- Extend CG and PG flags to 64 bits
- Enable VCN clk sysfs nodes for navi12

amdkfd:
- Fix IO link cleanup during device removal
- RAS fixes
- Retry fault fixes
- Asynchronously free events
- SVM fixes

radeon:
- Drop some dead code
- Misc code cleanups


Aashish Sharma (1):
  drm/amd/display: Fix unused-but-set-variable warning

Ahmad Othman (1):
  drm/amd/display: Fix HDCP SEND AKI INIT error

Alex Deucher (7):
  drm/amdgpu: make amdgpu_display_framebuffer_init() static
  drm/amdgpu: drop amdgpu_display_gem_fb_init()
  drm/amdgpu: make amdgpu_display_gem_fb_verify_and_init() static
  drm/amdgpu: don't use BACO for reset in S3
  drm/amdgpu/smu10: fix SoC/fclk units in auto mode
  drm/amdgpu: fix VCN 3.1.2 firmware name
  drm/amd/display: fix 64 bit divide in freesync code

Angus Wang (4):
  drm/amd/display: Create underflow interrupt IRQ type
  drm/amd/display: Add flip interval workaround
  drm/amd/display: Remove underflow IRQ type
  drm/amd/display: Fix inconsistent timestamp type

Anthony Koo (3):
  drm/amd/display: [FW Promotion] Release 0.0.109.0
  drm/amd/display: [FW Promotion] Release 0.0.110.0
  drm/amd/display: [FW Promotion] Release 0.0.111.0

Aric Cyr (4):
  drm/amd/display: 3.2.178
  drm/amd/display: 3.2.179
  drm/amd/display: 3.2.180
  drm/amd/display: 3.2.181

Becle Lee (1):
  drm/amd/display: fix missing-prototypes warning

Benjamin Marty (1):
  drm/amdgpu/display: change pipe policy for DCN 2.1

Boyuan Zhang (1):
  drm/amdgpu/vcn3: send smu interface type

CHANDAN VURDIGERE NATARAJ (1):
  drm/amd/display: Fix by adding FPU protection for 
dcn30_internal_validate_bw

Charlene Liu (2):
  drm/amd/display: Clear optc false state when disable otg
  drm/amd/display: remove dtbclk_ss compensation for dcn316

Chris Park (1):
  drm/amd/display: Correct Slice reset calculation

Christian König (10):
  drm/amdgpu: move VM PDEs to idle after update
  drm/amdgpu: separate VM PT handling into amdgpu_vm_pt.c
  drm/amdgpu: simplify VM update tracking a bit
  drm/amdgpu: rework TLB flushing
  drm/amdkfd: start using tlb_seq from the VM subsystem
  drm/amdkfd: use tlb_seq from the VM subsystem for SVM as well v2
  drm/amdgpu: remove table_freed param from the VM code
  drm/amdgpu: fix some kerneldoc in the VM code v2
  drm/amdgpu: fix incorrect size printing in error msg
  drm/amdgpu: fix TLB flushing during eviction

Colin Ian King (1):
  drm/amdgpu: Fix spelling mistake "regiser" -> "register"

Dan Carpenter (1):
  drm/amdkfd: potential NULL dereference in kfd_set/reset_event()

Darren Powell (2):
  amdgpu/pm: Add new hwmgr API function "emit_clock_levels"
  amdgpu/pm: Implement emit_clk_levels for vega10

David Zhang (2):
  drm: add PSR2 support and capability definition as per eDP 1.5
  drm/amd/display: implement shared PSR-SU sink validation helper

Dillon Varone (2):
  drm/amd/display: Add dtb clock to dc_clocks
  drm/amd/display: Select correct DTO source

Dmytro Laktyushkin (1):
  drm/amd/display: update dcn315 clock table read

Duncan Ma (1):
  drm/amd/display: Add odm seamless boot support

Eric Bernstein (1):
  drm/amd/display: remove assert for odm transition case

Eric Yang (1):
  drm/amd/display: undo clearing of z10 related function pointers

Evan Quan (1):
  drm/amdgpu: expand cg_flags from u32 to u64

Evgenii Krasnikov (1):
  drm/amd/display: ensure PSR force_static flag can always be set

Felix Kuehling (4):
  drm/amdkfd: Improve concurrency of event handling
  drm/amdkfd: Fix NULL pointer dereference
  drm/amdkfd: Asynchronously free events
  drm/amdkfd: fix race condition in kfd_wait_on_events

Gavin Wan (1)

[PATCH v2 0/2] drm/vkms: check plane_composer->map[0] before using it

2022-04-15 Thread Tales Lelo da Aparecida
Hi, this is a follow-up of my last patch. Thanks for the reviews!

Changes from v1:

Edit the first commit message as suggested by Melissa and add a commit to 
enhance the
error handling (André)

Tales Lelo da Aparecida (2):
  drm/vkms: check plane_composer->map[0] before using it
  drm/vkms: return early if compose_plane fails

 drivers/gpu/drm/vkms/vkms_composer.c | 32 ++--
 1 file changed, 21 insertions(+), 11 deletions(-)

-- 
2.35.1



[PATCH v2 1/2] drm/vkms: check plane_composer->map[0] before using it

2022-04-15 Thread Tales Lelo da Aparecida
Fix a copypasta error. The caller of compose_plane() already checks
primary_composer->map. In contrast, plane_composer->map is never
verified here before handling.

Fixes: 7938f4218168 ("dma-buf-map: Rename to iosys-map")
Reviewed-by: André Almeida 
Signed-off-by: Tales Lelo da Aparecida 
---
v2: detail the commit message with more information

 drivers/gpu/drm/vkms/vkms_composer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index c6a1036bf2ea..b47ac170108c 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -157,7 +157,7 @@ static void compose_plane(struct vkms_composer 
*primary_composer,
void *vaddr;
void (*pixel_blend)(const u8 *p_src, u8 *p_dst);
 
-   if (WARN_ON(iosys_map_is_null(&primary_composer->map[0])))
+   if (WARN_ON(iosys_map_is_null(&plane_composer->map[0])))
return;
 
vaddr = plane_composer->map[0].vaddr;
-- 
2.35.1



[PATCH v2 2/2] drm/vkms: return early if compose_plane fails

2022-04-15 Thread Tales Lelo da Aparecida
Do not exit quietly from compose_plane. If any plane has an invalid
map, propagate the error value upwards. While here, add log messages
for the invalid index.

Signed-off-by: Tales Lelo da Aparecida 
---
 drivers/gpu/drm/vkms/vkms_composer.c | 30 ++--
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index b47ac170108c..c0a3b53cd155 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -149,16 +149,16 @@ static void blend(void *vaddr_dst, void *vaddr_src,
}
 }
 
-static void compose_plane(struct vkms_composer *primary_composer,
- struct vkms_composer *plane_composer,
- void *vaddr_out)
+static int compose_plane(struct vkms_composer *primary_composer,
+struct vkms_composer *plane_composer,
+void *vaddr_out)
 {
struct drm_framebuffer *fb = &plane_composer->fb;
void *vaddr;
void (*pixel_blend)(const u8 *p_src, u8 *p_dst);
 
if (WARN_ON(iosys_map_is_null(&plane_composer->map[0])))
-   return;
+   return -EINVAL;
 
vaddr = plane_composer->map[0].vaddr;
 
@@ -168,6 +168,8 @@ static void compose_plane(struct vkms_composer 
*primary_composer,
pixel_blend = &x_blend;
 
blend(vaddr_out, vaddr, primary_composer, plane_composer, pixel_blend);
+
+   return 0;
 }
 
 static int compose_active_planes(void **vaddr_out,
@@ -177,7 +179,7 @@ static int compose_active_planes(void **vaddr_out,
struct drm_framebuffer *fb = &primary_composer->fb;
struct drm_gem_object *gem_obj = drm_gem_fb_get_obj(fb, 0);
const void *vaddr;
-   int i;
+   int i, ret;
 
if (!*vaddr_out) {
*vaddr_out = kzalloc(gem_obj->size, GFP_KERNEL);
@@ -187,8 +189,10 @@ static int compose_active_planes(void **vaddr_out,
}
}
 
-   if (WARN_ON(iosys_map_is_null(&primary_composer->map[0])))
+   if (WARN_ON(iosys_map_is_null(&primary_composer->map[0]))) {
+   DRM_DEBUG_DRIVER("Failed to compose. Invalid map in the primary 
plane.");
return -EINVAL;
+   }
 
vaddr = primary_composer->map[0].vaddr;
 
@@ -198,10 +202,16 @@ static int compose_active_planes(void **vaddr_out,
 * planes should be in z-order and compose them associatively:
 * ((primary <- overlay) <- cursor)
 */
-   for (i = 1; i < crtc_state->num_active_planes; i++)
-   compose_plane(primary_composer,
- crtc_state->active_planes[i]->composer,
- *vaddr_out);
+   for (i = 1; i < crtc_state->num_active_planes; i++) {
+   ret = compose_plane(primary_composer,
+   crtc_state->active_planes[i]->composer,
+   *vaddr_out);
+   if (ret) {
+   DRM_DEBUG_DRIVER("Failed to compose. Invalid map in the 
active_planes[%d].",
+i);
+   return ret;
+   }
+   }
 
return 0;
 }
-- 
2.35.1



[PATCH v6] drm/msm/dp: stop event kernel thread when DP unbind

2022-04-15 Thread Kuogee Hsieh
Current DP driver implementation, event thread is kept running
after DP display is unbind. This patch fix this problem by disabling
DP irq and stop event thread to exit gracefully at dp_display_unbind().

Changes in v2:
-- start event thread at dp_display_bind()

Changes in v3:
-- disable all HDP interrupts at unbind
-- replace dp_hpd_event_setup() with dp_hpd_event_thread_start()
-- replace dp_hpd_event_stop() with dp_hpd_event_thread_stop()
-- move init_waitqueue_head(&dp->event_q) to probe()
-- move spin_lock_init(&dp->event_lock) to probe()

Changes in v4:
-- relocate both dp_display_bind() and dp_display_unbind() to bottom of file

Changes in v5:
-- cancel relocation of both dp_display_bind() and dp_display_unbind()

Changes in v5:
-- move empty event q to dp_event_thread_start()

Fixes: e91e3065a806 ("drm/msm/dp: Add DP compliance tests on Snapdragon 
Chipsets")
Signed-off-by: Kuogee Hsieh 
Reported-by: Dmitry Baryshkov 
Reviewed-by: Stephen Boyd 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 35 ---
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 01453db..92c9819 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -113,6 +113,7 @@ struct dp_display_private {
u32 hpd_state;
u32 event_pndx;
u32 event_gndx;
+   struct task_struct *ev_tsk;
struct dp_event event_list[DP_EVENT_Q_MAX];
spinlock_t event_lock;
 
@@ -230,6 +231,14 @@ void dp_display_signal_audio_complete(struct msm_dp 
*dp_display)
complete_all(&dp->audio_comp);
 }
 
+static void dp_hpd_event_thread_stop(struct dp_display_private *dp_priv)
+{
+   kthread_stop(dp_priv->ev_tsk);
+
+}
+
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
+
 static int dp_display_bind(struct device *dev, struct device *master,
   void *data)
 {
@@ -269,6 +278,7 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
if (rc)
DRM_ERROR("Audio registration Dp failed\n");
 
+   rc = dp_hpd_event_thread_start(dp);
 end:
return rc;
 }
@@ -280,6 +290,9 @@ static void dp_display_unbind(struct device *dev, struct 
device *master,
struct drm_device *drm = dev_get_drvdata(master);
struct msm_drm_private *priv = drm->dev_private;
 
+   /* disable all HPD interrupts */
+   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
+   dp_hpd_event_thread_stop(dp);
dp_power_client_deinit(dp->power);
dp_aux_unregister(dp->aux);
priv->dp[dp->id] = NULL;
@@ -1054,7 +1067,7 @@ static int hpd_event_thread(void *data)
 
dp_priv = (struct dp_display_private *)data;
 
-   while (1) {
+   while (!kthread_should_stop()) {
if (timeout_mode) {
wait_event_timeout(dp_priv->event_q,
(dp_priv->event_pndx == dp_priv->event_gndx),
@@ -1132,12 +1145,19 @@ static int hpd_event_thread(void *data)
return 0;
 }
 
-static void dp_hpd_event_setup(struct dp_display_private *dp_priv)
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)
 {
-   init_waitqueue_head(&dp_priv->event_q);
-   spin_lock_init(&dp_priv->event_lock);
+   /* set event q to empty */
+   dp_priv->event_gndx = 0;
+   dp_priv->event_pndx = 0;
+
+   dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, 
"dp_hpd_handler");
+   if (IS_ERR(dp_priv->ev_tsk)) {
+   DRM_ERROR("failed to create DP event thread\n");
+   return PTR_ERR(dp_priv->ev_tsk);
+   }
 
-   kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");
+   return 0;
 }
 
 static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
@@ -1266,7 +1286,10 @@ static int dp_display_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
 
+   /* setup event q */
mutex_init(&dp->event_mutex);
+   init_waitqueue_head(&dp->event_q);
+   spin_lock_init(&dp->event_lock);
 
/* Store DP audio handle inside DP display */
dp->dp_display.dp_audio = dp->audio;
@@ -1441,8 +1464,6 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
 
dp = container_of(dp_display, struct dp_display_private, dp_display);
 
-   dp_hpd_event_setup(dp);
-
dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2 5/7] drm: rcar-du: Factorise rcar_du_{atomic_check,modeset_init}

2022-04-15 Thread Laurent Pinchart
Hi Biju,

Thank you for the patch.

On Wed, Mar 16, 2022 at 01:10:58PM +, Biju Das wrote:
> RZ/G2L SoC's does not have group/plane registers compared to RCar, hence it
> needs a different CRTC implementation. Factorise rcar_du_{atomic_check,
> modeset_init} by adding struct rcar_du_crtc_helper_funcs to struct
> rcar_du_device_info, so that it can support RZ/G2L SoC without any code
> changes.

I'd like to go the other way around. Instead of adding a layer of
indirection in the DU driver, could you create a new DRM driver, and
share common code with the DU driver ?

> Signed-off-by: Biju Das 
> ---
> v1->v2:
>  * Changed crtc_helper_funcs->rcar_crtc_helper_funcs
> RFC->v1:
>  * New patch
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c | 24 
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h | 16 
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c |  6 +++---
>  3 files changed, 43 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index f6e234dafb72..0df1430b9664 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -34,6 +34,12 @@
>   * Device Information
>   */
>  
> +static struct rcar_du_crtc_helper_funcs rcar_crtc_helper_funcs = {
> + .du_planes_init = rcar_du_planes_init,
> + .du_crtc_create = rcar_du_crtc_create,
> + .du_atomic_check_planes = rcar_du_atomic_check_planes,
> +};
> +
>  static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
>   .gen = 2,
>   .features = RCAR_DU_FEATURE_CRTC_IRQ
> @@ -58,6 +64,7 @@ static const struct rcar_du_device_info 
> rzg1_du_r8a7743_info = {
>   .num_rpf = 4,
>   .max_width = 4095,
>   .max_height = 2047,
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
> @@ -83,6 +90,7 @@ static const struct rcar_du_device_info 
> rzg1_du_r8a7745_info = {
>   .num_rpf = 4,
>   .max_width = 4095,
>   .max_height = 2047,
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static const struct rcar_du_device_info rzg1_du_r8a77470_info = {
> @@ -113,6 +121,7 @@ static const struct rcar_du_device_info 
> rzg1_du_r8a77470_info = {
>   .num_rpf = 4,
>   .max_width = 4095,
>   .max_height = 2047,
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a774a1_info = {
> @@ -146,6 +155,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774a1_info = {
>   .max_width = 8190,
>   .max_height = 8190,
>   .dpll_mask =  BIT(1),
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a774b1_info = {
> @@ -179,6 +189,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774b1_info = {
>   .max_width = 8190,
>   .max_height = 8190,
>   .dpll_mask =  BIT(1),
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a774c0_info = {
> @@ -209,6 +220,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774c0_info = {
>   .max_width = 8190,
>   .max_height = 8190,
>   .lvds_clk_mask =  BIT(1) | BIT(0),
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a774e1_info = {
> @@ -242,6 +254,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a774e1_info = {
>   .max_width = 8190,
>   .max_height = 8190,
>   .dpll_mask =  BIT(1),
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7779_info = {
> @@ -265,6 +278,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7779_info = {
>   },
>   .max_width = 4095,
>   .max_height = 2047,
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7790_info = {
> @@ -298,6 +312,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7790_info = {
>   .num_rpf = 4,
>   .max_width = 4095,
>   .max_height = 2047,
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  /* M2-W (r8a7791) and M2-N (r8a7793) are identical */
> @@ -326,6 +341,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7791_info = {
>   .num_rpf = 4,
>   .max_width = 4095,
>   .max_height = 2047,
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7792_info = {
> @@ -349,6 +365,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7792_info = {
>   .num_rpf = 4,
>   .max_width = 4095,
>   .max_height = 2047,
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static const struct rcar_du_device_info rcar_du_r8a7794_info = {
> @@ -375,6 +392,7 @@ static const struct rcar_du_device_info 
> rcar_du_r8a7794_info = {
>   .num_rpf = 4,
>   .max_width = 4095,
>   .max_height = 2047,
> + .fns = &rcar_crtc_helper_funcs,
>  };
>  
>  static cons

[PATCH v2 0/2] drm/vc4: hdmi: Replace drm_detect_hdmi_monitor() with drm_display_info.is_hdmi

2022-04-15 Thread José Expósito
Hi everyone,

These patches replace the calls to drm_detect_hdmi_monitor() with the
more efficient drm_display_info.is_hdmi in the VC4 driver.

As I mentioned in v1, vc4_hdmi_encoder.hdmi_monitor (removed by this
series) is used by some code not present in the mainline kernel but
present in the Raspberry Pi tree [1].
Let me know if you want me to open a PR in the Raspberry Pi kernel
project applying this series and fixing this issue.

Thanks,
José Expósito

[1] 
https://github.com/raspberrypi/linux/blob/rpi-5.15.y/drivers/gpu/drm/vc4/vc4_firmware_kms.c#L1410

v1: 
https://lore.kernel.org/dri-devel/20220406165514.6106-1-jose.exposit...@gmail.com/

v2: Add the ftrace command used in the first patch
Remove vc4_hdmi_encoder.hdmi_monitor
(Thanks to Maxime for suggesting these changes)

José Expósito (2):
  drm/vc4: hdmi: Replace drm_detect_hdmi_monitor() with is_hdmi
  drm/vc4: hdmi: Remove vc4_hdmi_encoder.hdmi_monitor

 drivers/gpu/drm/vc4/vc4_hdmi.c | 17 ++---
 drivers/gpu/drm/vc4/vc4_hdmi.h |  1 -
 2 files changed, 6 insertions(+), 12 deletions(-)

-- 
2.25.1



[PATCH v2 1/2] drm/vc4: hdmi: Replace drm_detect_hdmi_monitor() with is_hdmi

2022-04-15 Thread José Expósito
Once EDID is parsed, the monitor HDMI support information is cached in
drm_display_info.is_hdmi by drm_parse_hdmi_vsdb_video().

This driver calls drm_detect_hdmi_monitor() to receive the same
information and stores its own cached value, which is less efficient.

Avoid calling drm_detect_hdmi_monitor() and use drm_display_info.is_hdmi
instead.

drm_detect_hdmi_monitor() is called in vc4_hdmi_connector_detect() and
vc4_hdmi_connector_get_modes(). In both cases it is safe to rely on
drm_display_info.is_hdmi as shown by ftrace:

$ sudo trace-cmd record -p function_graph -l "vc4_hdmi_*" -l "drm_*"

vc4_hdmi_connector_detect:

vc4_hdmi_connector_detect() {
  drm_get_edid() {
drm_connector_update_edid_property() {
  drm_add_display_info() {
drm_reset_display_info();
drm_for_each_detailed_block.part.0();
drm_parse_cea_ext() {
  drm_find_cea_extension();
  drm_parse_hdmi_vsdb_video();
  /* drm_display_info.is_hdmi is cached here */
}
  }
}
  }
  /* drm_display_info.is_hdmi is used here */
}

vc4_hdmi_connector_get_modes:

vc4_hdmi_connector_get_modes() {
  drm_get_edid() {
drm_connector_update_edid_property() {
  drm_add_display_info() {
drm_reset_display_info();
drm_for_each_detailed_block.part.0();
drm_parse_cea_ext() {
  drm_find_cea_extension();
  drm_parse_hdmi_vsdb_video();
  /* drm_display_info.is_hdmi is cached here */
}
  }
}
  }
  /* drm_display_info.is_hdmi is used here */
  drm_connector_update_edid_property();
}

Signed-off-by: José Expósito 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 6c58b0fd13fb..ecdb1ffc2023 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -216,7 +216,7 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, 
bool force)
 
if (edid) {
cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, 
edid);
-   vc4_hdmi->encoder.hdmi_monitor = 
drm_detect_hdmi_monitor(edid);
+   vc4_hdmi->encoder.hdmi_monitor = 
connector->display_info.is_hdmi;
kfree(edid);
}
}
@@ -255,7 +255,7 @@ static int vc4_hdmi_connector_get_modes(struct 
drm_connector *connector)
goto out;
}
 
-   vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
+   vc4_encoder->hdmi_monitor = connector->display_info.is_hdmi;
 
drm_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
-- 
2.25.1



[PATCH v2 2/2] drm/vc4: hdmi: Remove vc4_hdmi_encoder.hdmi_monitor

2022-04-15 Thread José Expósito
The vc4_hdmi_encoder.hdmi_monitor field was used to cache the value
returned by drm_detect_hdmi_monitor() in order to avoid calling it
multiple times.

Now that drm_detect_hdmi_monitor() has been replaced with
drm_display_info.is_hdmi, there is no need to cache it in the driver
encoder struct.

Remove vc4_hdmi_encoder.hdmi_monitor and use drm_display_info.is_hdmi
instead.

Signed-off-by: José Expósito 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 17 ++---
 drivers/gpu/drm/vc4/vc4_hdmi.h |  1 -
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index ecdb1ffc2023..9c73a211ae80 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -107,9 +107,9 @@ static bool vc4_hdmi_mode_needs_scrambling(const struct 
drm_display_mode *mode)
 static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi,
   const struct drm_display_mode *mode)
 {
-   struct vc4_hdmi_encoder *vc4_encoder = &vc4_hdmi->encoder;
+   struct drm_display_info *display = &vc4_hdmi->connector.display_info;
 
-   return !vc4_encoder->hdmi_monitor ||
+   return !display->is_hdmi ||
drm_default_rgb_quant_range(mode) == 
HDMI_QUANTIZATION_RANGE_FULL;
 }
 
@@ -216,7 +216,6 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, 
bool force)
 
if (edid) {
cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, 
edid);
-   vc4_hdmi->encoder.hdmi_monitor = 
connector->display_info.is_hdmi;
kfree(edid);
}
}
@@ -242,7 +241,6 @@ static void vc4_hdmi_connector_destroy(struct drm_connector 
*connector)
 static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
 {
struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
-   struct vc4_hdmi_encoder *vc4_encoder = &vc4_hdmi->encoder;
int ret = 0;
struct edid *edid;
 
@@ -255,8 +253,6 @@ static int vc4_hdmi_connector_get_modes(struct 
drm_connector *connector)
goto out;
}
 
-   vc4_encoder->hdmi_monitor = connector->display_info.is_hdmi;
-
drm_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
kfree(edid);
@@ -578,13 +574,12 @@ static void vc4_hdmi_set_infoframes(struct drm_encoder 
*encoder)
 static bool vc4_hdmi_supports_scrambling(struct drm_encoder *encoder,
 struct drm_display_mode *mode)
 {
-   struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
struct drm_display_info *display = &vc4_hdmi->connector.display_info;
 
lockdep_assert_held(&vc4_hdmi->mutex);
 
-   if (!vc4_encoder->hdmi_monitor)
+   if (!display->is_hdmi)
return false;
 
if (!display->hdmi.scdc.supported ||
@@ -1147,7 +1142,7 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct 
drm_encoder *encoder,
 {
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
-   struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
+   struct drm_display_info *display = &vc4_hdmi->connector.display_info;
bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
unsigned long flags;
@@ -1168,7 +1163,7 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct 
drm_encoder *encoder,
HDMI_WRITE(HDMI_VID_CTL,
   HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_BLANKPIX);
 
-   if (vc4_encoder->hdmi_monitor) {
+   if (display->is_hdmi) {
HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
   HDMI_READ(HDMI_SCHEDULER_CONTROL) |
   VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
@@ -1195,7 +1190,7 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct 
drm_encoder *encoder,
  "!VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
}
 
-   if (vc4_encoder->hdmi_monitor) {
+   if (display->is_hdmi) {
spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 
WARN_ON(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 1076faeab616..44977002445f 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -11,7 +11,6 @@
 /* VC4 HDMI encoder KMS struct */
 struct vc4_hdmi_encoder {
struct vc4_encoder base;
-   bool hdmi_monitor;
 };
 
 static inline struct vc4_hdmi_encoder *
-- 
2.25.1



[Bug 215839] New: distorted video playback with hybrid GPU (DRI_PRIME=1, Radeon HD 6470M and Intel-GPU)

2022-04-15 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215839

Bug ID: 215839
   Summary: distorted video playback with hybrid GPU (DRI_PRIME=1,
Radeon HD 6470M and Intel-GPU)
   Product: Drivers
   Version: 2.5
Kernel Version: 5.15.28
  Hardware: All
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: kolafl...@kolahilft.de
Regression: No

At least Kodi and VLC show garbage when being run with DRI_PRIME=1

I guess this is either a bug in the "radeon" kernel module or in Mesa3D /
Gallium.



Hardware:
HP Notebook
Product: LR294EA#ABD
Model: Pavilion g6-1024sg
CPU + integrated graphics: Intel® Core™ i5 ("i915" driver)
Dedicated GPU: Radeon HD 6470M ("radeon" driver)
https://icecat.biz/de-at/p/hp/lr294ea/pavilion-notebooks-0886111633067-g6-1024sg-8025113.html

OS:
Tested Debian-11 (Linux-5.10.106)
manjaro-xfce-21.2.5-minimal-220314-linux515.iso (Linux-5.15.28)
(both running X)

$ cat /sys/kernel/debug/vgaswitcheroo/switch
0:DIS: :DynOff::01:00.0
1:IGD:+:Pwr::00:02.0

Console output (both VLC and Kodi):
radeon: The kernel rejected CS, see dmesg for more information (-22).

dmesg:
[ 2210.372308] radeon :01:00.0: evergreen_surface_check_linear_aligned:214
texture pitch 1920 invalid must be aligned with 256
[ 2210.372320] radeon :01:00.0: evergreen_cs_track_validate_texture:829
texture invalid 0x1dfc3bc1 0x1437 0x0b20 0x 0x
0x80020001
[ 2210.372327] [drm:radeon_cs_ioctl [radeon]] *ERROR* Invalid command stream !



I connected an external full HD (1920x1080) monitor and disabled the notebooks
internal monitor via xrandr.
(especially in Kodi you may not be able to reproduce slow rendering without an
1920x1080 monitor)
(I want to use the notebook as media computer for my TV)

When running Kodi-19.4 or VLC-3.0.17.3 without specific settings, full HD
(1920x1080 H264) videos don't render smoothly.
On Debian-11 additionally Firefox-ESR-91.8 also becomes slow (all CPU cores
under heavy load) when playing full HD videos with JavaScript controls.
Try these:
https://www.ardmediathek.de/video/seehund-puma-und-co/fuenf-mann-ueber-bord-215/das-erste/Y3JpZDovL2Rhc2Vyc3RlLmRlL3NlZWh1bmQsIHB1bWEgJmFtcDsgY28uLzI1MDdkNTZlLWI0ZjYtNDAxNS1iYTI1LTE1N2FjOWNjZTE3NA
https://pdvideosdaserste-a.akamaihd.net/int/2021/06/10/6528b8d0-72d0-45b4-9e7c-29dce5bb796a/1920-1_917111.mp4
(caution: baby seals shown compete hard with baby kittens ;-))
In Kodi install the "ARDundZDF" add-on from repo.kodinerds.net and open:
ARDundZDF -> TV-Livestreams -> Überregional (second option) -> Das Erste ->
1920x1080



To solve this for Firefox I simply added "export DRI_PRIME=1" to ~/.profile
Now Firefox-ESR-91.8 on Debian-11 works fine!
But the issue wasn't fixed for Kodi and VLC. Instead they now show complete
garbage :-(

For VLC I was able to nail down the problem:
When running VLC without specific settings, video output "OpenGL" and decoding
via "VA-API" (without DRM) are being chosen.
So when running VLC with these settings and with DRI_PRIME=1 the output is
distorted.

So for VLC the workaround is pretty easy:
Choose any other video decoder (VDPAU, "VA-API video decoder via DRM" or simply
"Disable").
In this case the video will playback fine and smooth with and without setting
DRI_PRIME=1.
Some other video output methods like "XVideo output (XCB)" also solve the
problem while keeping VA-API as video decoder. Actually I also reported a bug
to VLC about the questionable default settings:
https://code.videolan.org/videolan/vlc/-/issues/26831

Until now I found no solution for Kodi!



= Notes =

ffplay renders smoothly without further settings. (with and without
DRI_PRIME=1)

Maybe related:
https://bugzilla.kernel.org/show_bug.cgi?id=89331

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[PATCH 2/2] drm/panel/raspberrypi-touchscreen: Initialise the bridge in prepare

2022-04-15 Thread Stefan Wahren
From: Dave Stevenson 

The panel has a prepare call which is before video starts, and an
enable call which is after.
The Toshiba bridge should be configured before video, so move
the relevant power and initialisation calls to prepare.

Fixes: 2f733d6194bd ("drm/panel: Add support for the Raspberry Pi 7" 
Touchscreen.")
Signed-off-by: Dave Stevenson 
Signed-off-by: Stefan Wahren 
---
 drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c 
b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
index 1f805eb8fdb5..145047e19394 100644
--- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
+++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
@@ -265,7 +265,7 @@ static int rpi_touchscreen_noop(struct drm_panel *panel)
return 0;
 }
 
-static int rpi_touchscreen_enable(struct drm_panel *panel)
+static int rpi_touchscreen_prepare(struct drm_panel *panel)
 {
struct rpi_touchscreen *ts = panel_to_ts(panel);
int i;
@@ -295,6 +295,13 @@ static int rpi_touchscreen_enable(struct drm_panel *panel)
rpi_touchscreen_write(ts, DSI_STARTDSI, 0x01);
msleep(100);
 
+   return 0;
+}
+
+static int rpi_touchscreen_enable(struct drm_panel *panel)
+{
+   struct rpi_touchscreen *ts = panel_to_ts(panel);
+
/* Turn on the backlight. */
rpi_touchscreen_i2c_write(ts, REG_PWM, 255);
 
@@ -349,7 +356,7 @@ static int rpi_touchscreen_get_modes(struct drm_panel 
*panel,
 static const struct drm_panel_funcs rpi_touchscreen_funcs = {
.disable = rpi_touchscreen_disable,
.unprepare = rpi_touchscreen_noop,
-   .prepare = rpi_touchscreen_noop,
+   .prepare = rpi_touchscreen_prepare,
.enable = rpi_touchscreen_enable,
.get_modes = rpi_touchscreen_get_modes,
 };
-- 
2.25.1



[PATCH 0/2] drm/panel/raspberrypi-touchscreen: Fix minor issues

2022-04-15 Thread Stefan Wahren
This small patch series tries to upstream 2 minor issues which has been
fixed in the vendor tree by Dave Stevenson.

Dave Stevenson (2):
  drm/panel/raspberrypi-touchscreen: Avoid NULL deref if not initialised
  drm/panel/raspberrypi-touchscreen: Initialise the bridge in prepare

 .../gpu/drm/panel/panel-raspberrypi-touchscreen.c   | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

-- 
2.25.1



[PATCH 1/2] drm/panel/raspberrypi-touchscreen: Avoid NULL deref if not initialised

2022-04-15 Thread Stefan Wahren
From: Dave Stevenson 

If a call to rpi_touchscreen_i2c_write from rpi_touchscreen_probe
fails before mipi_dsi_device_register_full is called, then
in trying to log the error message if uses ts->dsi->dev when
it is still NULL.

Use ts->i2c->dev instead, which is initialised earlier in probe.

Fixes: 2f733d6194bd ("drm/panel: Add support for the Raspberry Pi 7" 
Touchscreen.")
Signed-off-by: Dave Stevenson 
Signed-off-by: Stefan Wahren 
---
 drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c 
b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
index 46029c5610c8..1f805eb8fdb5 100644
--- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
+++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
@@ -229,7 +229,7 @@ static void rpi_touchscreen_i2c_write(struct 
rpi_touchscreen *ts,
 
ret = i2c_smbus_write_byte_data(ts->i2c, reg, val);
if (ret)
-   dev_err(&ts->dsi->dev, "I2C write failed: %d\n", ret);
+   dev_err(&ts->i2c->dev, "I2C write failed: %d\n", ret);
 }
 
 static int rpi_touchscreen_write(struct rpi_touchscreen *ts, u16 reg, u32 val)
-- 
2.25.1



[Bug 215839] distorted video playback with hybrid GPU (DRI_PRIME=1, Radeon HD 6470M and Intel-GPU)

2022-04-15 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215839

Alex Deucher (alexdeuc...@gmail.com) changed:

   What|Removed |Added

 CC||alexdeuc...@gmail.com

--- Comment #1 from Alex Deucher (alexdeuc...@gmail.com) ---
This is a mesa bug.  I'd suggest filing a bug here:
https://gitlab.freedesktop.org/groups/mesa/-/issues
There is either a memory alignment bug in the r600 mesa driver or the intel
mesa driver is not allocating memory with the proper alignment requirements for
the radeon hardware so when the radeon driver tries to use the buffer the
commands get rejected causing the image distortions.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 215839] distorted video playback with hybrid GPU (DRI_PRIME=1, Radeon HD 6470M and Intel-GPU)

2022-04-15 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215839

--- Comment #2 from kolAflash (kolafl...@kolahilft.de) ---
Thanks for your assessment Alex!

Here is the Mesa bug:
https://gitlab.freedesktop.org/mesa/mesa/-/issues/6326
I can only set the status of this kernel.org bug to "resolved". But I guess it
should be "invalid" or something else!?

I also found a workaround for Kodi:
Settings -> Player
Set UI mode to >= Advanced
Under "Videos" disable
  "Allow hardware acceleration - VAAPI"
Then Kodi will work fine with DRI_PRIME=1
Interestingly even without DRI_PRIME=1 full HD videos now play smooth too.
(maybe Kodi should leave VAAPI disabled by default...)

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[PATCH] drm/amd/display: make hubp1_wait_pipe_read_start() static

2022-04-15 Thread Tales Lelo da Aparecida
It's a local function, let's make it static.

Signed-off-by: Tales Lelo da Aparecida 
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index fbff6beb78be..3a7f76e2c598 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -1316,7 +1316,7 @@ void hubp1_set_flip_int(struct hubp *hubp)
  *
  * @hubp: hubp struct reference.
  */
-void hubp1_wait_pipe_read_start(struct hubp *hubp)
+static void hubp1_wait_pipe_read_start(struct hubp *hubp)
 {
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 
-- 
2.35.1



[PATCH] drm/msm: remove unused hotplug and edid macros from msm_drv.h

2022-04-15 Thread Abhinav Kumar
Remove unused MSM_DISPLAY_CAP_HOT_PLUG and MSM_DISPLAY_CAP_EDID
macros from msm_drv.h.

Even if we need these, there are drm equivalent ones present.

Reported-by: Dmitry Baryshkov 
Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/msm_drv.h | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 9f68aa6..17de795 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -74,14 +74,10 @@ enum msm_dp_controller {
  * enum msm_display_caps - features/capabilities supported by displays
  * @MSM_DISPLAY_CAP_VID_MODE:   Video or "active" mode supported
  * @MSM_DISPLAY_CAP_CMD_MODE:   Command mode supported
- * @MSM_DISPLAY_CAP_HOT_PLUG:   Hot plug detection supported
- * @MSM_DISPLAY_CAP_EDID:   EDID supported
  */
 enum msm_display_caps {
MSM_DISPLAY_CAP_VID_MODE= BIT(0),
MSM_DISPLAY_CAP_CMD_MODE= BIT(1),
-   MSM_DISPLAY_CAP_HOT_PLUG= BIT(2),
-   MSM_DISPLAY_CAP_EDID= BIT(3),
 };
 
 /**
-- 
2.7.4



Re: [Freedreno] [PATCH 06/12] drm/msm/dpu: make changes to dpu_encoder to support virtual encoder

2022-04-15 Thread Abhinav Kumar

Hi Marijn

Looking at msm-next tip, this code has already been refactored in

https://gitlab.freedesktop.org/drm/msm/-/commit/ef58e0ad34365e2c8274b74e6e745b8c180ff0d3

So, I will just rebase my changes on msm-next tip and it should address 
below comments as well.



Thanks

Abhinav
On 4/14/2022 3:30 PM, Abhinav Kumar wrote:

Hi Marijn

Thank you for your suggestion.
I will address it and add your "Reported by".

Thanks

Abhinav

On 4/14/2022 3:26 PM, Marijn Suijten wrote:

On 2022-02-04 13:17:19, Abhinav Kumar wrote:

Make changes to dpu_encoder to support virtual encoder needed
to support writeback for dpu.

Signed-off-by: Abhinav Kumar 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 57 
+

  1 file changed, 42 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index e977c05..947069b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -974,6 +974,7 @@ static void dpu_encoder_virt_mode_set(struct 
drm_encoder *drm_enc,

  struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
  struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
  struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
+    enum dpu_hw_blk_type blk_type;
  int num_lm, num_ctl, num_pp;
  int i, j;
@@ -1061,20 +1062,36 @@ static void dpu_encoder_virt_mode_set(struct 
drm_encoder *drm_enc,

  phys->hw_pp = dpu_enc->hw_pp[i];
  phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
+    if (phys->intf_mode == INTF_MODE_WB_LINE)
+    blk_type = DPU_HW_BLK_WB;
+    else
+    blk_type = DPU_HW_BLK_INTF;
+
  num_blk = dpu_rm_get_assigned_resources(&dpu_kms->rm,
-    global_state, drm_enc->base.id, DPU_HW_BLK_INTF,
+    global_state, drm_enc->base.id, blk_type,
  hw_blk, ARRAY_SIZE(hw_blk));
-    for (j = 0; j < num_blk; j++) {
-    struct dpu_hw_intf *hw_intf;
-    hw_intf = to_dpu_hw_intf(hw_blk[i]);
-    if (hw_intf->idx == phys->intf_idx)
-    phys->hw_intf = hw_intf;
+    if (blk_type == DPU_HW_BLK_WB) {
+    for (j = 0; j < num_blk; j++) {
+    struct dpu_hw_wb *hw_wb;
+
+    hw_wb = to_dpu_hw_wb(hw_blk[i]);
+    if (hw_wb->idx == phys->intf_idx)
+    phys->hw_wb = hw_wb;
+    }
+    } else {
+    for (j = 0; j < num_blk; j++) {
+    struct dpu_hw_intf *hw_intf;
+
+    hw_intf = to_dpu_hw_intf(hw_blk[i]);
+    if (hw_intf->idx == phys->intf_idx)
+    phys->hw_intf = hw_intf;
+    }


It appears the original bit of code iterates j from 0 to num_blks yet
only uses i as iteration value.  All of this code seems reentrant
meaning that executing it more than one times is redundant.  You've
adopted this mistake, though I'd argue it should use j in hw_blk[i] as
that follows the number of elements in hw_blk returned by
dpu_rm_get_assigned_resources.

I suggest to address this in a separate patch (I can send that too, feel
free to add my Reported-by otherwise) and rebase this patch on top of
that, substituting i with j here as well.  It seems to have been
introduced by b954fa6baaca ("drm/msm/dpu: Refactor rm iterator").

- Marijn


  }
-    if (!phys->hw_intf) {
+    if (!phys->hw_intf && !phys->hw_wb) {
  DPU_ERROR_ENC(dpu_enc,
-  "no intf block assigned at idx: %d\n", i);
+  "no intf or WB block assigned at idx: %d\n", i);
  return;
  }
@@ -1224,15 +1241,22 @@ static void dpu_encoder_virt_disable(struct 
drm_encoder *drm_enc)

  mutex_unlock(&dpu_enc->enc_lock);
  }
-static enum dpu_intf dpu_encoder_get_intf(struct dpu_mdss_cfg *catalog,
+static enum dpu_intf dpu_encoder_get_intf_or_wb(struct dpu_mdss_cfg 
*catalog,

  enum dpu_intf_type type, u32 controller_id)
  {
  int i = 0;
-    for (i = 0; i < catalog->intf_count; i++) {
-    if (catalog->intf[i].type == type
-    && catalog->intf[i].controller_id == controller_id) {
-    return catalog->intf[i].id;
+    if (type != INTF_WB) {
+    for (i = 0; i < catalog->intf_count; i++) {
+    if (catalog->intf[i].type == type
+    && catalog->intf[i].controller_id == controller_id) {
+    return catalog->intf[i].id;
+    }
+    }
+    } else {
+    for (i = 0; i < catalog->wb_count; i++) {
+    if (catalog->wb[i].id == controller_id)
+    return catalog->wb[i].id;
  }
  }
@@ -2096,6 +2120,9 @@ static int dpu_encoder_setup_display(struct 
dpu_encoder_virt *dpu_enc,

  case DRM_MODE_ENCODER_TMDS:
  intf_type = INTF_DP;
  break;
+    case DRM_MODE_ENCODER_VIRTUAL:
+    intf_type = INTF_WB;
+    break;
  }
  WARN_ON(disp_info->num_of_h_tile

Re: [PATCH] drm/msm: remove unused hotplug and edid macros from msm_drv.h

2022-04-15 Thread Stephen Boyd
Quoting Abhinav Kumar (2022-04-15 12:09:42)
> Remove unused MSM_DISPLAY_CAP_HOT_PLUG and MSM_DISPLAY_CAP_EDID
> macros from msm_drv.h.
>
> Even if we need these, there are drm equivalent ones present.
>
> Reported-by: Dmitry Baryshkov 
> Signed-off-by: Abhinav Kumar 
> ---

Reviewed-by: Stephen Boyd 


Re: [PATCH v6] drm/msm/dp: stop event kernel thread when DP unbind

2022-04-15 Thread Stephen Boyd
Quoting Kuogee Hsieh (2022-04-15 08:41:16)
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index 01453db..92c9819 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -230,6 +231,14 @@ void dp_display_signal_audio_complete(struct msm_dp 
> *dp_display)
> complete_all(&dp->audio_comp);
>  }
>
> +static void dp_hpd_event_thread_stop(struct dp_display_private *dp_priv)
> +{
> +   kthread_stop(dp_priv->ev_tsk);
> +
> +}
> +
> +static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
> +
>  static int dp_display_bind(struct device *dev, struct device *master,
>void *data)
>  {
> @@ -280,6 +290,9 @@ static void dp_display_unbind(struct device *dev, struct 
> device *master,
> struct drm_device *drm = dev_get_drvdata(master);
> struct msm_drm_private *priv = drm->dev_private;
>
> +   /* disable all HPD interrupts */
> +   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
> +   dp_hpd_event_thread_stop(dp);

It's a one line function. How about just

kthread_stop(dp->ev_tsk)

> dp_power_client_deinit(dp->power);
> dp_aux_unregister(dp->aux);
> priv->dp[dp->id] = NULL;


[PATCH 0/2] Update AMDGPU glossary and MAINTAINERS

2022-04-15 Thread Tales Lelo da Aparecida
I was handling the request from [0] and then I noticed that some AMD
developers were missing from get_maintainers output due to the lack of a
reference to their documentation in the MAINTAINERS file.

[0] https://gitlab.freedesktop.org/drm/amd/-/issues/1939#note_1309737

Tales Lelo da Aparecida (2):
  Documentation/gpu: Add entries to amdgpu glossary
  MAINTAINERS: add docs entry to AMDGPU

 Documentation/gpu/amdgpu/amdgpu-glossary.rst | 13 +
 MAINTAINERS  |  1 +
 2 files changed, 14 insertions(+)

-- 
2.35.1



[PATCH 1/2] Documentation/gpu: Add entries to amdgpu glossary

2022-04-15 Thread Tales Lelo da Aparecida
Add missing acronyms to the amdgppu glossary.

Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/1939#note_1309737
Signed-off-by: Tales Lelo da Aparecida 
---
 Documentation/gpu/amdgpu/amdgpu-glossary.rst | 13 +
 1 file changed, 13 insertions(+)

diff --git a/Documentation/gpu/amdgpu/amdgpu-glossary.rst 
b/Documentation/gpu/amdgpu/amdgpu-glossary.rst
index 859dcec6c6f9..48829d097f40 100644
--- a/Documentation/gpu/amdgpu/amdgpu-glossary.rst
+++ b/Documentation/gpu/amdgpu/amdgpu-glossary.rst
@@ -8,12 +8,19 @@ we have a dedicated glossary for Display Core at
 
 .. glossary::
 
+active_cu_number
+  The number of CUs that are active on the system.  The number of active
+  CUs may be less than SE * SH * CU depending on the board configuration.
+
 CP
   Command Processor
 
 CPLIB
   Content Protection Library
 
+CU
+  Compute unit
+
 DFS
   Digital Frequency Synthesizer
 
@@ -74,6 +81,12 @@ we have a dedicated glossary for Display Core at
 SDMA
   System DMA
 
+SE
+  Shader Engine
+
+SH
+  SHader array
+
 SMU
   System Management Unit
 
-- 
2.35.1



[PATCH 2/2] MAINTAINERS: add docs entry to AMDGPU

2022-04-15 Thread Tales Lelo da Aparecida
To make sure maintainers of amdgpu drivers are aware of any changes
 in their documentation, add its entry to MAINTAINERS.

Signed-off-by: Tales Lelo da Aparecida 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d54b9f15ffce..b3594b2a09de 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16449,6 +16449,7 @@ S:  Supported
 T: git https://gitlab.freedesktop.org/agd5f/linux.git
 B: https://gitlab.freedesktop.org/drm/amd/-/issues
 C: irc://irc.oftc.net/radeon
+F: Documentation/gpu/amdgpu/
 F: drivers/gpu/drm/amd/
 F: drivers/gpu/drm/radeon/
 F: include/uapi/drm/amdgpu_drm.h
-- 
2.35.1



[Bug 215842] New: PC freeze sidn kernel 5.17.x

2022-04-15 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215842

Bug ID: 215842
   Summary: PC freeze sidn kernel 5.17.x
   Product: Drivers
   Version: 2.5
Kernel Version: 5.17.3
  Hardware: Intel
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: blocking
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: andreykolt...@live.de
Regression: No

Hello,

the display of my PC freezes (i cant also go to thy tty and ssh also down). I
can always recreate this by going to https://github.com/jonaburg/picom and
scrolling to the video. I can only see this behavior since the update to
5.17.x. Firefox version 99.0.1 (64-bit) is used as the browser. When switching
to the LTS kernel, the problem disappears and the PC no longer freezes. This
was tested many times on my productive system. I also tried different WMs
(xmonad, qtile, KDE, i3) and switching the filesystem from btrfs to ext4 - but
the problem remained. The PC has a SWAP. The XORG version is X.Org X Server
1.21.1.3. This Problem is also reproduceable on Wayland. I tested also by
uninstall of picom and reinstall it etc.

This are my components:

Resolution: 2560x1440 
OS: Arch Linux x86_64 
CPU: Intel i5-6600K (4) @ 4.600GHz
GPU: Intel HD Graphics 530 
GPU: AMD ATI Radeon RX 470/480/570/570X/580/580X/590 
Memory: 1049MiB / 14947MiB

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [RFC PATCH 1/6] drm/dp: Helpers to make it easier for drivers to use DP AUX bus properly

2022-04-15 Thread Doug Anderson
Hi,

On Thu, Apr 14, 2022 at 4:52 PM Stephen Boyd  wrote:
>
> Quoting Douglas Anderson (2022-04-08 19:36:23)
> > As talked about in the kerneldoc for "struct dp_aux_ep_client" in this
> > patch and also in the past in commit a1e3667a9835 ("drm/bridge:
> > ti-sn65dsi86: Promote the AUX channel to its own sub-dev"), to use the
> > DP AUX bus properly we really need two "struct device"s. One "struct
> > device" is in charge of providing the DP AUX bus and the other is
> > where we'll try to get a reference to the newly probed endpoint
> > devices.
> >
> > In ti-sn65dsi86 this wasn't too difficult to accomplish. That driver
> > is already broken up into several "struct devices" anyway because it
> > also provides a PWM and some GPIOs. Adding one more wasn't that
> > difficult / ugly.
> >
> > When I tried to do the same solution in parade-ps8640, it felt like I
> > was copying too much boilerplate code. I made the realization that I
> > didn't _really_ need a separate "driver" for each person that wanted
> > to do the same thing. By putting all the "driver" related code in a
> > common place then we could save a bit of hassle. This change
> > effectively adds a new "ep_client" driver that can be used by
> > anyone. The devices instantiated by this driver will just call through
> > to the probe/remove/shutdown calls provided.
> >
> > At the moment, the "ep_client" driver is backed by the Linux auxiliary
> > bus (unfortunate naming--this has nothing to do with DP AUX). I didn't
> > want to expose this to clients, though, so as far as clients are
> > concerned they get a vanilla "struct device".
> >
> > Signed-off-by: Douglas Anderson 
> > ---
>
> Is it correct that the struct dp_aux_ep_client is largely equivalent to
> a struct dp_aux_ep_device? What's the difference? I think it is a fully
> probed dp_aux_ep_device? Or a way to tell the driver that calls
> of_dp_aux_populate_ep_devices() that the endpoint has probed now?

They're not the same. The "DP AUX Endpoint Device" is essentially the
panel, though at one point in time someone argued that conceivably one
could put other devices on it even though this might be a really bad
idea. At some point in the discussion someone mentioned the concept of
a touchscreen running over DP Aux had been discussed and, indeed, "dp
aux touchscreen" gets hits if you search for it. The idea that it
could be something different is one reason why I refrained from
calling it a panel in all the function names and always tried to call
it a "DP AUX Endpoint".

The "DP AUX Endpoint Device Client" is the client of the panel, or the
code that needs to get a reference to the panel. Logically, I guess
this is the part of the eDP controller that's responsible for shoving
bits to the panel. Essentially the drm_bridge. Most importantly, it's
_not_ the part of the eDP controller providing the AUX bus.


> I read the commit text but it didn't click until I read the next patch
> that this is solving a probe ordering/loop problem. The driver that
> creates the 'struct drm_dp_aux' and populates devices on the DP aux bus
> with of_dp_aux_populate_ep_devices() wants to be sure that the
> drm_bridge made by the 'struct dp_aux_ep_driver' probe routine in
> edp-panel is going to be there before calling drm_of_get_bridge().
>
> of_dp_aux_populate_ep_devices();
> [No idea if the bridge is registered yet]
> drm_of_get_bridge();
>
> The solution is to retry the drm_of_get_bridge() until 'struct
> dp_aux_ep_driver' probes and registers the next bridge. It looks like a
> wait_for_completion() on top of drm_of_get_bridge() implemented through
> driver probe and -EPROBE_DEFER; no disrespect!

Yes, that's exactly what it is.


> Is there another problem here that the driver that creates the 'struct
> drm_dp_aux' and populates devices on the DP aux bus with
> of_dp_aux_populate_ep_devices() wants to use that same 'struct
> drm_dp_aux' directly to poke at some 'struct dp_aux_ep_device' that was
> populated? And the 'struct dp_aux_ep_device' may either not be probed
> and bound to a 'struct dp_aux_ep_driver' or it may not be powered on
> because it went to runtime PM suspend?
>
> Put another way, I worry that the owner of 'struct drm_dp_aux' wants to
> use some function in include/drm/dp/drm_dp_helper.h that takes the
> 'struct drm_dp_aux' directly without considering the device model state
> of the endpoint device (the 'struct dp_aux_ep_device'). That would be a
> similar problem as waiting for the endpoint to be powered on and probed.
> Solving that through a sub-driver feels awkward.
>
> What if we had some function like drm_dp_get_aux_ep() that took a
> 'struct drm_dp_aux' and looked for the endpoint device (there can only
> be one?),

The code is designed to handle the fact that there could be more than
one AUX endpoint device. I don't know if this will ever happen but it
is plausible. The "touchscreen over DP AUX", if that ever became a
thing supported in Linux, could be an example. In 

Re: [RFC PATCH 1/6] drm/dp: Helpers to make it easier for drivers to use DP AUX bus properly

2022-04-15 Thread Doug Anderson
Hi,

On Thu, Apr 14, 2022 at 5:47 PM Dmitry Baryshkov
 wrote:
>
> On 09/04/2022 05:36, Douglas Anderson wrote:
> > As talked about in the kerneldoc for "struct dp_aux_ep_client" in this
> > patch and also in the past in commit a1e3667a9835 ("drm/bridge:
> > ti-sn65dsi86: Promote the AUX channel to its own sub-dev"), to use the
> > DP AUX bus properly we really need two "struct device"s. One "struct
> > device" is in charge of providing the DP AUX bus and the other is
> > where we'll try to get a reference to the newly probed endpoint
> > devices.
> >
> > In ti-sn65dsi86 this wasn't too difficult to accomplish. That driver
> > is already broken up into several "struct devices" anyway because it
> > also provides a PWM and some GPIOs. Adding one more wasn't that
> > difficult / ugly.
> >
> > When I tried to do the same solution in parade-ps8640, it felt like I
> > was copying too much boilerplate code. I made the realization that I
> > didn't _really_ need a separate "driver" for each person that wanted
> > to do the same thing. By putting all the "driver" related code in a
> > common place then we could save a bit of hassle. This change
> > effectively adds a new "ep_client" driver that can be used by
> > anyone. The devices instantiated by this driver will just call through
> > to the probe/remove/shutdown calls provided.
> >
> > At the moment, the "ep_client" driver is backed by the Linux auxiliary
> > bus (unfortunate naming--this has nothing to do with DP AUX). I didn't
> > want to expose this to clients, though, so as far as clients are
> > concerned they get a vanilla "struct device".
>
> I have been thinking about your approach for quite some time. I think
> that enforcing a use of auxilliary device is an overkill. What do we
> really need is the the set callbacks in the bus struct or a notifier. We
> have to notify the aux_bus controller side that the client has been
> probed successfully or that the client is going to be removed.

It seems like these new callbacks would be nearly the same as the
probe/remove callbacks in my proposal except:

* They rely on there being exactly 1 AUX device, or we make it a rule
that we wait for all AUX devices to probe (?)

* We need to come up with a system for detecting when everything
probes or is going to be removed, though that's probably not too hard.
I guess the DP AUX bus could just replace the panel's probe function
with its own and essentially "tail patch" it. I guess it could "head
patch" the remove call? ...or is there some better way you were
thinking of knowing when all our children probed?

* The callback on the aux bus controller side would not be able to
DEFER. In other words trying to acquire a reference to the panel can
always be the last thing we do so we know there can be no reasons to
defer after. This should be doable, but at least in the ps8640 case it
will require changing the code a bit. I notice that today it actually
tries to get the panel side _before_ it gets the MIPI side and it
potentially can return -EPROBE_DEFER if it can't find the MIPI side. I
guess I have a niggling feeling that we'll find some reason in the
future that we can't be last, but we can probably ignore that. ;-)

I can switch this all to normal callbacks if that's what everyone
wants, but it doesn't feel significantly cleaner to me and does seem
to have some (small) downsides.


> And this
> approach would make driver's life easier, since e.g. the bus code can
> pm_get the EP device before calling callbacks/notifiers and
> pm_put_autosuspend it afterwards.

Not sure about doing the pm calls on behalf of the EP device. What's
the goal there?


Re: [RFC PATCH 4/6] drm/panel-edp: Take advantage of is_hpd_asserted() in struct drm_dp_aux

2022-04-15 Thread Doug Anderson
Hi,

On Thu, Apr 14, 2022 at 5:51 PM Dmitry Baryshkov
 wrote:
>
> On 09/04/2022 05:36, Douglas Anderson wrote:
> > Let's add support for being able to read the HPD pin even if it's
> > hooked directly to the controller. This will allow us to get more
> > accurate delays also lets us take away the waiting in the AUX transfer
> > functions of the eDP controller drivers.
> >
> > Signed-off-by: Douglas Anderson 
> > ---
> >
> >   drivers/gpu/drm/panel/panel-edp.c | 37 ++-
> >   1 file changed, 31 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/panel/panel-edp.c 
> > b/drivers/gpu/drm/panel/panel-edp.c
> > index 1732b4f56e38..4a143eb9544b 100644
> > --- a/drivers/gpu/drm/panel/panel-edp.c
> > +++ b/drivers/gpu/drm/panel/panel-edp.c
> > @@ -417,6 +417,19 @@ static int panel_edp_get_hpd_gpio(struct device *dev, 
> > struct panel_edp *p)
> >   return 0;
> >   }
> >
> > +static bool panel_edp_can_read_hpd(struct panel_edp *p)
> > +{
> > + return !p->no_hpd && (p->hpd_gpio || (p->aux && 
> > p->aux->is_hpd_asserted));
> > +}
> > +
> > +static bool panel_edp_read_hpd(struct panel_edp *p)
> > +{
> > + if (p->hpd_gpio)
> > + return gpiod_get_value_cansleep(p->hpd_gpio);
> > +
> > + return p->aux->is_hpd_asserted(p->aux);
> > +}
> > +
> >   static int panel_edp_prepare_once(struct panel_edp *p)
> >   {
> >   struct device *dev = p->base.dev;
> > @@ -441,13 +454,21 @@ static int panel_edp_prepare_once(struct panel_edp *p)
> >   if (delay)
> >   msleep(delay);
> >
> > - if (p->hpd_gpio) {
> > + if (panel_edp_can_read_hpd(p)) {
> >   if (p->desc->delay.hpd_absent)
> >   hpd_wait_us = p->desc->delay.hpd_absent * 1000UL;
> >   else
> >   hpd_wait_us = 200;
> >
> > - err = readx_poll_timeout(gpiod_get_value_cansleep, 
> > p->hpd_gpio,
> > + /*
> > +  * Extra max delay, mostly to account for ps8640. ps8640
> > +  * is crazy and the bridge chip driver itself has over 200 ms
> > +  * of delay if it needs to do the pm_runtime resume of the
> > +  * bridge chip to read the HPD.
> > +  */
> > + hpd_wait_us += 300;
>
> I think this should come in a separate commit and ideally this should be
> configurable somehow. Other hosts wouldn't need such 'additional' delay.
>
> With this change removed:
>
> Reviewed-by: Dmitry Baryshkov 

What would you think about changing the API slightly? Instead of
is_hpd_asserted(), we change it to wait_hpd_asserted() and it takes a
timeout in microseconds. If you pass 0 for the timeout the function is
defined to behave the same as is_hpd_asserted() today--AKA a single
poll of the line.

-Doug


Re: [RFC PATCH 4/6] drm/panel-edp: Take advantage of is_hpd_asserted() in struct drm_dp_aux

2022-04-15 Thread Dmitry Baryshkov
On Sat, 16 Apr 2022 at 00:17, Doug Anderson  wrote:
>
> Hi,
>
> On Thu, Apr 14, 2022 at 5:51 PM Dmitry Baryshkov
>  wrote:
> >
> > On 09/04/2022 05:36, Douglas Anderson wrote:
> > > Let's add support for being able to read the HPD pin even if it's
> > > hooked directly to the controller. This will allow us to get more
> > > accurate delays also lets us take away the waiting in the AUX transfer
> > > functions of the eDP controller drivers.
> > >
> > > Signed-off-by: Douglas Anderson 
> > > ---
> > >
> > >   drivers/gpu/drm/panel/panel-edp.c | 37 ++-
> > >   1 file changed, 31 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/panel/panel-edp.c 
> > > b/drivers/gpu/drm/panel/panel-edp.c
> > > index 1732b4f56e38..4a143eb9544b 100644
> > > --- a/drivers/gpu/drm/panel/panel-edp.c
> > > +++ b/drivers/gpu/drm/panel/panel-edp.c
> > > @@ -417,6 +417,19 @@ static int panel_edp_get_hpd_gpio(struct device 
> > > *dev, struct panel_edp *p)
> > >   return 0;
> > >   }
> > >
> > > +static bool panel_edp_can_read_hpd(struct panel_edp *p)
> > > +{
> > > + return !p->no_hpd && (p->hpd_gpio || (p->aux && 
> > > p->aux->is_hpd_asserted));
> > > +}
> > > +
> > > +static bool panel_edp_read_hpd(struct panel_edp *p)
> > > +{
> > > + if (p->hpd_gpio)
> > > + return gpiod_get_value_cansleep(p->hpd_gpio);
> > > +
> > > + return p->aux->is_hpd_asserted(p->aux);
> > > +}
> > > +
> > >   static int panel_edp_prepare_once(struct panel_edp *p)
> > >   {
> > >   struct device *dev = p->base.dev;
> > > @@ -441,13 +454,21 @@ static int panel_edp_prepare_once(struct panel_edp 
> > > *p)
> > >   if (delay)
> > >   msleep(delay);
> > >
> > > - if (p->hpd_gpio) {
> > > + if (panel_edp_can_read_hpd(p)) {
> > >   if (p->desc->delay.hpd_absent)
> > >   hpd_wait_us = p->desc->delay.hpd_absent * 1000UL;
> > >   else
> > >   hpd_wait_us = 200;
> > >
> > > - err = readx_poll_timeout(gpiod_get_value_cansleep, 
> > > p->hpd_gpio,
> > > + /*
> > > +  * Extra max delay, mostly to account for ps8640. ps8640
> > > +  * is crazy and the bridge chip driver itself has over 200 
> > > ms
> > > +  * of delay if it needs to do the pm_runtime resume of the
> > > +  * bridge chip to read the HPD.
> > > +  */
> > > + hpd_wait_us += 300;
> >
> > I think this should come in a separate commit and ideally this should be
> > configurable somehow. Other hosts wouldn't need such 'additional' delay.
> >
> > With this change removed:
> >
> > Reviewed-by: Dmitry Baryshkov 
>
> What would you think about changing the API slightly? Instead of
> is_hpd_asserted(), we change it to wait_hpd_asserted() and it takes a
> timeout in microseconds. If you pass 0 for the timeout the function is
> defined to behave the same as is_hpd_asserted() today--AKA a single
> poll of the line.

This might work. Can you check it, please?

BTW: are these changes dependent on the first part of the patchset? It
might be worth splitting the patchset into two parts.

-- 
With best wishes
Dmitry


[PATCH v7] drm/msm/dp: stop event kernel thread when DP unbind

2022-04-15 Thread Kuogee Hsieh
Current DP driver implementation, event thread is kept running
after DP display is unbind. This patch fix this problem by disabling
DP irq and stop event thread to exit gracefully at dp_display_unbind().

Changes in v2:
-- start event thread at dp_display_bind()

Changes in v3:
-- disable all HDP interrupts at unbind
-- replace dp_hpd_event_setup() with dp_hpd_event_thread_start()
-- replace dp_hpd_event_stop() with dp_hpd_event_thread_stop()
-- move init_waitqueue_head(&dp->event_q) to probe()
-- move spin_lock_init(&dp->event_lock) to probe()

Changes in v4:
-- relocate both dp_display_bind() and dp_display_unbind() to bottom of file

Changes in v5:
-- cancel relocation of both dp_display_bind() and dp_display_unbind()

Changes in v6:
-- move empty event q to dp_event_thread_start()

Changes in v7:
-- call ktheread_stop() directly instead of dp_hpd_event_thread_stop() function

Fixes: e91e3065a806 ("drm/msm/dp: Add DP compliance tests on Snapdragon 
Chipsets")
Signed-off-by: Kuogee Hsieh 
Reported-by: Dmitry Baryshkov 
Reviewed-by: Stephen Boyd 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 31 ---
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 01453db..680e500 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -113,6 +113,7 @@ struct dp_display_private {
u32 hpd_state;
u32 event_pndx;
u32 event_gndx;
+   struct task_struct *ev_tsk;
struct dp_event event_list[DP_EVENT_Q_MAX];
spinlock_t event_lock;
 
@@ -230,6 +231,8 @@ void dp_display_signal_audio_complete(struct msm_dp 
*dp_display)
complete_all(&dp->audio_comp);
 }
 
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
+
 static int dp_display_bind(struct device *dev, struct device *master,
   void *data)
 {
@@ -269,6 +272,7 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
if (rc)
DRM_ERROR("Audio registration Dp failed\n");
 
+   rc = dp_hpd_event_thread_start(dp);
 end:
return rc;
 }
@@ -280,6 +284,11 @@ static void dp_display_unbind(struct device *dev, struct 
device *master,
struct drm_device *drm = dev_get_drvdata(master);
struct msm_drm_private *priv = drm->dev_private;
 
+   /* disable all HPD interrupts */
+   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
+
+   kthread_stop(dp->ev_tsk);
+
dp_power_client_deinit(dp->power);
dp_aux_unregister(dp->aux);
priv->dp[dp->id] = NULL;
@@ -1054,7 +1063,7 @@ static int hpd_event_thread(void *data)
 
dp_priv = (struct dp_display_private *)data;
 
-   while (1) {
+   while (!kthread_should_stop()) {
if (timeout_mode) {
wait_event_timeout(dp_priv->event_q,
(dp_priv->event_pndx == dp_priv->event_gndx),
@@ -1132,12 +1141,19 @@ static int hpd_event_thread(void *data)
return 0;
 }
 
-static void dp_hpd_event_setup(struct dp_display_private *dp_priv)
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)
 {
-   init_waitqueue_head(&dp_priv->event_q);
-   spin_lock_init(&dp_priv->event_lock);
+   /* set event q to empty */
+   dp_priv->event_gndx = 0;
+   dp_priv->event_pndx = 0;
+
+   dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, 
"dp_hpd_handler");
+   if (IS_ERR(dp_priv->ev_tsk)) {
+   DRM_ERROR("failed to create DP event thread\n");
+   return PTR_ERR(dp_priv->ev_tsk);
+   }
 
-   kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");
+   return 0;
 }
 
 static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
@@ -1266,7 +1282,10 @@ static int dp_display_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
 
+   /* setup event q */
mutex_init(&dp->event_mutex);
+   init_waitqueue_head(&dp->event_q);
+   spin_lock_init(&dp->event_lock);
 
/* Store DP audio handle inside DP display */
dp->dp_display.dp_audio = dp->audio;
@@ -1441,8 +1460,6 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
 
dp = container_of(dp_display, struct dp_display_private, dp_display);
 
-   dp_hpd_event_setup(dp);
-
dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [RFC PATCH 1/6] drm/dp: Helpers to make it easier for drivers to use DP AUX bus properly

2022-04-15 Thread Dmitry Baryshkov
On Sat, 16 Apr 2022 at 00:13, Doug Anderson  wrote:
>
> Hi,
>
> On Thu, Apr 14, 2022 at 5:47 PM Dmitry Baryshkov
>  wrote:
> >
> > On 09/04/2022 05:36, Douglas Anderson wrote:
> > > As talked about in the kerneldoc for "struct dp_aux_ep_client" in this
> > > patch and also in the past in commit a1e3667a9835 ("drm/bridge:
> > > ti-sn65dsi86: Promote the AUX channel to its own sub-dev"), to use the
> > > DP AUX bus properly we really need two "struct device"s. One "struct
> > > device" is in charge of providing the DP AUX bus and the other is
> > > where we'll try to get a reference to the newly probed endpoint
> > > devices.
> > >
> > > In ti-sn65dsi86 this wasn't too difficult to accomplish. That driver
> > > is already broken up into several "struct devices" anyway because it
> > > also provides a PWM and some GPIOs. Adding one more wasn't that
> > > difficult / ugly.
> > >
> > > When I tried to do the same solution in parade-ps8640, it felt like I
> > > was copying too much boilerplate code. I made the realization that I
> > > didn't _really_ need a separate "driver" for each person that wanted
> > > to do the same thing. By putting all the "driver" related code in a
> > > common place then we could save a bit of hassle. This change
> > > effectively adds a new "ep_client" driver that can be used by
> > > anyone. The devices instantiated by this driver will just call through
> > > to the probe/remove/shutdown calls provided.
> > >
> > > At the moment, the "ep_client" driver is backed by the Linux auxiliary
> > > bus (unfortunate naming--this has nothing to do with DP AUX). I didn't
> > > want to expose this to clients, though, so as far as clients are
> > > concerned they get a vanilla "struct device".
> >
> > I have been thinking about your approach for quite some time. I think
> > that enforcing a use of auxilliary device is an overkill. What do we
> > really need is the the set callbacks in the bus struct or a notifier. We
> > have to notify the aux_bus controller side that the client has been
> > probed successfully or that the client is going to be removed.
>
> It seems like these new callbacks would be nearly the same as the
> probe/remove callbacks in my proposal except:
>
> * They rely on there being exactly 1 AUX device, or we make it a rule
> that we wait for all AUX devices to probe (?)

Is the backlight a separate device on an AUX bus? Judging from
drm_panel_dp_aux_backlight(), it isn't. I assumed that aux bus is just
a point-to-point bus, so there is always a single client.

>
> * We need to come up with a system for detecting when everything
> probes or is going to be removed, though that's probably not too hard.
> I guess the DP AUX bus could just replace the panel's probe function
> with its own and essentially "tail patch" it. I guess it could "head
> patch" the remove call? ...or is there some better way you were
> thinking of knowing when all our children probed?
>
> * The callback on the aux bus controller side would not be able to
> DEFER. In other words trying to acquire a reference to the panel can
> always be the last thing we do so we know there can be no reasons to
> defer after. This should be doable, but at least in the ps8640 case it
> will require changing the code a bit. I notice that today it actually
> tries to get the panel side _before_ it gets the MIPI side and it
> potentially can return -EPROBE_DEFER if it can't find the MIPI side. I
> guess I have a niggling feeling that we'll find some reason in the
> future that we can't be last, but we can probably ignore that. ;-)
>
> I can switch this all to normal callbacks if that's what everyone
> wants, but it doesn't feel significantly cleaner to me and does seem
> to have some (small) downsides.
>
>
> > And this
> > approach would make driver's life easier, since e.g. the bus code can
> > pm_get the EP device before calling callbacks/notifiers and
> > pm_put_autosuspend it afterwards.
>
> Not sure about doing the pm calls on behalf of the EP device. What's
> the goal there?

I think any driver can pm_runtime_get another device. The goal is to
let the 'post_probe' callback to power up the panel, read the EDID,
etc.

BTW: as I'm slowly diving into DP vs eDP differences. Do we need to
write the EDID checksum like we do for DP?
Do you have any good summary for eDP vs DP differences?

-- 
With best wishes
Dmitry


Re: [PATCH v7] drm/msm/dp: stop event kernel thread when DP unbind

2022-04-15 Thread Dmitry Baryshkov
On Sat, 16 Apr 2022 at 01:34, Kuogee Hsieh  wrote:
>
> Current DP driver implementation, event thread is kept running
> after DP display is unbind. This patch fix this problem by disabling
> DP irq and stop event thread to exit gracefully at dp_display_unbind().
>
> Changes in v2:
> -- start event thread at dp_display_bind()
>
> Changes in v3:
> -- disable all HDP interrupts at unbind
> -- replace dp_hpd_event_setup() with dp_hpd_event_thread_start()
> -- replace dp_hpd_event_stop() with dp_hpd_event_thread_stop()
> -- move init_waitqueue_head(&dp->event_q) to probe()
> -- move spin_lock_init(&dp->event_lock) to probe()
>
> Changes in v4:
> -- relocate both dp_display_bind() and dp_display_unbind() to bottom of file
>
> Changes in v5:
> -- cancel relocation of both dp_display_bind() and dp_display_unbind()
>
> Changes in v6:
> -- move empty event q to dp_event_thread_start()
>
> Changes in v7:
> -- call ktheread_stop() directly instead of dp_hpd_event_thread_stop() 
> function
>
> Fixes: e91e3065a806 ("drm/msm/dp: Add DP compliance tests on Snapdragon 
> Chipsets")
> Signed-off-by: Kuogee Hsieh 
> Reported-by: Dmitry Baryshkov 
> Reviewed-by: Stephen Boyd 
> ---
>  drivers/gpu/drm/msm/dp/dp_display.c | 31 ---
>  1 file changed, 24 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index 01453db..680e500 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -113,6 +113,7 @@ struct dp_display_private {
> u32 hpd_state;
> u32 event_pndx;
> u32 event_gndx;
> +   struct task_struct *ev_tsk;
> struct dp_event event_list[DP_EVENT_Q_MAX];
> spinlock_t event_lock;
>
> @@ -230,6 +231,8 @@ void dp_display_signal_audio_complete(struct msm_dp 
> *dp_display)
> complete_all(&dp->audio_comp);
>  }
>
> +static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
> +
>  static int dp_display_bind(struct device *dev, struct device *master,
>void *data)
>  {
> @@ -269,6 +272,7 @@ static int dp_display_bind(struct device *dev, struct 
> device *master,
> if (rc)
> DRM_ERROR("Audio registration Dp failed\n");

I think I asked it in v3 and didn't get an answer:
Isn't 'goto end' missing here?

>
> +   rc = dp_hpd_event_thread_start(dp);

if (rc) { DRM_ERROR(); goto end; }
return 0;

Please.

>  end:
> return rc;
>  }
> @@ -280,6 +284,11 @@ static void dp_display_unbind(struct device *dev, struct 
> device *master,
> struct drm_device *drm = dev_get_drvdata(master);
> struct msm_drm_private *priv = drm->dev_private;
>
> +   /* disable all HPD interrupts */
> +   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
> +
> +   kthread_stop(dp->ev_tsk);
> +
> dp_power_client_deinit(dp->power);
> dp_aux_unregister(dp->aux);
> priv->dp[dp->id] = NULL;
> @@ -1054,7 +1063,7 @@ static int hpd_event_thread(void *data)
>
> dp_priv = (struct dp_display_private *)data;
>
> -   while (1) {
> +   while (!kthread_should_stop()) {
> if (timeout_mode) {
> wait_event_timeout(dp_priv->event_q,
> (dp_priv->event_pndx == dp_priv->event_gndx),
> @@ -1132,12 +1141,19 @@ static int hpd_event_thread(void *data)
> return 0;
>  }
>
> -static void dp_hpd_event_setup(struct dp_display_private *dp_priv)
> +static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)
>  {
> -   init_waitqueue_head(&dp_priv->event_q);
> -   spin_lock_init(&dp_priv->event_lock);
> +   /* set event q to empty */
> +   dp_priv->event_gndx = 0;
> +   dp_priv->event_pndx = 0;
> +
> +   dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, 
> "dp_hpd_handler");
> +   if (IS_ERR(dp_priv->ev_tsk)) {
> +   DRM_ERROR("failed to create DP event thread\n");
> +   return PTR_ERR(dp_priv->ev_tsk);
> +   }
>
> -   kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");
> +   return 0;
>  }
>
>  static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
> @@ -1266,7 +1282,10 @@ static int dp_display_probe(struct platform_device 
> *pdev)
> return -EPROBE_DEFER;
> }
>
> +   /* setup event q */
> mutex_init(&dp->event_mutex);
> +   init_waitqueue_head(&dp->event_q);
> +   spin_lock_init(&dp->event_lock);
>
> /* Store DP audio handle inside DP display */
> dp->dp_display.dp_audio = dp->audio;
> @@ -1441,8 +1460,6 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
>
> dp = container_of(dp_display, struct dp_display_private, dp_display);
>
> -   dp_hpd_event_setup(dp);
> -
> dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
>  }
>
> --
> The Qualcomm Innovation Center, Inc. is a member of the Cod

Re: [PATCH v7] drm/msm/dp: stop event kernel thread when DP unbind

2022-04-15 Thread Kuogee Hsieh



On 4/15/2022 3:48 PM, Dmitry Baryshkov wrote:

On Sat, 16 Apr 2022 at 01:34, Kuogee Hsieh  wrote:

Current DP driver implementation, event thread is kept running
after DP display is unbind. This patch fix this problem by disabling
DP irq and stop event thread to exit gracefully at dp_display_unbind().

Changes in v2:
-- start event thread at dp_display_bind()

Changes in v3:
-- disable all HDP interrupts at unbind
-- replace dp_hpd_event_setup() with dp_hpd_event_thread_start()
-- replace dp_hpd_event_stop() with dp_hpd_event_thread_stop()
-- move init_waitqueue_head(&dp->event_q) to probe()
-- move spin_lock_init(&dp->event_lock) to probe()

Changes in v4:
-- relocate both dp_display_bind() and dp_display_unbind() to bottom of file

Changes in v5:
-- cancel relocation of both dp_display_bind() and dp_display_unbind()

Changes in v6:
-- move empty event q to dp_event_thread_start()

Changes in v7:
-- call ktheread_stop() directly instead of dp_hpd_event_thread_stop() function

Fixes: e91e3065a806 ("drm/msm/dp: Add DP compliance tests on Snapdragon 
Chipsets")
Signed-off-by: Kuogee Hsieh 
Reported-by: Dmitry Baryshkov 
Reviewed-by: Stephen Boyd 
---
  drivers/gpu/drm/msm/dp/dp_display.c | 31 ---
  1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 01453db..680e500 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -113,6 +113,7 @@ struct dp_display_private {
 u32 hpd_state;
 u32 event_pndx;
 u32 event_gndx;
+   struct task_struct *ev_tsk;
 struct dp_event event_list[DP_EVENT_Q_MAX];
 spinlock_t event_lock;

@@ -230,6 +231,8 @@ void dp_display_signal_audio_complete(struct msm_dp 
*dp_display)
 complete_all(&dp->audio_comp);
  }

+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
+
  static int dp_display_bind(struct device *dev, struct device *master,
void *data)
  {
@@ -269,6 +272,7 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
 if (rc)
 DRM_ERROR("Audio registration Dp failed\n");

I think I asked it in v3 and didn't get an answer:
Isn't 'goto end' missing here?
I did follow you suggestion at v3 and made changes at 
dp_hpd_event_thread_start()

+   rc = dp_hpd_event_thread_start(dp);

if (rc) { DRM_ERROR(); goto end; }
return 0;

Please.

This is at dp_display_bind(),  "end" is the next statement why goto needed?

  end:
 return rc;
  }
@@ -280,6 +284,11 @@ static void dp_display_unbind(struct device *dev, struct 
device *master,
 struct drm_device *drm = dev_get_drvdata(master);
 struct msm_drm_private *priv = drm->dev_private;

+   /* disable all HPD interrupts */
+   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
+
+   kthread_stop(dp->ev_tsk);
+
 dp_power_client_deinit(dp->power);
 dp_aux_unregister(dp->aux);
 priv->dp[dp->id] = NULL;
@@ -1054,7 +1063,7 @@ static int hpd_event_thread(void *data)

 dp_priv = (struct dp_display_private *)data;

-   while (1) {
+   while (!kthread_should_stop()) {
 if (timeout_mode) {
 wait_event_timeout(dp_priv->event_q,
 (dp_priv->event_pndx == dp_priv->event_gndx),
@@ -1132,12 +1141,19 @@ static int hpd_event_thread(void *data)
 return 0;
  }

-static void dp_hpd_event_setup(struct dp_display_private *dp_priv)
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)
  {
-   init_waitqueue_head(&dp_priv->event_q);
-   spin_lock_init(&dp_priv->event_lock);
+   /* set event q to empty */
+   dp_priv->event_gndx = 0;
+   dp_priv->event_pndx = 0;
+
+   dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, 
"dp_hpd_handler");
+   if (IS_ERR(dp_priv->ev_tsk)) {
+   DRM_ERROR("failed to create DP event thread\n");
+   return PTR_ERR(dp_priv->ev_tsk);
+   }

-   kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");
+   return 0;
  }

  static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
@@ -1266,7 +1282,10 @@ static int dp_display_probe(struct platform_device *pdev)
 return -EPROBE_DEFER;
 }

+   /* setup event q */
 mutex_init(&dp->event_mutex);
+   init_waitqueue_head(&dp->event_q);
+   spin_lock_init(&dp->event_lock);

 /* Store DP audio handle inside DP display */
 dp->dp_display.dp_audio = dp->audio;
@@ -1441,8 +1460,6 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)

 dp = container_of(dp_display, struct dp_display_private, dp_display);

-   dp_hpd_event_setup(dp);
-
 dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
  }

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 

Re: [Freedreno] [PATCH 06/12] drm/msm/dpu: make changes to dpu_encoder to support virtual encoder

2022-04-15 Thread Marijn Suijten
Hi Abhinav,

On 2022-04-15 12:25:55, Abhinav Kumar wrote:
> Hi Marijn
> 
> Looking at msm-next tip, this code has already been refactored in
> 
> https://gitlab.freedesktop.org/drm/msm/-/commit/ef58e0ad34365e2c8274b74e6e745b8c180ff0d3
> 
> So, I will just rebase my changes on msm-next tip and it should address 
> below comments as well.

That's actually great, I love patches that remove a whole lot of
(especially bug-containing) lines, awesome Dmitry!

Looking forward to the next revision, spotted some minor nits in this
revision but it probably makes little sense to point them out here
presuming they might have already been addressed on your end or removed
altogether.

- Marijn


Re: [PATCH v7] drm/msm/dp: stop event kernel thread when DP unbind

2022-04-15 Thread Dmitry Baryshkov
On Sat, 16 Apr 2022 at 02:10, Kuogee Hsieh  wrote:
>
>
> On 4/15/2022 3:48 PM, Dmitry Baryshkov wrote:
> > On Sat, 16 Apr 2022 at 01:34, Kuogee Hsieh  wrote:
> >> Current DP driver implementation, event thread is kept running
> >> after DP display is unbind. This patch fix this problem by disabling
> >> DP irq and stop event thread to exit gracefully at dp_display_unbind().
> >>
> >> Changes in v2:
> >> -- start event thread at dp_display_bind()
> >>
> >> Changes in v3:
> >> -- disable all HDP interrupts at unbind
> >> -- replace dp_hpd_event_setup() with dp_hpd_event_thread_start()
> >> -- replace dp_hpd_event_stop() with dp_hpd_event_thread_stop()
> >> -- move init_waitqueue_head(&dp->event_q) to probe()
> >> -- move spin_lock_init(&dp->event_lock) to probe()
> >>
> >> Changes in v4:
> >> -- relocate both dp_display_bind() and dp_display_unbind() to bottom of 
> >> file
> >>
> >> Changes in v5:
> >> -- cancel relocation of both dp_display_bind() and dp_display_unbind()
> >>
> >> Changes in v6:
> >> -- move empty event q to dp_event_thread_start()
> >>
> >> Changes in v7:
> >> -- call ktheread_stop() directly instead of dp_hpd_event_thread_stop() 
> >> function
> >>
> >> Fixes: e91e3065a806 ("drm/msm/dp: Add DP compliance tests on Snapdragon 
> >> Chipsets")
> >> Signed-off-by: Kuogee Hsieh 
> >> Reported-by: Dmitry Baryshkov 
> >> Reviewed-by: Stephen Boyd 
> >> ---
> >>   drivers/gpu/drm/msm/dp/dp_display.c | 31 ---
> >>   1 file changed, 24 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> >> b/drivers/gpu/drm/msm/dp/dp_display.c
> >> index 01453db..680e500 100644
> >> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> >> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> >> @@ -113,6 +113,7 @@ struct dp_display_private {
> >>  u32 hpd_state;
> >>  u32 event_pndx;
> >>  u32 event_gndx;
> >> +   struct task_struct *ev_tsk;
> >>  struct dp_event event_list[DP_EVENT_Q_MAX];
> >>  spinlock_t event_lock;
> >>
> >> @@ -230,6 +231,8 @@ void dp_display_signal_audio_complete(struct msm_dp 
> >> *dp_display)
> >>  complete_all(&dp->audio_comp);
> >>   }
> >>
> >> +static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
> >> +
> >>   static int dp_display_bind(struct device *dev, struct device *master,
> >> void *data)
> >>   {
> >> @@ -269,6 +272,7 @@ static int dp_display_bind(struct device *dev, struct 
> >> device *master,
> >>  if (rc)
> >>  DRM_ERROR("Audio registration Dp failed\n");
> > I think I asked it in v3 and didn't get an answer:
> > Isn't 'goto end' missing here?
> I did follow you suggestion at v3 and made changes at
> dp_hpd_event_thread_start()

I'm asking about this place. Should we return an immediate error if
audio registration has failed or not?

> >> +   rc = dp_hpd_event_thread_start(dp);
> > if (rc) { DRM_ERROR(); goto end; }
> > return 0;
> >
> > Please.
> This is at dp_display_bind(),  "end" is the next statement why goto needed?

To be explicit that this is a fatal error. Compare this to my question
regarding the audio registration failure.

> >>   end:
> >>  return rc;
> >>   }
> >> @@ -280,6 +284,11 @@ static void dp_display_unbind(struct device *dev, 
> >> struct device *master,
> >>  struct drm_device *drm = dev_get_drvdata(master);
> >>  struct msm_drm_private *priv = drm->dev_private;
> >>
> >> +   /* disable all HPD interrupts */
> >> +   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
> >> +
> >> +   kthread_stop(dp->ev_tsk);
> >> +
> >>  dp_power_client_deinit(dp->power);
> >>  dp_aux_unregister(dp->aux);
> >>  priv->dp[dp->id] = NULL;
> >> @@ -1054,7 +1063,7 @@ static int hpd_event_thread(void *data)
> >>
> >>  dp_priv = (struct dp_display_private *)data;
> >>
> >> -   while (1) {
> >> +   while (!kthread_should_stop()) {
> >>  if (timeout_mode) {
> >>  wait_event_timeout(dp_priv->event_q,
> >>  (dp_priv->event_pndx == 
> >> dp_priv->event_gndx),
> >> @@ -1132,12 +1141,19 @@ static int hpd_event_thread(void *data)
> >>  return 0;
> >>   }
> >>
> >> -static void dp_hpd_event_setup(struct dp_display_private *dp_priv)
> >> +static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)
> >>   {
> >> -   init_waitqueue_head(&dp_priv->event_q);
> >> -   spin_lock_init(&dp_priv->event_lock);
> >> +   /* set event q to empty */
> >> +   dp_priv->event_gndx = 0;
> >> +   dp_priv->event_pndx = 0;
> >> +
> >> +   dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, 
> >> "dp_hpd_handler");
> >> +   if (IS_ERR(dp_priv->ev_tsk)) {
> >> +   DRM_ERROR("failed to create DP event thread\n");
> >> +   return PTR_ERR(dp_priv->ev_tsk);
> >> +   }
> >>
> >> -   kthre

Re: [PATCH v7] drm/msm/dp: stop event kernel thread when DP unbind

2022-04-15 Thread Kuogee Hsieh



On 4/15/2022 4:27 PM, Dmitry Baryshkov wrote:

On Sat, 16 Apr 2022 at 02:10, Kuogee Hsieh  wrote:


On 4/15/2022 3:48 PM, Dmitry Baryshkov wrote:

On Sat, 16 Apr 2022 at 01:34, Kuogee Hsieh  wrote:

Current DP driver implementation, event thread is kept running
after DP display is unbind. This patch fix this problem by disabling
DP irq and stop event thread to exit gracefully at dp_display_unbind().

Changes in v2:
-- start event thread at dp_display_bind()

Changes in v3:
-- disable all HDP interrupts at unbind
-- replace dp_hpd_event_setup() with dp_hpd_event_thread_start()
-- replace dp_hpd_event_stop() with dp_hpd_event_thread_stop()
-- move init_waitqueue_head(&dp->event_q) to probe()
-- move spin_lock_init(&dp->event_lock) to probe()

Changes in v4:
-- relocate both dp_display_bind() and dp_display_unbind() to bottom of file

Changes in v5:
-- cancel relocation of both dp_display_bind() and dp_display_unbind()

Changes in v6:
-- move empty event q to dp_event_thread_start()

Changes in v7:
-- call ktheread_stop() directly instead of dp_hpd_event_thread_stop() function

Fixes: e91e3065a806 ("drm/msm/dp: Add DP compliance tests on Snapdragon 
Chipsets")
Signed-off-by: Kuogee Hsieh 
Reported-by: Dmitry Baryshkov 
Reviewed-by: Stephen Boyd 
---
   drivers/gpu/drm/msm/dp/dp_display.c | 31 ---
   1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 01453db..680e500 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -113,6 +113,7 @@ struct dp_display_private {
  u32 hpd_state;
  u32 event_pndx;
  u32 event_gndx;
+   struct task_struct *ev_tsk;
  struct dp_event event_list[DP_EVENT_Q_MAX];
  spinlock_t event_lock;

@@ -230,6 +231,8 @@ void dp_display_signal_audio_complete(struct msm_dp 
*dp_display)
  complete_all(&dp->audio_comp);
   }

+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
+
   static int dp_display_bind(struct device *dev, struct device *master,
 void *data)
   {
@@ -269,6 +272,7 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
  if (rc)
  DRM_ERROR("Audio registration Dp failed\n");

I think I asked it in v3 and didn't get an answer:
Isn't 'goto end' missing here?

I did follow you suggestion at v3 and made changes at
dp_hpd_event_thread_start()

I'm asking about this place. Should we return an immediate error if
audio registration has failed or not?


ok,

it is not in this patch.

I will make changes to it.


+   rc = dp_hpd_event_thread_start(dp);

if (rc) { DRM_ERROR(); goto end; }
return 0;

Please.

This is at dp_display_bind(),  "end" is the next statement why goto needed?

To be explicit that this is a fatal error. Compare this to my question
regarding the audio registration failure.


   end:
  return rc;
   }
@@ -280,6 +284,11 @@ static void dp_display_unbind(struct device *dev, struct 
device *master,
  struct drm_device *drm = dev_get_drvdata(master);
  struct msm_drm_private *priv = drm->dev_private;

+   /* disable all HPD interrupts */
+   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
+
+   kthread_stop(dp->ev_tsk);
+
  dp_power_client_deinit(dp->power);
  dp_aux_unregister(dp->aux);
  priv->dp[dp->id] = NULL;
@@ -1054,7 +1063,7 @@ static int hpd_event_thread(void *data)

  dp_priv = (struct dp_display_private *)data;

-   while (1) {
+   while (!kthread_should_stop()) {
  if (timeout_mode) {
  wait_event_timeout(dp_priv->event_q,
  (dp_priv->event_pndx == dp_priv->event_gndx),
@@ -1132,12 +1141,19 @@ static int hpd_event_thread(void *data)
  return 0;
   }

-static void dp_hpd_event_setup(struct dp_display_private *dp_priv)
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)
   {
-   init_waitqueue_head(&dp_priv->event_q);
-   spin_lock_init(&dp_priv->event_lock);
+   /* set event q to empty */
+   dp_priv->event_gndx = 0;
+   dp_priv->event_pndx = 0;
+
+   dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, 
"dp_hpd_handler");
+   if (IS_ERR(dp_priv->ev_tsk)) {
+   DRM_ERROR("failed to create DP event thread\n");
+   return PTR_ERR(dp_priv->ev_tsk);
+   }

-   kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");
+   return 0;
   }

   static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
@@ -1266,7 +1282,10 @@ static int dp_display_probe(struct platform_device *pdev)
  return -EPROBE_DEFER;
  }

+   /* setup event q */
  mutex_init(&dp->event_mutex);
+   init_waitqueue_head(&dp->event_q);
+   spin_lock_init(&dp->event_lock);

  

[PATCH v8] drm/msm/dp: stop event kernel thread when DP unbind

2022-04-15 Thread Kuogee Hsieh
Current DP driver implementation, event thread is kept running
after DP display is unbind. This patch fix this problem by disabling
DP irq and stop event thread to exit gracefully at dp_display_unbind().

Changes in v2:
-- start event thread at dp_display_bind()

Changes in v3:
-- disable all HDP interrupts at unbind
-- replace dp_hpd_event_setup() with dp_hpd_event_thread_start()
-- replace dp_hpd_event_stop() with dp_hpd_event_thread_stop()
-- move init_waitqueue_head(&dp->event_q) to probe()
-- move spin_lock_init(&dp->event_lock) to probe()

Changes in v4:
-- relocate both dp_display_bind() and dp_display_unbind() to bottom of file

Changes in v5:
-- cancel relocation of both dp_display_bind() and dp_display_unbind()

Changes in v6:
-- move empty event q to dp_event_thread_start()

Changes in v7:
-- call ktheread_stop() directly instead of dp_hpd_event_thread_stop() function

Changes in v8:
-- return error immediately if audio registration failed.

Fixes: e91e3065a806 ("drm/msm/dp: Add DP compliance tests on Snapdragon 
Chipsets")
Signed-off-by: Kuogee Hsieh 
Reported-by: Dmitry Baryshkov 
Reviewed-by: Stephen Boyd 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 35 +++
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 01453db..590f90b 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -113,6 +113,7 @@ struct dp_display_private {
u32 hpd_state;
u32 event_pndx;
u32 event_gndx;
+   struct task_struct *ev_tsk;
struct dp_event event_list[DP_EVENT_Q_MAX];
spinlock_t event_lock;
 
@@ -230,6 +231,8 @@ void dp_display_signal_audio_complete(struct msm_dp 
*dp_display)
complete_all(&dp->audio_comp);
 }
 
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
+
 static int dp_display_bind(struct device *dev, struct device *master,
   void *data)
 {
@@ -266,9 +269,12 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
}
 
rc = dp_register_audio_driver(dev, dp->audio);
-   if (rc)
+   if (rc) {
DRM_ERROR("Audio registration Dp failed\n");
+   goto end;
+   }
 
+   rc = dp_hpd_event_thread_start(dp);
 end:
return rc;
 }
@@ -280,6 +286,11 @@ static void dp_display_unbind(struct device *dev, struct 
device *master,
struct drm_device *drm = dev_get_drvdata(master);
struct msm_drm_private *priv = drm->dev_private;
 
+   /* disable all HPD interrupts */
+   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
+
+   kthread_stop(dp->ev_tsk);
+
dp_power_client_deinit(dp->power);
dp_aux_unregister(dp->aux);
priv->dp[dp->id] = NULL;
@@ -1054,7 +1065,7 @@ static int hpd_event_thread(void *data)
 
dp_priv = (struct dp_display_private *)data;
 
-   while (1) {
+   while (!kthread_should_stop()) {
if (timeout_mode) {
wait_event_timeout(dp_priv->event_q,
(dp_priv->event_pndx == dp_priv->event_gndx),
@@ -1132,12 +1143,19 @@ static int hpd_event_thread(void *data)
return 0;
 }
 
-static void dp_hpd_event_setup(struct dp_display_private *dp_priv)
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)
 {
-   init_waitqueue_head(&dp_priv->event_q);
-   spin_lock_init(&dp_priv->event_lock);
+   /* set event q to empty */
+   dp_priv->event_gndx = 0;
+   dp_priv->event_pndx = 0;
+
+   dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, 
"dp_hpd_handler");
+   if (IS_ERR(dp_priv->ev_tsk)) {
+   DRM_ERROR("failed to create DP event thread\n");
+   return PTR_ERR(dp_priv->ev_tsk);
+   }
 
-   kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");
+   return 0;
 }
 
 static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
@@ -1266,7 +1284,10 @@ static int dp_display_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
 
+   /* setup event q */
mutex_init(&dp->event_mutex);
+   init_waitqueue_head(&dp->event_q);
+   spin_lock_init(&dp->event_lock);
 
/* Store DP audio handle inside DP display */
dp->dp_display.dp_audio = dp->audio;
@@ -1441,8 +1462,6 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
 
dp = container_of(dp_display, struct dp_display_private, dp_display);
 
-   dp_hpd_event_setup(dp);
-
dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v8] drm/msm/dp: stop event kernel thread when DP unbind

2022-04-15 Thread Dmitry Baryshkov
On Sat, 16 Apr 2022 at 02:36, Kuogee Hsieh  wrote:
>
> Current DP driver implementation, event thread is kept running
> after DP display is unbind. This patch fix this problem by disabling
> DP irq and stop event thread to exit gracefully at dp_display_unbind().
>
> Changes in v2:
> -- start event thread at dp_display_bind()
>
> Changes in v3:
> -- disable all HDP interrupts at unbind
> -- replace dp_hpd_event_setup() with dp_hpd_event_thread_start()
> -- replace dp_hpd_event_stop() with dp_hpd_event_thread_stop()
> -- move init_waitqueue_head(&dp->event_q) to probe()
> -- move spin_lock_init(&dp->event_lock) to probe()
>
> Changes in v4:
> -- relocate both dp_display_bind() and dp_display_unbind() to bottom of file
>
> Changes in v5:
> -- cancel relocation of both dp_display_bind() and dp_display_unbind()
>
> Changes in v6:
> -- move empty event q to dp_event_thread_start()
>
> Changes in v7:
> -- call ktheread_stop() directly instead of dp_hpd_event_thread_stop() 
> function
>
> Changes in v8:
> -- return error immediately if audio registration failed.
>
> Fixes: e91e3065a806 ("drm/msm/dp: Add DP compliance tests on Snapdragon 
> Chipsets")
> Signed-off-by: Kuogee Hsieh 
> Reported-by: Dmitry Baryshkov 
> Reviewed-by: Stephen Boyd 
> ---
>  drivers/gpu/drm/msm/dp/dp_display.c | 35 +++
>  1 file changed, 27 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index 01453db..590f90b 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -113,6 +113,7 @@ struct dp_display_private {
> u32 hpd_state;
> u32 event_pndx;
> u32 event_gndx;
> +   struct task_struct *ev_tsk;
> struct dp_event event_list[DP_EVENT_Q_MAX];
> spinlock_t event_lock;
>
> @@ -230,6 +231,8 @@ void dp_display_signal_audio_complete(struct msm_dp 
> *dp_display)
> complete_all(&dp->audio_comp);
>  }
>
> +static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
> +
>  static int dp_display_bind(struct device *dev, struct device *master,
>void *data)
>  {
> @@ -266,9 +269,12 @@ static int dp_display_bind(struct device *dev, struct 
> device *master,
> }
>
> rc = dp_register_audio_driver(dev, dp->audio);
> -   if (rc)
> +   if (rc) {
> DRM_ERROR("Audio registration Dp failed\n");
> +   goto end;
> +   }
>
> +   rc = dp_hpd_event_thread_start(dp);

At least a DRM_ERROR is missing here. And yes, I'd ask again for a
goto/return 0;

>  end:
> return rc;
>  }
> @@ -280,6 +286,11 @@ static void dp_display_unbind(struct device *dev, struct 
> device *master,
> struct drm_device *drm = dev_get_drvdata(master);
> struct msm_drm_private *priv = drm->dev_private;
>
> +   /* disable all HPD interrupts */
> +   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
> +
> +   kthread_stop(dp->ev_tsk);
> +
> dp_power_client_deinit(dp->power);
> dp_aux_unregister(dp->aux);
> priv->dp[dp->id] = NULL;
> @@ -1054,7 +1065,7 @@ static int hpd_event_thread(void *data)
>
> dp_priv = (struct dp_display_private *)data;
>
> -   while (1) {
> +   while (!kthread_should_stop()) {
> if (timeout_mode) {
> wait_event_timeout(dp_priv->event_q,
> (dp_priv->event_pndx == dp_priv->event_gndx),
> @@ -1132,12 +1143,19 @@ static int hpd_event_thread(void *data)
> return 0;
>  }
>
> -static void dp_hpd_event_setup(struct dp_display_private *dp_priv)
> +static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)
>  {
> -   init_waitqueue_head(&dp_priv->event_q);
> -   spin_lock_init(&dp_priv->event_lock);
> +   /* set event q to empty */
> +   dp_priv->event_gndx = 0;
> +   dp_priv->event_pndx = 0;
> +
> +   dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, 
> "dp_hpd_handler");
> +   if (IS_ERR(dp_priv->ev_tsk)) {
> +   DRM_ERROR("failed to create DP event thread\n");
> +   return PTR_ERR(dp_priv->ev_tsk);
> +   }
>
> -   kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");
> +   return 0;
>  }
>
>  static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
> @@ -1266,7 +1284,10 @@ static int dp_display_probe(struct platform_device 
> *pdev)
> return -EPROBE_DEFER;
> }
>
> +   /* setup event q */
> mutex_init(&dp->event_mutex);
> +   init_waitqueue_head(&dp->event_q);
> +   spin_lock_init(&dp->event_lock);
>
> /* Store DP audio handle inside DP display */
> dp->dp_display.dp_audio = dp->audio;
> @@ -1441,8 +1462,6 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
>
> dp = container_of(dp_display, struct dp_display_private, dp_display);
>
> -   d

RE: [PATCH 9/9] vfio: Remove calls to vfio_group_add_container_user()

2022-04-15 Thread Tian, Kevin
> From: Jason Gunthorpe 
> Sent: Friday, April 15, 2022 8:07 PM
> 
> On Fri, Apr 15, 2022 at 02:32:08AM +, Tian, Kevin wrote:
> 
> > While it's a welcomed fix is it actually related to this series? The point
> > of this patch is that those functions are called when container_users
> > is non-zero. This is true even without this fix given container_users
> > is decremented after calling device->ops->close_device().
> 
> It isn't, it is decremented before which causes it to be 0 when the
> assertions are called.
> 

right, it's quite obvious when I read it the second time. 


[PATCH v9] drm/msm/dp: stop event kernel thread when DP unbind

2022-04-15 Thread Kuogee Hsieh
Current DP driver implementation, event thread is kept running
after DP display is unbind. This patch fix this problem by disabling
DP irq and stop event thread to exit gracefully at dp_display_unbind().

Changes in v2:
-- start event thread at dp_display_bind()

Changes in v3:
-- disable all HDP interrupts at unbind
-- replace dp_hpd_event_setup() with dp_hpd_event_thread_start()
-- replace dp_hpd_event_stop() with dp_hpd_event_thread_stop()
-- move init_waitqueue_head(&dp->event_q) to probe()
-- move spin_lock_init(&dp->event_lock) to probe()

Changes in v4:
-- relocate both dp_display_bind() and dp_display_unbind() to bottom of file

Changes in v5:
-- cancel relocation of both dp_display_bind() and dp_display_unbind()

Changes in v6:
-- move empty event q to dp_event_thread_start()

Changes in v7:
-- call ktheread_stop() directly instead of dp_hpd_event_thread_stop() function

Changes in v8:
-- return error immediately if audio registration failed.

Changes in v9:
-- return error immediately if event thread create failed.

Fixes: e91e3065a806 ("drm/msm/dp: Add DP compliance tests on Snapdragon 
Chipsets")
Signed-off-by: Kuogee Hsieh 
Reported-by: Dmitry Baryshkov 
Reviewed-by: Stephen Boyd 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 41 +
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 01453db..5b289b9 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -113,6 +113,7 @@ struct dp_display_private {
u32 hpd_state;
u32 event_pndx;
u32 event_gndx;
+   struct task_struct *ev_tsk;
struct dp_event event_list[DP_EVENT_Q_MAX];
spinlock_t event_lock;
 
@@ -230,6 +231,8 @@ void dp_display_signal_audio_complete(struct msm_dp 
*dp_display)
complete_all(&dp->audio_comp);
 }
 
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
+
 static int dp_display_bind(struct device *dev, struct device *master,
   void *data)
 {
@@ -266,9 +269,18 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
}
 
rc = dp_register_audio_driver(dev, dp->audio);
-   if (rc)
+   if (rc) {
DRM_ERROR("Audio registration Dp failed\n");
+   goto end;
+   }
 
+   rc = dp_hpd_event_thread_start(dp);
+   if (rc) {
+   DRM_ERROR("Event thread create failed\n");
+   goto end;
+   }
+
+   return 0;
 end:
return rc;
 }
@@ -280,6 +292,11 @@ static void dp_display_unbind(struct device *dev, struct 
device *master,
struct drm_device *drm = dev_get_drvdata(master);
struct msm_drm_private *priv = drm->dev_private;
 
+   /* disable all HPD interrupts */
+   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
+
+   kthread_stop(dp->ev_tsk);
+
dp_power_client_deinit(dp->power);
dp_aux_unregister(dp->aux);
priv->dp[dp->id] = NULL;
@@ -1054,7 +1071,7 @@ static int hpd_event_thread(void *data)
 
dp_priv = (struct dp_display_private *)data;
 
-   while (1) {
+   while (!kthread_should_stop()) {
if (timeout_mode) {
wait_event_timeout(dp_priv->event_q,
(dp_priv->event_pndx == dp_priv->event_gndx),
@@ -1132,12 +1149,19 @@ static int hpd_event_thread(void *data)
return 0;
 }
 
-static void dp_hpd_event_setup(struct dp_display_private *dp_priv)
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)
 {
-   init_waitqueue_head(&dp_priv->event_q);
-   spin_lock_init(&dp_priv->event_lock);
+   /* set event q to empty */
+   dp_priv->event_gndx = 0;
+   dp_priv->event_pndx = 0;
+
+   dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, 
"dp_hpd_handler");
+   if (IS_ERR(dp_priv->ev_tsk)) {
+   DRM_ERROR("failed to create DP event thread\n");
+   return PTR_ERR(dp_priv->ev_tsk);
+   }
 
-   kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");
+   return 0;
 }
 
 static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
@@ -1266,7 +1290,10 @@ static int dp_display_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
 
+   /* setup event q */
mutex_init(&dp->event_mutex);
+   init_waitqueue_head(&dp->event_q);
+   spin_lock_init(&dp->event_lock);
 
/* Store DP audio handle inside DP display */
dp->dp_display.dp_audio = dp->audio;
@@ -1441,8 +1468,6 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
 
dp = container_of(dp_display, struct dp_display_private, dp_display);
 
-   dp_hpd_event_setup(dp);
-
dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foun

Re: [PATCH v2] drm/msm/dp: enhance both connect and disconnect pending_timeout handle

2022-04-15 Thread Kuogee Hsieh



On 4/14/2022 4:34 PM, Dmitry Baryshkov wrote:

On 15/04/2022 01:06, Kuogee Hsieh wrote:


On 4/8/2022 4:59 PM, Dmitry Baryshkov wrote:
On Fri, 8 Apr 2022 at 23:30, Kuogee Hsieh  
wrote:


On 4/8/2022 5:27 AM, Dmitry Baryshkov wrote:

On 07/04/2022 00:28, Kuogee Hsieh wrote:
dp_hpd_plug_handle() is responsible for setting up main link and 
send
uevent to notify user space framework to start video stream. 
Similarly,
dp_hdp_unplug_handle is responsible to send uevent to notify user 
space

framework to stop video stream and then tear down main link.
However there are rare cases, such as in the middle of system
suspending,
that uevent could not be delivered to user space framework. 
Therefore
some kind of recover mechanism armed by timer need to be in place 
in the

case of user space framework does not respond to uevent.

Hmm, how does userpsace 'respond' to the uevent? The driver should
send hotplug notifications to userspace, but it must not expect any
particular reaction. The userspace might be as simple, as fbdev
emulation, but the driver still should function correctly.

yes, driver is function correctly by setting up main link. but it does
not know which resolution to display.

It send hotplug notification through uevent to framework after main 
link

is ready.

Framework  is responsible to set up MDP timing engine to start 
video stream.



However it does not know which

It's of no concern to the driver. It is completely the userspace
problem. After resuming, it should reread available video output
properties. The display could have been changed while the system is
suspended.
 From your description I still do not understand why you need the
'recovery' mechanism.


I mean "recovery" means  dp driver may leave stay at link ready 
mistakenly after dongle unplugged due to missing framework action to 
tear down main link so that next dongle plug in will not work.


Currently it was armed with timeout function and it will fired if 
framework did not call msm_dp_display_disable() after 5 second.


framework = userspace?

Is my understanding correct? Currently DP driver sends a notification 
to userspace that DP is unplugged, waits for userspace to disable DP 
output, and only after that it will shutdown the link. Is this a 
correct description?

Yes, you are correct, connection need to be tear down from top to bottom.


If so, then yes, your change is correct. I mean that the kernel 
shouldn't wait for clients to stop using video pipeline if the sink 
gets unplugged. Instead it should tear the video stream down and let 
the DRM client cope with that.


I'm not sure how should the driver react if the client doesn't disable 
the output, but then the sink gets reattached?


I do not know that either.

But it should not happen as long as framework response to uevent.

And a bit more interesting question: how should the driver behave if 
the new sink is not compatible with the existing video stream.


When dongle plug/replug in, driver will always read sink's edid.

Therefore resolution database should be updated accordingly.





Anyway, we think this approach is not good. therefore it is replaced 
with  below patch.


drm/msm/dp: tear down main link at unplug handle immediately





Re: [RFC PATCH 1/6] drm/dp: Helpers to make it easier for drivers to use DP AUX bus properly

2022-04-15 Thread Doug Anderson
Hi,

On Fri, Apr 15, 2022 at 3:45 PM Dmitry Baryshkov
 wrote:
>
> On Sat, 16 Apr 2022 at 00:13, Doug Anderson  wrote:
> >
> > Hi,
> >
> > On Thu, Apr 14, 2022 at 5:47 PM Dmitry Baryshkov
> >  wrote:
> > >
> > > On 09/04/2022 05:36, Douglas Anderson wrote:
> > > > As talked about in the kerneldoc for "struct dp_aux_ep_client" in this
> > > > patch and also in the past in commit a1e3667a9835 ("drm/bridge:
> > > > ti-sn65dsi86: Promote the AUX channel to its own sub-dev"), to use the
> > > > DP AUX bus properly we really need two "struct device"s. One "struct
> > > > device" is in charge of providing the DP AUX bus and the other is
> > > > where we'll try to get a reference to the newly probed endpoint
> > > > devices.
> > > >
> > > > In ti-sn65dsi86 this wasn't too difficult to accomplish. That driver
> > > > is already broken up into several "struct devices" anyway because it
> > > > also provides a PWM and some GPIOs. Adding one more wasn't that
> > > > difficult / ugly.
> > > >
> > > > When I tried to do the same solution in parade-ps8640, it felt like I
> > > > was copying too much boilerplate code. I made the realization that I
> > > > didn't _really_ need a separate "driver" for each person that wanted
> > > > to do the same thing. By putting all the "driver" related code in a
> > > > common place then we could save a bit of hassle. This change
> > > > effectively adds a new "ep_client" driver that can be used by
> > > > anyone. The devices instantiated by this driver will just call through
> > > > to the probe/remove/shutdown calls provided.
> > > >
> > > > At the moment, the "ep_client" driver is backed by the Linux auxiliary
> > > > bus (unfortunate naming--this has nothing to do with DP AUX). I didn't
> > > > want to expose this to clients, though, so as far as clients are
> > > > concerned they get a vanilla "struct device".
> > >
> > > I have been thinking about your approach for quite some time. I think
> > > that enforcing a use of auxilliary device is an overkill. What do we
> > > really need is the the set callbacks in the bus struct or a notifier. We
> > > have to notify the aux_bus controller side that the client has been
> > > probed successfully or that the client is going to be removed.
> >
> > It seems like these new callbacks would be nearly the same as the
> > probe/remove callbacks in my proposal except:
> >
> > * They rely on there being exactly 1 AUX device, or we make it a rule
> > that we wait for all AUX devices to probe (?)
>
> Is the backlight a separate device on an AUX bus? Judging from
> drm_panel_dp_aux_backlight(), it isn't. I assumed that aux bus is just
> a point-to-point bus, so there is always a single client.

Define "device". ;-)

It's a seperate "struct device" from a Linux point of view since it's
a backlight class device. Certainly it's highly correlated to the
display, but one can conceptually think of them as different devices,
sorta. ;-)

I actually dug a tiny bit more into the whole "touchscreen over aux".
I guess DP 1.2 has a standard of "USB over DP AUX". No idea how that
would be modeled, of course.

I guess the summary is that I'm OK w/ changing it to assume one device
for now, but I'm still not sure it's compelling to move to normal
callbacks. The API for callbacks is pretty much the same as the one I
proposed and IMO leaving it the way it is (with an extra struct
device) doesn't really add much complexity and has a few (small) nice
benefits.


> > * We need to come up with a system for detecting when everything
> > probes or is going to be removed, though that's probably not too hard.
> > I guess the DP AUX bus could just replace the panel's probe function
> > with its own and essentially "tail patch" it. I guess it could "head
> > patch" the remove call? ...or is there some better way you were
> > thinking of knowing when all our children probed?
> >
> > * The callback on the aux bus controller side would not be able to
> > DEFER. In other words trying to acquire a reference to the panel can
> > always be the last thing we do so we know there can be no reasons to
> > defer after. This should be doable, but at least in the ps8640 case it
> > will require changing the code a bit. I notice that today it actually
> > tries to get the panel side _before_ it gets the MIPI side and it
> > potentially can return -EPROBE_DEFER if it can't find the MIPI side. I
> > guess I have a niggling feeling that we'll find some reason in the
> > future that we can't be last, but we can probably ignore that. ;-)
> >
> > I can switch this all to normal callbacks if that's what everyone
> > wants, but it doesn't feel significantly cleaner to me and does seem
> > to have some (small) downsides.
> >
> >
> > > And this
> > > approach would make driver's life easier, since e.g. the bus code can
> > > pm_get the EP device before calling callbacks/notifiers and
> > > pm_put_autosuspend it afterwards.
> >
> > Not sure about doing the pm calls on behalf of the EP device. What's
> > t

Re: [RFC PATCH 4/6] drm/panel-edp: Take advantage of is_hpd_asserted() in struct drm_dp_aux

2022-04-15 Thread Doug Anderson
Hi,

On Fri, Apr 15, 2022 at 3:12 PM Dmitry Baryshkov
 wrote:
>
> On Sat, 16 Apr 2022 at 00:17, Doug Anderson  wrote:
> >
> > Hi,
> >
> > On Thu, Apr 14, 2022 at 5:51 PM Dmitry Baryshkov
> >  wrote:
> > >
> > > On 09/04/2022 05:36, Douglas Anderson wrote:
> > > > Let's add support for being able to read the HPD pin even if it's
> > > > hooked directly to the controller. This will allow us to get more
> > > > accurate delays also lets us take away the waiting in the AUX transfer
> > > > functions of the eDP controller drivers.
> > > >
> > > > Signed-off-by: Douglas Anderson 
> > > > ---
> > > >
> > > >   drivers/gpu/drm/panel/panel-edp.c | 37 ++-
> > > >   1 file changed, 31 insertions(+), 6 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/panel/panel-edp.c 
> > > > b/drivers/gpu/drm/panel/panel-edp.c
> > > > index 1732b4f56e38..4a143eb9544b 100644
> > > > --- a/drivers/gpu/drm/panel/panel-edp.c
> > > > +++ b/drivers/gpu/drm/panel/panel-edp.c
> > > > @@ -417,6 +417,19 @@ static int panel_edp_get_hpd_gpio(struct device 
> > > > *dev, struct panel_edp *p)
> > > >   return 0;
> > > >   }
> > > >
> > > > +static bool panel_edp_can_read_hpd(struct panel_edp *p)
> > > > +{
> > > > + return !p->no_hpd && (p->hpd_gpio || (p->aux && 
> > > > p->aux->is_hpd_asserted));
> > > > +}
> > > > +
> > > > +static bool panel_edp_read_hpd(struct panel_edp *p)
> > > > +{
> > > > + if (p->hpd_gpio)
> > > > + return gpiod_get_value_cansleep(p->hpd_gpio);
> > > > +
> > > > + return p->aux->is_hpd_asserted(p->aux);
> > > > +}
> > > > +
> > > >   static int panel_edp_prepare_once(struct panel_edp *p)
> > > >   {
> > > >   struct device *dev = p->base.dev;
> > > > @@ -441,13 +454,21 @@ static int panel_edp_prepare_once(struct 
> > > > panel_edp *p)
> > > >   if (delay)
> > > >   msleep(delay);
> > > >
> > > > - if (p->hpd_gpio) {
> > > > + if (panel_edp_can_read_hpd(p)) {
> > > >   if (p->desc->delay.hpd_absent)
> > > >   hpd_wait_us = p->desc->delay.hpd_absent * 1000UL;
> > > >   else
> > > >   hpd_wait_us = 200;
> > > >
> > > > - err = readx_poll_timeout(gpiod_get_value_cansleep, 
> > > > p->hpd_gpio,
> > > > + /*
> > > > +  * Extra max delay, mostly to account for ps8640. ps8640
> > > > +  * is crazy and the bridge chip driver itself has over 
> > > > 200 ms
> > > > +  * of delay if it needs to do the pm_runtime resume of the
> > > > +  * bridge chip to read the HPD.
> > > > +  */
> > > > + hpd_wait_us += 300;
> > >
> > > I think this should come in a separate commit and ideally this should be
> > > configurable somehow. Other hosts wouldn't need such 'additional' delay.
> > >
> > > With this change removed:
> > >
> > > Reviewed-by: Dmitry Baryshkov 
> >
> > What would you think about changing the API slightly? Instead of
> > is_hpd_asserted(), we change it to wait_hpd_asserted() and it takes a
> > timeout in microseconds. If you pass 0 for the timeout the function is
> > defined to behave the same as is_hpd_asserted() today--AKA a single
> > poll of the line.
>
> This might work. Can you check it, please?

Cool. I'll spin with this. Hopefully early next week unless my inbox
blows up. ...or my main PC's SSD like happened this week. ;-)


> BTW: are these changes dependent on the first part of the patchset? It
> might be worth splitting the patchset into two parts.

Definitely not. As per the cover letter, this is two series jammed
into one. I'm happy to split them up. The 2nd half seems much less
controversial.

-Doug


Re: [RFC PATCH 4/6] drm/panel-edp: Take advantage of is_hpd_asserted() in struct drm_dp_aux

2022-04-15 Thread Dmitry Baryshkov

On 16/04/2022 03:12, Doug Anderson wrote:

Hi,

On Fri, Apr 15, 2022 at 3:12 PM Dmitry Baryshkov
 wrote:


On Sat, 16 Apr 2022 at 00:17, Doug Anderson  wrote:


Hi,

On Thu, Apr 14, 2022 at 5:51 PM Dmitry Baryshkov
 wrote:


On 09/04/2022 05:36, Douglas Anderson wrote:

Let's add support for being able to read the HPD pin even if it's
hooked directly to the controller. This will allow us to get more
accurate delays also lets us take away the waiting in the AUX transfer
functions of the eDP controller drivers.

Signed-off-by: Douglas Anderson 
---

   drivers/gpu/drm/panel/panel-edp.c | 37 ++-
   1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-edp.c 
b/drivers/gpu/drm/panel/panel-edp.c
index 1732b4f56e38..4a143eb9544b 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -417,6 +417,19 @@ static int panel_edp_get_hpd_gpio(struct device *dev, 
struct panel_edp *p)
   return 0;
   }

+static bool panel_edp_can_read_hpd(struct panel_edp *p)
+{
+ return !p->no_hpd && (p->hpd_gpio || (p->aux && p->aux->is_hpd_asserted));
+}
+
+static bool panel_edp_read_hpd(struct panel_edp *p)
+{
+ if (p->hpd_gpio)
+ return gpiod_get_value_cansleep(p->hpd_gpio);
+
+ return p->aux->is_hpd_asserted(p->aux);
+}
+
   static int panel_edp_prepare_once(struct panel_edp *p)
   {
   struct device *dev = p->base.dev;
@@ -441,13 +454,21 @@ static int panel_edp_prepare_once(struct panel_edp *p)
   if (delay)
   msleep(delay);

- if (p->hpd_gpio) {
+ if (panel_edp_can_read_hpd(p)) {
   if (p->desc->delay.hpd_absent)
   hpd_wait_us = p->desc->delay.hpd_absent * 1000UL;
   else
   hpd_wait_us = 200;

- err = readx_poll_timeout(gpiod_get_value_cansleep, p->hpd_gpio,
+ /*
+  * Extra max delay, mostly to account for ps8640. ps8640
+  * is crazy and the bridge chip driver itself has over 200 ms
+  * of delay if it needs to do the pm_runtime resume of the
+  * bridge chip to read the HPD.
+  */
+ hpd_wait_us += 300;


I think this should come in a separate commit and ideally this should be
configurable somehow. Other hosts wouldn't need such 'additional' delay.

With this change removed:

Reviewed-by: Dmitry Baryshkov 


What would you think about changing the API slightly? Instead of
is_hpd_asserted(), we change it to wait_hpd_asserted() and it takes a
timeout in microseconds. If you pass 0 for the timeout the function is
defined to behave the same as is_hpd_asserted() today--AKA a single
poll of the line.


This might work. Can you check it, please?


Cool. I'll spin with this. Hopefully early next week unless my inbox
blows up. ...or my main PC's SSD like happened this week. ;-)



BTW: are these changes dependent on the first part of the patchset? It
might be worth splitting the patchset into two parts.


Definitely not. As per the cover letter, this is two series jammed
into one. I'm happy to split them up. The 2nd half seems much less
controversial.


Great, let's get it in then. As you have time.


--
With best wishes
Dmitry


[PATCH 1/3] drm/msm: remove explicit devfreq status reset

2022-04-15 Thread Chia-I Wu
It is redundant since commit 7c0ffcd40b16 ("drm/msm/gpu: Respect PM QoS
constraints") because dev_pm_qos_update_request triggers get_dev_status.

Signed-off-by: Chia-I Wu 
Cc: Rob Clark 
---
 drivers/gpu/drm/msm/msm_gpu_devfreq.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c 
b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
index 12641616acd3..317a95d42922 100644
--- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c
+++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
@@ -224,7 +224,6 @@ void msm_devfreq_boost(struct msm_gpu *gpu, unsigned factor)
 void msm_devfreq_active(struct msm_gpu *gpu)
 {
struct msm_gpu_devfreq *df = &gpu->devfreq;
-   struct devfreq_dev_status status;
unsigned int idle_time;
 
if (!has_devfreq(gpu))
@@ -248,12 +247,6 @@ void msm_devfreq_active(struct msm_gpu *gpu)
 
dev_pm_qos_update_request(&df->idle_freq,
  PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
-
-   /*
-* Reset the polling interval so we aren't inconsistent
-* about freq vs busy/total cycles
-*/
-   msm_devfreq_get_dev_status(&gpu->pdev->dev, &status);
 }
 
 
-- 
2.36.0.rc0.470.gd361397f0d-goog



[PATCH 2/3] drm/msm: simplify gpu_busy callback

2022-04-15 Thread Chia-I Wu
Move tracking and busy time calculation to msm_devfreq_get_dev_status.

Signed-off-by: Chia-I Wu 
Cc: Rob Clark 
---
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 19 ++--
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 15 +
 drivers/gpu/drm/msm/msm_gpu.h |  9 +++-
 drivers/gpu/drm/msm/msm_gpu_devfreq.c | 32 ++-
 4 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 407f50a15faa..217615e0e850 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1662,28 +1662,23 @@ static struct msm_ringbuffer *a5xx_active_ring(struct 
msm_gpu *gpu)
return a5xx_gpu->cur_ring;
 }
 
-static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu)
+static u64 a5xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate)
 {
-   u64 busy_cycles, busy_time;
+   u64 busy_cycles;
 
/* Only read the gpu busy if the hardware is already active */
-   if (pm_runtime_get_if_in_use(&gpu->pdev->dev) == 0)
+   if (pm_runtime_get_if_in_use(&gpu->pdev->dev) == 0) {
+   *out_sample_rate = 1;
return 0;
+   }
 
busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
-
-   busy_time = busy_cycles - gpu->devfreq.busy_cycles;
-   do_div(busy_time, clk_get_rate(gpu->core_clk) / 100);
-
-   gpu->devfreq.busy_cycles = busy_cycles;
+   *out_sample_rate = clk_get_rate(gpu->core_clk);
 
pm_runtime_put(&gpu->pdev->dev);
 
-   if (WARN_ON(busy_time > ~0LU))
-   return ~0LU;
-
-   return (unsigned long)busy_time;
+   return busy_cycles;
 }
 
 static uint32_t a5xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index ccc4fcf7a630..fba6259395dd 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1649,12 +1649,14 @@ static void a6xx_destroy(struct msm_gpu *gpu)
kfree(a6xx_gpu);
 }
 
-static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
+static u64 a6xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate)
 {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
-   u64 busy_cycles, busy_time;
+   u64 busy_cycles;
 
+   /* 19.2MHz */
+   *out_sample_rate = 1920;
 
/* Only read the gpu busy if the hardware is already active */
if (pm_runtime_get_if_in_use(a6xx_gpu->gmu.dev) == 0)
@@ -1664,17 +1666,10 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L,
REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H);
 
-   busy_time = (busy_cycles - gpu->devfreq.busy_cycles) * 10;
-   do_div(busy_time, 192);
-
-   gpu->devfreq.busy_cycles = busy_cycles;
 
pm_runtime_put(a6xx_gpu->gmu.dev);
 
-   if (WARN_ON(busy_time > ~0LU))
-   return ~0LU;
-
-   return (unsigned long)busy_time;
+   return busy_cycles;
 }
 
 static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 02419f2ca2bc..389c6dab751b 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -62,7 +62,7 @@ struct msm_gpu_funcs {
/* for generation specific debugfs: */
void (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
 #endif
-   unsigned long (*gpu_busy)(struct msm_gpu *gpu);
+   u64 (*gpu_busy)(struct msm_gpu *gpu, unsigned long *out_sample_rate);
struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);
int (*gpu_state_put)(struct msm_gpu_state *state);
unsigned long (*gpu_get_freq)(struct msm_gpu *gpu);
@@ -106,11 +106,8 @@ struct msm_gpu_devfreq {
struct dev_pm_qos_request boost_freq;
 
/**
-* busy_cycles:
-*
-* Used by implementation of gpu->gpu_busy() to track the last
-* busy counter value, for calculating elapsed busy cycles since
-* last sampling period.
+* busy_cycles: Last busy counter value, for calculating elapsed busy
+* cycles since last sampling period.
 */
u64 busy_cycles;
 
diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c 
b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
index 317a95d42922..f531015107c3 100644
--- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c
+++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
@@ -49,18 +49,38 @@ static unsigned long get_freq(struct msm_gpu *gpu)
return clk_get_rate(gpu->core_clk);
 }
 
-static int msm_devfreq_get_dev_status(struct device *dev,
+static void get_raw_dev_status(struct msm_gpu *gpu,
struct devfreq_dev_statu

[PATCH 3/3] drm/msm: return the average load over the polling period

2022-04-15 Thread Chia-I Wu
simple_ondemand interacts poorly with clamp_to_idle.  It only looks at
the load since the last get_dev_status call, while it should really look
at the load over polling_ms.  When clamp_to_idle true, it almost always
picks the lowest frequency on active because the gpu is idle between
msm_devfreq_idle/msm_devfreq_active.

This logic could potentially be moved into devfreq core.

Fixes: 7c0ffcd40b16 ("drm/msm/gpu: Respect PM QoS constraints")
Signed-off-by: Chia-I Wu 
Cc: Rob Clark 
---
 drivers/gpu/drm/msm/msm_gpu.h |  3 ++
 drivers/gpu/drm/msm/msm_gpu_devfreq.c | 60 ++-
 2 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 389c6dab751b..143c56f5185b 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -9,6 +9,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -117,6 +118,8 @@ struct msm_gpu_devfreq {
/** idle_time: Time of last transition to idle: */
ktime_t idle_time;
 
+   struct devfreq_dev_status average_status;
+
/**
 * idle_work:
 *
diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c 
b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
index f531015107c3..d2539ca78c29 100644
--- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c
+++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
@@ -9,6 +9,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -75,12 +76,69 @@ static void get_raw_dev_status(struct msm_gpu *gpu,
status->busy_time = busy_time;
 }
 
+static void update_average_dev_status(struct msm_gpu *gpu,
+   const struct devfreq_dev_status *raw)
+{
+   struct msm_gpu_devfreq *df = &gpu->devfreq;
+   const u32 polling_ms = df->devfreq->profile->polling_ms;
+   const u32 max_history_ms = polling_ms * 11 / 10;
+   struct devfreq_dev_status *avg = &df->average_status;
+   u64 avg_freq;
+
+   /* simple_ondemand governor interacts poorly with gpu->clamp_to_idle.
+* When we enforce the constraint on idle, it calls get_dev_status
+* which would normally reset the stats.  When we remove the
+* constraint on active, it calls get_dev_status again where busy_time
+* would be 0.
+*
+* To remedy this, we always return the average load over the past
+* polling_ms.
+*/
+
+   /* raw is longer than polling_ms or avg has no history */
+   if (div_u64(raw->total_time, USEC_PER_MSEC) >= polling_ms ||
+   !avg->total_time) {
+   *avg = *raw;
+   return;
+   }
+
+   /* Truncate the oldest history first.
+*
+* Because we keep the history with a single devfreq_dev_status,
+* rather than a list of devfreq_dev_status, we have to assume freq
+* and load are the same over avg->total_time.  We can scale down
+* avg->busy_time and avg->total_time by the same factor to drop
+* history.
+*/
+   if (div_u64(avg->total_time + raw->total_time, USEC_PER_MSEC) >=
+   max_history_ms) {
+   const u32 new_total_time = polling_ms * USEC_PER_MSEC -
+   raw->total_time;
+   avg->busy_time = div_u64(
+   mul_u32_u32(avg->busy_time, new_total_time),
+   avg->total_time);
+   avg->total_time = new_total_time;
+   }
+
+   /* compute the average freq over avg->total_time + raw->total_time */
+   avg_freq = mul_u32_u32(avg->current_frequency, avg->total_time);
+   avg_freq += mul_u32_u32(raw->current_frequency, raw->total_time);
+   do_div(avg_freq, avg->total_time + raw->total_time);
+
+   avg->current_frequency = avg_freq;
+   avg->busy_time += raw->busy_time;
+   avg->total_time += raw->total_time;
+}
+
 static int msm_devfreq_get_dev_status(struct device *dev,
struct devfreq_dev_status *status)
 {
struct msm_gpu *gpu = dev_to_gpu(dev);
+   struct devfreq_dev_status raw;
 
-   get_raw_dev_status(gpu, status);
+   get_raw_dev_status(gpu, &raw);
+   update_average_dev_status(gpu, &raw);
+   *status = gpu->devfreq.average_status;
 
return 0;
 }
-- 
2.36.0.rc0.470.gd361397f0d-goog



Re: [PATCH 3/3] drm/msm: return the average load over the polling period

2022-04-15 Thread Chia-I Wu
On Fri, Apr 15, 2022 at 5:33 PM Chia-I Wu  wrote:
>
> simple_ondemand interacts poorly with clamp_to_idle.  It only looks at
> the load since the last get_dev_status call, while it should really look
> at the load over polling_ms.  When clamp_to_idle true, it almost always
> picks the lowest frequency on active because the gpu is idle between
> msm_devfreq_idle/msm_devfreq_active.
>
> This logic could potentially be moved into devfreq core.
The idea is to extend devfreq_simple_ondemand_data to specify whether
devfreq_simple_ondemand_func should use "last status" or "average
status" to determine the target frequency.  devfreq core will need to
store "struct devfreq_dev_status average_status", which will be
updated when a device uses simple_ondemand and asks for average_status
instead of last_status.



>
> Fixes: 7c0ffcd40b16 ("drm/msm/gpu: Respect PM QoS constraints")
> Signed-off-by: Chia-I Wu 
> Cc: Rob Clark 
> ---
>  drivers/gpu/drm/msm/msm_gpu.h |  3 ++
>  drivers/gpu/drm/msm/msm_gpu_devfreq.c | 60 ++-
>  2 files changed, 62 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
> index 389c6dab751b..143c56f5185b 100644
> --- a/drivers/gpu/drm/msm/msm_gpu.h
> +++ b/drivers/gpu/drm/msm/msm_gpu.h
> @@ -9,6 +9,7 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -117,6 +118,8 @@ struct msm_gpu_devfreq {
> /** idle_time: Time of last transition to idle: */
> ktime_t idle_time;
>
> +   struct devfreq_dev_status average_status;
> +
> /**
>  * idle_work:
>  *
> diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c 
> b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
> index f531015107c3..d2539ca78c29 100644
> --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c
> +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
> @@ -9,6 +9,7 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
>
>  /*
> @@ -75,12 +76,69 @@ static void get_raw_dev_status(struct msm_gpu *gpu,
> status->busy_time = busy_time;
>  }
>
> +static void update_average_dev_status(struct msm_gpu *gpu,
> +   const struct devfreq_dev_status *raw)
> +{
> +   struct msm_gpu_devfreq *df = &gpu->devfreq;
> +   const u32 polling_ms = df->devfreq->profile->polling_ms;
> +   const u32 max_history_ms = polling_ms * 11 / 10;
> +   struct devfreq_dev_status *avg = &df->average_status;
> +   u64 avg_freq;
> +
> +   /* simple_ondemand governor interacts poorly with gpu->clamp_to_idle.
> +* When we enforce the constraint on idle, it calls get_dev_status
> +* which would normally reset the stats.  When we remove the
> +* constraint on active, it calls get_dev_status again where busy_time
> +* would be 0.
> +*
> +* To remedy this, we always return the average load over the past
> +* polling_ms.
> +*/
> +
> +   /* raw is longer than polling_ms or avg has no history */
> +   if (div_u64(raw->total_time, USEC_PER_MSEC) >= polling_ms ||
> +   !avg->total_time) {
> +   *avg = *raw;
> +   return;
> +   }
> +
> +   /* Truncate the oldest history first.
> +*
> +* Because we keep the history with a single devfreq_dev_status,
> +* rather than a list of devfreq_dev_status, we have to assume freq
> +* and load are the same over avg->total_time.  We can scale down
> +* avg->busy_time and avg->total_time by the same factor to drop
> +* history.
> +*/
> +   if (div_u64(avg->total_time + raw->total_time, USEC_PER_MSEC) >=
> +   max_history_ms) {
> +   const u32 new_total_time = polling_ms * USEC_PER_MSEC -
> +   raw->total_time;
> +   avg->busy_time = div_u64(
> +   mul_u32_u32(avg->busy_time, new_total_time),
> +   avg->total_time);
> +   avg->total_time = new_total_time;
> +   }
> +
> +   /* compute the average freq over avg->total_time + raw->total_time */
> +   avg_freq = mul_u32_u32(avg->current_frequency, avg->total_time);
> +   avg_freq += mul_u32_u32(raw->current_frequency, raw->total_time);
> +   do_div(avg_freq, avg->total_time + raw->total_time);
> +
> +   avg->current_frequency = avg_freq;
> +   avg->busy_time += raw->busy_time;
> +   avg->total_time += raw->total_time;
> +}
> +
>  static int msm_devfreq_get_dev_status(struct device *dev,
> struct devfreq_dev_status *status)
>  {
> struct msm_gpu *gpu = dev_to_gpu(dev);
> +   struct devfreq_dev_status raw;
>
> -   get_raw_dev_status(gpu, status);
> +   get_raw_dev_status(gpu, &raw);
> +   update_average_dev_status(gpu, &raw);
> +   *status = gpu->devfreq.average_status;
>
> return 0;
>  }
> --
> 2.36.0.rc0.470.gd361397f0d-goog
>


Re: [RFC PATCH 1/6] drm/dp: Helpers to make it easier for drivers to use DP AUX bus properly

2022-04-15 Thread Dmitry Baryshkov

On 16/04/2022 03:09, Doug Anderson wrote:

Hi,

On Fri, Apr 15, 2022 at 3:45 PM Dmitry Baryshkov
 wrote:


On Sat, 16 Apr 2022 at 00:13, Doug Anderson  wrote:


Hi,

On Thu, Apr 14, 2022 at 5:47 PM Dmitry Baryshkov
 wrote:


On 09/04/2022 05:36, Douglas Anderson wrote:

As talked about in the kerneldoc for "struct dp_aux_ep_client" in this
patch and also in the past in commit a1e3667a9835 ("drm/bridge:
ti-sn65dsi86: Promote the AUX channel to its own sub-dev"), to use the
DP AUX bus properly we really need two "struct device"s. One "struct
device" is in charge of providing the DP AUX bus and the other is
where we'll try to get a reference to the newly probed endpoint
devices.

In ti-sn65dsi86 this wasn't too difficult to accomplish. That driver
is already broken up into several "struct devices" anyway because it
also provides a PWM and some GPIOs. Adding one more wasn't that
difficult / ugly.

When I tried to do the same solution in parade-ps8640, it felt like I
was copying too much boilerplate code. I made the realization that I
didn't _really_ need a separate "driver" for each person that wanted
to do the same thing. By putting all the "driver" related code in a
common place then we could save a bit of hassle. This change
effectively adds a new "ep_client" driver that can be used by
anyone. The devices instantiated by this driver will just call through
to the probe/remove/shutdown calls provided.

At the moment, the "ep_client" driver is backed by the Linux auxiliary
bus (unfortunate naming--this has nothing to do with DP AUX). I didn't
want to expose this to clients, though, so as far as clients are
concerned they get a vanilla "struct device".


I have been thinking about your approach for quite some time. I think
that enforcing a use of auxilliary device is an overkill. What do we
really need is the the set callbacks in the bus struct or a notifier. We
have to notify the aux_bus controller side that the client has been
probed successfully or that the client is going to be removed.


It seems like these new callbacks would be nearly the same as the
probe/remove callbacks in my proposal except:

* They rely on there being exactly 1 AUX device, or we make it a rule
that we wait for all AUX devices to probe (?)


Is the backlight a separate device on an AUX bus? Judging from
drm_panel_dp_aux_backlight(), it isn't. I assumed that aux bus is just
a point-to-point bus, so there is always a single client.


Define "device". ;-)


"a device on the AUX bus" = the device, which lists dp_aux_bus_type as 
dev->bus_type.




It's a seperate "struct device" from a Linux point of view since it's
a backlight class device. Certainly it's highly correlated to the
display, but one can conceptually think of them as different devices,
sorta. ;-)

I actually dug a tiny bit more into the whole "touchscreen over aux".
I guess DP 1.2 has a standard of "USB over DP AUX". No idea how that
would be modeled, of course.


Ugh. Do you have any details of the standard itself? Like how does it 
looks like from the host point of view. And if the AUX is required to be 
powered for this USB bus to work?


In other words: if we were to model it at this moment, would it be the 
child of the panel device (like backlight) or a separate device sitting 
on the same AUX bus?




I guess the summary is that I'm OK w/ changing it to assume one device
for now, but I'm still not sure it's compelling to move to normal
callbacks. The API for callbacks is pretty much the same as the one I
proposed and IMO leaving it the way it is (with an extra struct
device) doesn't really add much complexity and has a few (small) nice
benefits.


I think Stephen didn't like too many similarities between 
dp_aux_ep_client and dp_aux_ep_device. And I'd second him here.




* We need to come up with a system for detecting when everything
probes or is going to be removed, though that's probably not too hard.
I guess the DP AUX bus could just replace the panel's probe function
with its own and essentially "tail patch" it. I guess it could "head
patch" the remove call? ...or is there some better way you were
thinking of knowing when all our children probed?

* The callback on the aux bus controller side would not be able to
DEFER. In other words trying to acquire a reference to the panel can
always be the last thing we do so we know there can be no reasons to
defer after. This should be doable, but at least in the ps8640 case it
will require changing the code a bit. I notice that today it actually
tries to get the panel side _before_ it gets the MIPI side and it
potentially can return -EPROBE_DEFER if it can't find the MIPI side. I
guess I have a niggling feeling that we'll find some reason in the
future that we can't be last, but we can probably ignore that. ;-)

I can switch this all to normal callbacks if that's what everyone
wants, but it doesn't feel significantly cleaner to me and does seem
to have some (small) downsides.



And this
approach would make driver's li

[PATCH 1/2] dt-bindings: display: simple: Add DataImage FG040346DSSWBG04 compatible string

2022-04-15 Thread Marek Vasut
Add DataImage FG040346DSSWBG04 4.3" 480x272 TFT LCD 24bit DPI panel
compatible string.

Signed-off-by: Marek Vasut 
Cc: Rob Herring 
Cc: Sam Ravnborg 
Cc: Thomas Zimmermann 
Cc: devicet...@vger.kernel.org
To: dri-devel@lists.freedesktop.org
---
 .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml 
b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 1eb9dd4f8f58e..cfe7bb9f89de6 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -105,6 +105,8 @@ properties:
   - chunghwa,claa101wb01
 # Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel
   - chunghwa,claa101wb03
+# DataImage, Inc. 4.3" WQVGA (480x272) TFT LCD panel with 24-bit 
parallel interface.
+  - dataimage,fg040346dsswbg04
 # DataImage, Inc. 7" WVGA (800x480) TFT LCD panel with 24-bit parallel 
interface.
   - dataimage,scf0700c48ggu18
 # DLC Display Co. DLC1010GIG 10.1" WXGA TFT LCD Panel
-- 
2.35.1



[PATCH 2/2] drm/panel: simple: Add DataImage FG040346DSSWBG04 panel support

2022-04-15 Thread Marek Vasut
Add DataImage FG040346DSSWBG04 4.3" 480x272 TFT LCD 24bit DPI panel
support.

Signed-off-by: Marek Vasut 
Cc: Sam Ravnborg 
Cc: Thomas Zimmermann 
To: dri-devel@lists.freedesktop.org
---
 drivers/gpu/drm/panel/panel-simple.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index a34f4198a5341..3c35f8a32d327 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1402,6 +1402,31 @@ static const struct panel_desc chunghwa_claa101wb01 = {
.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
+static const struct display_timing dataimage_fg040346dsswbg04_timing = {
+   .pixelclock = { 500, 900, 1200 },
+   .hactive = { 480, 480, 480 },
+   .hfront_porch = { 12, 12, 12 },
+   .hback_porch = { 12, 12, 12 },
+   .hsync_len = { 21, 21, 21 },
+   .vactive = { 272, 272, 272 },
+   .vfront_porch = { 4, 4, 4 },
+   .vback_porch = { 4, 4, 4 },
+   .vsync_len = { 8, 8, 8 },
+};
+
+static const struct panel_desc dataimage_fg040346dsswbg04 = {
+   .timings = &dataimage_fg040346dsswbg04_timing,
+   .num_timings = 1,
+   .bpc = 8,
+   .size = {
+   .width = 95,
+   .height = 54,
+   },
+   .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+   .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
+   .connector_type = DRM_MODE_CONNECTOR_DPI,
+};
+
 static const struct drm_display_mode dataimage_scf0700c48ggu18_mode = {
.clock = 33260,
.hdisplay = 800,
@@ -3768,6 +3793,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "chunghwa,claa101wb01",
.data = &chunghwa_claa101wb01
+   }, {
+   .compatible = "dataimage,fg040346dsswbg04",
+   .data = &dataimage_fg040346dsswbg04,
}, {
.compatible = "dataimage,scf0700c48ggu18",
.data = &dataimage_scf0700c48ggu18,
-- 
2.35.1