Re: [PATCH] drm/bridge: anx7625: Fill in empty ELD when no connector

2022-04-18 Thread Xin Ji
On Thu, Apr 14, 2022 at 05:00:04PM +0800, Hsin-Yi Wang wrote:
> Speaker may share I2S with DP and .get_eld callback will be called when
> speaker is playing. When HDMI wans't connected, the connector will be
> null. Instead of return an error, fill in empty ELD.
> 
> Signed-off-by: Hsin-Yi Wang 
> ---
>  drivers/gpu/drm/bridge/analogix/anx7625.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
> b/drivers/gpu/drm/bridge/analogix/anx7625.c
> index 6516f9570b86..f2bc30c98c77 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> @@ -1932,14 +1932,14 @@ static int anx7625_audio_get_eld(struct device *dev, 
> void *data,
>   struct anx7625_data *ctx = dev_get_drvdata(dev);
>  
>   if (!ctx->connector) {
> - dev_err(dev, "connector not initial\n");
> - return -EINVAL;
> + /* Pass en empty ELD if connector not available */
> + memset(buf, 0, len);
> + } else {
> + dev_dbg(dev, "audio copy eld\n");
> + memcpy(buf, ctx->connector->eld,
> +min(sizeof(ctx->connector->eld), len));
>   }
>  
> - dev_dbg(dev, "audio copy eld\n");
> - memcpy(buf, ctx->connector->eld,
> -min(sizeof(ctx->connector->eld), len));
> -
>   return 0;
Hi Hsin-Yi, it's OK for me.
Reviewed-by: Xin Ji 

Thanks,
Xin
>  }
>  
> -- 
> 2.35.1.1178.g4f1659d476-goog


[PATCH resend v8 5/5] phy: freescale: phy-fsl-imx8-mipi-dphy: Add i.MX8qxp LVDS PHY mode support

2022-04-18 Thread Liu Ying
i.MX8qxp SoC embeds a Mixel MIPI DPHY + LVDS PHY combo which supports
either a MIPI DSI display or a LVDS display.  The PHY mode is controlled
by SCU firmware and the driver would call a SCU firmware function to
configure the PHY mode.  The single LVDS PHY has 4 data lanes to support
a LVDS display.  Also, with a master LVDS PHY and a slave LVDS PHY, they
may work together to support a LVDS display with 8 data lanes(usually, dual
LVDS link display).  Note that this patch supports the LVDS PHY mode only
for the i.MX8qxp Mixel combo PHY, i.e., the MIPI DPHY mode is yet to be
supported, so for now error would be returned from ->set_mode() if MIPI
DPHY mode is passed over to it for the combo PHY.

Cc: Guido Günther 
Cc: Robert Chiras 
Cc: Kishon Vijay Abraham I 
Cc: Vinod Koul 
Cc: Shawn Guo 
Cc: Sascha Hauer 
Cc: Pengutronix Kernel Team 
Cc: Fabio Estevam 
Cc: NXP Linux Team 
Reviewed-by: Guido Günther 
Signed-off-by: Liu Ying 
---
v7->v8:
* No change.

v6->v7:
* Use marco instead of magic number for CCM and CA values.
* Suppress 'checkpatch --strict' warnings.
* Check !opts in mixel_dphy_configure().

v5->v6:
* No change.

v4->v5:
* No change.

v3->v4:
* Add Guido's R-b tag.

v2->v3:
* Improve readability of mixel_dphy_set_mode(). (Guido)

v1->v2:
* Print invalid PHY mode in dmesg. (Guido)

 .../phy/freescale/phy-fsl-imx8-mipi-dphy.c| 276 +-
 1 file changed, 265 insertions(+), 11 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c 
b/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c
index a95572b397ca..e625b32889bf 100644
--- a/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c
+++ b/drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c
@@ -4,17 +4,33 @@
  * Copyright 2019 Purism SPC
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
+
+/* Control and Status Registers(CSR) */
+#define PHY_CTRL   0x00
+#define  CCM_MASK  GENMASK(7, 5)
+#define  CCM(n)FIELD_PREP(CCM_MASK, (n))
+#define  CCM_1_2V  0x5
+#define  CA_MASK   GENMASK(4, 2)
+#define  CA_3_51MA 0x4
+#define  CA(n) FIELD_PREP(CA_MASK, (n))
+#define  RFB   BIT(1)
+#define  LVDS_EN   BIT(0)
 
 /* DPHY registers */
 #define DPHY_PD_DPHY   0x00
@@ -55,8 +71,15 @@
 #define PWR_ON 0
 #define PWR_OFF1
 
+#define MIN_VCO_FREQ 64000
+#define MAX_VCO_FREQ 15
+
+#define MIN_LVDS_REFCLK_FREQ 2400
+#define MAX_LVDS_REFCLK_FREQ 15000
+
 enum mixel_dphy_devtype {
MIXEL_IMX8MQ,
+   MIXEL_IMX8QXP,
 };
 
 struct mixel_dphy_devdata {
@@ -65,6 +88,7 @@ struct mixel_dphy_devdata {
u8 reg_rxlprp;
u8 reg_rxcdrp;
u8 reg_rxhs_settle;
+   bool is_combo;  /* MIPI DPHY and LVDS PHY combo */
 };
 
 static const struct mixel_dphy_devdata mixel_dphy_devdata[] = {
@@ -74,6 +98,10 @@ static const struct mixel_dphy_devdata mixel_dphy_devdata[] 
= {
.reg_rxlprp = 0x40,
.reg_rxcdrp = 0x44,
.reg_rxhs_settle = 0x48,
+   .is_combo = false,
+   },
+   [MIXEL_IMX8QXP] = {
+   .is_combo = true,
},
 };
 
@@ -95,8 +123,12 @@ struct mixel_dphy_cfg {
 struct mixel_dphy_priv {
struct mixel_dphy_cfg cfg;
struct regmap *regmap;
+   struct regmap *lvds_regmap;
struct clk *phy_ref_clk;
const struct mixel_dphy_devdata *devdata;
+   struct imx_sc_ipc *ipc_handle;
+   bool is_slave;
+   int id;
 };
 
 static const struct regmap_config mixel_dphy_regmap_config = {
@@ -317,7 +349,8 @@ static int mixel_dphy_set_pll_params(struct phy *phy)
return 0;
 }
 
-static int mixel_dphy_configure(struct phy *phy, union phy_configure_opts 
*opts)
+static int
+mixel_dphy_configure_mipi_dphy(struct phy *phy, union phy_configure_opts *opts)
 {
struct mixel_dphy_priv *priv = phy_get_drvdata(phy);
struct mixel_dphy_cfg cfg = { 0 };
@@ -345,15 +378,126 @@ static int mixel_dphy_configure(struct phy *phy, union 
phy_configure_opts *opts)
return 0;
 }
 
+static int
+mixel_dphy_configure_lvds_phy(struct phy *phy, union phy_configure_opts *opts)
+{
+   struct mixel_dphy_priv *priv = phy_get_drvdata(phy);
+   struct phy_configure_opts_lvds *lvds_opts = >lvds;
+   unsigned long data_rate;
+   unsigned long fvco;
+   u32 rsc;
+   u32 co;
+   int ret;
+
+   priv->is_slave = lvds_opts->is_slave;
+
+   /* LVDS interface pins */
+   regmap_write(priv->lvds_regmap, PHY_CTRL,
+CCM(CCM_1_2V) | CA(CA_3_51MA) | RFB);
+
+   /* enable MODE8 only for slave LVDS PHY */
+   rsc = priv->id ? IMX_SC_R_MIPI_1 : IMX_SC_R_MIPI_0;
+   ret = imx_sc_misc_set_control(priv->ipc_handle, 

[PATCH resend v8 4/5] dt-bindings: phy: mixel: mipi-dsi-phy: Add Mixel combo PHY support for i.MX8qxp

2022-04-18 Thread Liu Ying
Add support for Mixel MIPI DPHY + LVDS PHY combo IP
as found on Freescale i.MX8qxp SoC.

Cc: Guido Günther 
Cc: Kishon Vijay Abraham I 
Cc: Vinod Koul 
Cc: Rob Herring 
Cc: NXP Linux Team 
Reviewed-by: Rob Herring 
Reviewed-by: Guido Günther 
Signed-off-by: Liu Ying 
---
v7->v8:
* No change.

v6->v7:
* No change.

v5->v6:
* No change.

v4->v5:
* No change.

v3->v4:
* Add Rob's and Guido's R-b tags.

v2->v3:
* No change.

v1->v2:
* Add the binding for i.MX8qxp Mixel combo PHY based on the converted binding.
  (Guido)

 .../bindings/phy/mixel,mipi-dsi-phy.yaml  | 41 +--
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml 
b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
index c34f2e6d6bd5..786cfd71cb7e 100644
--- a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
@@ -14,10 +14,14 @@ description: |
   MIPI-DSI IP from Northwest Logic). It represents the physical layer for the
   electrical signals for DSI.
 
+  The Mixel PHY IP block found on i.MX8qxp is a combo PHY that can work
+  in either MIPI-DSI PHY mode or LVDS PHY mode.
+
 properties:
   compatible:
 enum:
   - fsl,imx8mq-mipi-dphy
+  - fsl,imx8qxp-mipi-dphy
 
   reg:
 maxItems: 1
@@ -40,6 +44,11 @@ properties:
   "#phy-cells":
 const: 0
 
+  fsl,syscon:
+$ref: /schemas/types.yaml#/definitions/phandle
+description: |
+  A phandle which points to Control and Status Registers(CSR) module.
+
   power-domains:
 maxItems: 1
 
@@ -48,12 +57,38 @@ required:
   - reg
   - clocks
   - clock-names
-  - assigned-clocks
-  - assigned-clock-parents
-  - assigned-clock-rates
   - "#phy-cells"
   - power-domains
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: fsl,imx8mq-mipi-dphy
+then:
+  properties:
+fsl,syscon: false
+
+  required:
+- assigned-clocks
+- assigned-clock-parents
+- assigned-clock-rates
+
+  - if:
+  properties:
+compatible:
+  contains:
+const: fsl,imx8qxp-mipi-dphy
+then:
+  properties:
+assigned-clocks: false
+assigned-clock-parents: false
+assigned-clock-rates: false
+
+  required:
+- fsl,syscon
+
 additionalProperties: false
 
 examples:
-- 
2.25.1



[PATCH resend v8 3/5] dt-bindings: phy: Convert mixel, mipi-dsi-phy to json-schema

2022-04-18 Thread Liu Ying
This patch converts the mixel,mipi-dsi-phy binding to
DT schema format using json-schema.

Comparing to the plain text version, the new binding adds
the 'assigned-clocks', 'assigned-clock-parents' and
'assigned-clock-rates' properites, otherwise 'make dtbs_check'
would complain that there are mis-matches.  Also, the new
binding requires the 'power-domains' property since all potential
SoCs that embed this PHY would provide a power domain for it.
The example of the new binding takes reference to the latest
dphy node in imx8mq.dtsi.

Cc: Guido Günther 
Cc: Kishon Vijay Abraham I 
Cc: Vinod Koul 
Cc: Rob Herring 
Cc: NXP Linux Team 
Reviewed-by: Rob Herring 
Reviewed-by: Guido Günther 
Signed-off-by: Liu Ying 
---
v7->v8:
* No change.

v6->v7:
* No change.

v5->v6:
* No change.

v4->v5:
* No change.

v3->v4:
* Add Rob's and Guido's R-b tags.

v2->v3:
* Improve the 'clock-names' property by dropping 'items:'.

v1->v2:
* Newly introduced in v2.  (Guido)

 .../bindings/phy/mixel,mipi-dsi-phy.txt   | 29 
 .../bindings/phy/mixel,mipi-dsi-phy.yaml  | 72 +++
 2 files changed, 72 insertions(+), 29 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.txt
 create mode 100644 
Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.txt 
b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.txt
deleted file mode 100644
index 9b23407233c0..
--- a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Mixel DSI PHY for i.MX8
-
-The Mixel MIPI-DSI PHY IP block is e.g. found on i.MX8 platforms (along the
-MIPI-DSI IP from Northwest Logic). It represents the physical layer for the
-electrical signals for DSI.
-
-Required properties:
-- compatible: Must be:
-  - "fsl,imx8mq-mipi-dphy"
-- clocks: Must contain an entry for each entry in clock-names.
-- clock-names: Must contain the following entries:
-  - "phy_ref": phandle and specifier referring to the DPHY ref clock
-- reg: the register range of the PHY controller
-- #phy-cells: number of cells in PHY, as defined in
-  Documentation/devicetree/bindings/phy/phy-bindings.txt
-  this must be <0>
-
-Optional properties:
-- power-domains: phandle to power domain
-
-Example:
-   dphy: dphy@30a0030 {
-   compatible = "fsl,imx8mq-mipi-dphy";
-   clocks = < IMX8MQ_CLK_DSI_PHY_REF>;
-   clock-names = "phy_ref";
-   reg = <0x30a00300 0x100>;
-   power-domains = <_mipi0>;
-   #phy-cells = <0>;
-};
diff --git a/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml 
b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
new file mode 100644
index ..c34f2e6d6bd5
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/mixel,mipi-dsi-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mixel DSI PHY for i.MX8
+
+maintainers:
+  - Guido Günther 
+
+description: |
+  The Mixel MIPI-DSI PHY IP block is e.g. found on i.MX8 platforms (along the
+  MIPI-DSI IP from Northwest Logic). It represents the physical layer for the
+  electrical signals for DSI.
+
+properties:
+  compatible:
+enum:
+  - fsl,imx8mq-mipi-dphy
+
+  reg:
+maxItems: 1
+
+  clocks:
+maxItems: 1
+
+  clock-names:
+const: phy_ref
+
+  assigned-clocks:
+maxItems: 1
+
+  assigned-clock-parents:
+maxItems: 1
+
+  assigned-clock-rates:
+maxItems: 1
+
+  "#phy-cells":
+const: 0
+
+  power-domains:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - assigned-clocks
+  - assigned-clock-parents
+  - assigned-clock-rates
+  - "#phy-cells"
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+dphy: dphy@30a0030 {
+compatible = "fsl,imx8mq-mipi-dphy";
+reg = <0x30a00300 0x100>;
+clocks = < IMX8MQ_CLK_DSI_PHY_REF>;
+clock-names = "phy_ref";
+assigned-clocks = < IMX8MQ_CLK_DSI_PHY_REF>;
+assigned-clock-parents = < IMX8MQ_VIDEO_PLL1_OUT>;
+assigned-clock-rates = <2400>;
+#phy-cells = <0>;
+power-domains = <_mipi>;
+};
-- 
2.25.1



[PATCH resend v8 2/5] phy: Add LVDS configuration options

2022-04-18 Thread Liu Ying
This patch allows LVDS PHYs to be configured through
the generic functions and through a custom structure
added to the generic union.

The parameters added here are based on common LVDS PHY
implementation practices.  The set of parameters
should cover all potential users.

Cc: Kishon Vijay Abraham I 
Cc: Vinod Koul 
Cc: NXP Linux Team 
Signed-off-by: Liu Ying 
---
v7->v8:
* Trivial kernel doc style fix - add '*'.

v6->v7:
* Update the year of copyright.
* Better variable explanation for bits_per_lane_and_dclk_cycle.

v5->v6:
* Rebase upon v5.17-rc1.

v4->v5:
* Align kernel-doc style to include/linux/phy/phy.h. (Vinod)
* Trivial tweaks.
* Drop Robert's R-b tag.

v3->v4:
* Add Robert's R-b tag.

v2->v3:
* No change.

v1->v2:
* No change.

 include/linux/phy/phy-lvds.h | 32 
 include/linux/phy/phy.h  |  4 
 2 files changed, 36 insertions(+)
 create mode 100644 include/linux/phy/phy-lvds.h

diff --git a/include/linux/phy/phy-lvds.h b/include/linux/phy/phy-lvds.h
new file mode 100644
index ..09931d080a6d
--- /dev/null
+++ b/include/linux/phy/phy-lvds.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020,2022 NXP
+ */
+
+#ifndef __PHY_LVDS_H_
+#define __PHY_LVDS_H_
+
+/**
+ * struct phy_configure_opts_lvds - LVDS configuration set
+ * @bits_per_lane_and_dclk_cycle:  Number of bits per lane per differential
+ * clock cycle.
+ * @differential_clk_rate: Clock rate, in Hertz, of the LVDS
+ * differential clock.
+ * @lanes: Number of active, consecutive,
+ * data lanes, starting from lane 0,
+ * used for the transmissions.
+ * @is_slave:  Boolean, true if the phy is a slave
+ * which works together with a master
+ * phy to support dual link transmission,
+ * otherwise a regular phy or a master phy.
+ *
+ * This structure is used to represent the configuration state of a LVDS phy.
+ */
+struct phy_configure_opts_lvds {
+   unsigned intbits_per_lane_and_dclk_cycle;
+   unsigned long   differential_clk_rate;
+   unsigned intlanes;
+   boolis_slave;
+};
+
+#endif /* __PHY_LVDS_H_ */
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index f3286f4cd306..b1413757fcc3 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -17,6 +17,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 struct phy;
@@ -57,10 +58,13 @@ enum phy_media {
  * the MIPI_DPHY phy mode.
  * @dp:Configuration set applicable for phys supporting
  * the DisplayPort protocol.
+ * @lvds:  Configuration set applicable for phys supporting
+ * the LVDS phy mode.
  */
 union phy_configure_opts {
struct phy_configure_opts_mipi_dphy mipi_dphy;
struct phy_configure_opts_dpdp;
+   struct phy_configure_opts_lvds  lvds;
 };
 
 /**
-- 
2.25.1



[PATCH resend v8 1/5] drm/bridge: nwl-dsi: Set PHY mode in nwl_dsi_mode_set()

2022-04-18 Thread Liu Ying
The Northwest Logic MIPI DSI host controller embedded in i.MX8qxp
works with a Mixel MIPI DPHY + LVDS PHY combo to support either
a MIPI DSI display or a LVDS display.  So, this patch calls
phy_set_mode() from nwl_dsi_mode_set() to set PHY mode to MIPI DPHY
explicitly.

Cc: Guido Günther 
Cc: Robert Chiras 
Cc: Martin Kepplinger 
Cc: Andrzej Hajda 
Cc: Neil Armstrong 
Cc: Laurent Pinchart 
Cc: Jonas Karlman 
Cc: Jernej Skrabec 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: NXP Linux Team 
Signed-off-by: Liu Ying 
---
v7->v8:
* Resend with Andrzej's and Jernej's mail addressed updated.

v6->v7:
* No change.

v5->v6:
* Rebase the series upon v5.17-rc1.
* Set PHY mode in ->mode_set() instead of ->pre_enable() in the nwl-dsi
  bridge driver due to the rebase.
* Drop Guido's R-b tag due to the rebase.

v4->v5:
* No change.

v3->v4:
* No change.

v2->v3:
* No change.

v1->v2:
* Add Guido's R-b tag.

 drivers/gpu/drm/bridge/nwl-dsi.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index d5945501a5ee..85bab7372af1 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -666,6 +666,12 @@ static int nwl_dsi_mode_set(struct nwl_dsi *dsi)
return ret;
}
 
+   ret = phy_set_mode(dsi->phy, PHY_MODE_MIPI_DPHY);
+   if (ret < 0) {
+   DRM_DEV_ERROR(dev, "Failed to set DSI phy mode: %d\n", ret);
+   goto uninit_phy;
+   }
+
ret = phy_configure(dsi->phy, phy_cfg);
if (ret < 0) {
DRM_DEV_ERROR(dev, "Failed to configure DSI phy: %d\n", ret);
-- 
2.25.1



[PATCH resend v8 0/5] phy: phy-fsl-imx8-mipi-dphy: Add i.MX8qxp LVDS PHY mode support

2022-04-18 Thread Liu Ying
Hi,

This is the v8 series to add i.MX8qxp LVDS PHY mode support for the Mixel
PHY in the Freescale i.MX8qxp SoC.

The Mixel PHY is MIPI DPHY + LVDS PHY combo, which can works in either
MIPI DPHY mode or LVDS PHY mode.  The PHY mode is controlled by i.MX8qxp
SCU firmware.  The PHY driver would call a SCU function to configure the
mode.

The PHY driver is already supporting the Mixel MIPI DPHY in i.MX8mq SoC,
where it appears to be a single MIPI DPHY.


Patch 1/5 sets PHY mode in the Northwest Logic MIPI DSI host controller
bridge driver, since i.MX8qxp SoC embeds this controller IP to support
MIPI DSI displays together with the Mixel PHY.

Patch 2/5 allows LVDS PHYs to be configured through the generic PHY functions
and through a custom structure added to the generic PHY configuration union.

Patch 3/5 converts mixel,mipi-dsi-phy plain text dt binding to json-schema.

Patch 4/5 adds dt binding support for the Mixel combo PHY in i.MX8qxp SoC.

Patch 5/5 adds the i.MX8qxp LVDS PHY mode support in the Mixel PHY driver.


Welcome comments, thanks.

v7->v8:
* Trivial kernel doc style fix for patch 2/5 - add '*'.
* Resend with reviewer mail addresses updated for patch 1/5.

v6->v7:
* Update the year of copyright for patch 2/5.
* Better variable explanation for bits_per_lane_and_dclk_cycle in patch 2/5.
* Use marco instead of magic number for CCM and CA values for patch 5/5.
* Suppress 'checkpatch --strict' warnings for patch 5/5.

v5->v6:
* Rebase the series upon v5.17-rc1.
* Set PHY mode in ->mode_set() instead of ->pre_enable() in the nwl-dsi
  bridge driver in patch 1/5 due to the rebase.
* Drop Guido's R-b tag on patch 1/5 due to the rebase.

v4->v5:
* Align kernel-doc style of include/linux/phy/phy-lvds.h to
  include/linux/phy/phy.h for patch 2/5. (Vinod)
* Trivial tweaks on patch 2/5.
* Drop Robert's R-b tag on patch 2/5.

v3->v4:
* Add all R-b tags received from v3 on relevant patches and respin. (Robert)

v2->v3:
* Improve readability of mixel_dphy_set_mode() in the Mixel PHY driver. (Guido)
* Improve the 'clock-names' property in the PHY dt binding.

v1->v2:
* Convert mixel,mipi-dsi-phy plain text dt binding to json-schema. (Guido)
* Print invalid PHY mode in dmesg from the Mixel PHY driver. (Guido)
* Add Guido's R-b tag on the patch for the nwl-dsi drm bridge driver.

Liu Ying (5):
  drm/bridge: nwl-dsi: Set PHY mode in nwl_dsi_mode_set()
  phy: Add LVDS configuration options
  dt-bindings: phy: Convert mixel,mipi-dsi-phy to json-schema
  dt-bindings: phy: mixel: mipi-dsi-phy: Add Mixel combo PHY support for
i.MX8qxp
  phy: freescale: phy-fsl-imx8-mipi-dphy: Add i.MX8qxp LVDS PHY mode
support

 .../bindings/phy/mixel,mipi-dsi-phy.txt   |  29 --
 .../bindings/phy/mixel,mipi-dsi-phy.yaml  | 107 +++
 drivers/gpu/drm/bridge/nwl-dsi.c  |   6 +
 .../phy/freescale/phy-fsl-imx8-mipi-dphy.c| 276 +-
 include/linux/phy/phy-lvds.h  |  32 ++
 include/linux/phy/phy.h   |   4 +
 6 files changed, 414 insertions(+), 40 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.txt
 create mode 100644 
Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml
 create mode 100644 include/linux/phy/phy-lvds.h

-- 
2.25.1



Re: [PATCH] drm/bridge: fix anx6345 power up sequence

2022-04-18 Thread Vasily Khoruzhick
On Sun, Apr 17, 2022 at 11:52 AM Vasily Khoruzhick  wrote:
>
> On Sun, Apr 17, 2022 at 9:15 AM Torsten Duwe  wrote:
> >
> > Align the power-up sequence with the known-good procedure documented in [1]:
> > un-swap dvdd12 and dvdd25, and allow a little extra time for them to settle
> > before de-asserting reset.
>
> Hi Torsten,
>
> Interesting find! I tried to fix the issue several times by playing
> with the delays to no avail.
>
> What's interesting, ANX6345 datasheet allows DVDD12 to come up either
> earlier or later than DVDD25 with the delay of T1 (2ms typical)
> between them, and actually bringing up DVDD12 first works fine in
> u-boot.
>
> The datasheet also requires reset to be deasserted no earlier than T2
> (2-5ms) after all the rails are stable.
>
> Another thing it mentions is that the system clock must be stable for
> T3 (1-3ms) before reset is deasserted, T3 is already a part of T2,
> however it cannot be gated on Pinebook, see [1], page 15
>
> The change looks good to me, but I'll need some time to actually test
> it. If you don't hear from me for longer than a week please ping me.

Your change doesn't fix the issue for me. Running "xrandr --output
eDP-1 --off; xrandr --output eDP-1 --auto" in a loop triggers the
issue pretty quickly even with the patch.


Re: [PATCH v2] drm/msm: properly add and remove internal bridges

2022-04-18 Thread Abhinav Kumar




On 4/11/2022 4:49 PM, Dmitry Baryshkov wrote:

Add calls to drm_bridge_add()/drm_bridge_remove() DRM bridges created by
the driver. This fixes the following warning.

WARNING: CPU: 0 PID: 1 at kernel/locking/mutex.c:579 __mutex_lock+0x840/0x9f4
DEBUG_LOCKS_WARN_ON(lock->magic != lock)
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.18.0-rc1-2-g3054695a0d27-dirty 
#55
Hardware name: Generic DT based system
  unwind_backtrace from show_stack+0x10/0x14
  show_stack from dump_stack_lvl+0x58/0x70
  dump_stack_lvl from __warn+0xc8/0x1e8
  __warn from warn_slowpath_fmt+0x78/0xa8
  warn_slowpath_fmt from __mutex_lock+0x840/0x9f4
  __mutex_lock from mutex_lock_nested+0x1c/0x24
  mutex_lock_nested from drm_bridge_hpd_enable+0x2c/0x84
  drm_bridge_hpd_enable from msm_hdmi_modeset_init+0xc0/0x21c
  msm_hdmi_modeset_init from mdp4_kms_init+0x53c/0x90c
  mdp4_kms_init from msm_drm_bind+0x514/0x698
  msm_drm_bind from try_to_bring_up_aggregate_device+0x160/0x1bc
  try_to_bring_up_aggregate_device from 
component_master_add_with_match+0xc4/0xf8
  component_master_add_with_match from msm_pdev_probe+0x274/0x350
  msm_pdev_probe from platform_probe+0x5c/0xbc
  platform_probe from really_probe.part.0+0x9c/0x290
  really_probe.part.0 from __driver_probe_device+0xa8/0x13c
  __driver_probe_device from driver_probe_device+0x34/0x10c
  driver_probe_device from __driver_attach+0xbc/0x178
  __driver_attach from bus_for_each_dev+0x74/0xc0
  bus_for_each_dev from bus_add_driver+0x160/0x1e4
  bus_add_driver from driver_register+0x88/0x118
  driver_register from do_one_initcall+0x6c/0x334
  do_one_initcall from kernel_init_freeable+0x1bc/0x220
  kernel_init_freeable from kernel_init+0x18/0x12c
  kernel_init from ret_from_fork+0x14/0x2c

Fixes: 3d3f8b1f8b62 ("drm/bridge: make bridge registration independent of drm 
flow")
Reported-by: kernel test robot 
Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
Changes since v1:
  - Dropped drm_bridge_detach() call, it is not necessary, also it breaks
compilation if MSM DRM is built as module.
---
  drivers/gpu/drm/msm/dp/dp_drm.c| 4 
  drivers/gpu/drm/msm/dsi/dsi_manager.c  | 3 +++
  drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 3 +++
  drivers/gpu/drm/msm/msm_drv.c  | 3 +++
  4 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 80f59cf99089..262744914f97 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -230,9 +230,13 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp 
*dp_display, struct drm_devi
bridge->funcs = _bridge_ops;
bridge->encoder = encoder;
  
+	drm_bridge_add(bridge);

+
rc = drm_bridge_attach(encoder, bridge, NULL, 
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (rc) {
DRM_ERROR("failed to attach bridge, rc=%d\n", rc);
+   drm_bridge_remove(bridge);
+
return ERR_PTR(rc);
}
  
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c

index 9f6af0f0fe00..1db93e562fe6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -665,6 +665,8 @@ struct drm_bridge *msm_dsi_manager_bridge_init(u8 id)
bridge = _bridge->base;
bridge->funcs = _mgr_bridge_funcs;
  
+	drm_bridge_add(bridge);

+
ret = drm_bridge_attach(encoder, bridge, NULL, 0);
if (ret)
goto fail;
@@ -735,6 +737,7 @@ struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id)
  
  void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)

  {
+   drm_bridge_remove(bridge);
  }
  
  int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 10ebe2089cb6..97c24010c4d1 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -15,6 +15,7 @@ void msm_hdmi_bridge_destroy(struct drm_bridge *bridge)
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
  
  	msm_hdmi_hpd_disable(hdmi_bridge);

+   drm_bridge_remove(bridge);
  }
  
  static void msm_hdmi_power_on(struct drm_bridge *bridge)

@@ -349,6 +350,8 @@ struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi)
DRM_BRIDGE_OP_DETECT |
DRM_BRIDGE_OP_EDID;
  
+	drm_bridge_add(bridge);

+
ret = drm_bridge_attach(hdmi->encoder, bridge, NULL, 
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (ret)
goto fail;
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 2905b82a9de3..d8f2c8838a7f 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -232,6 +232,9 @@ static int msm_drm_uninit(struct device *dev)
  
  	drm_mode_config_cleanup(ddev);
  
+	for (i = 0; i < priv->num_bridges; i++)

+   drm_bridge_remove(priv->bridges[i]);
+

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

2022-04-18 Thread Doug Anderson
Hi,

On Fri, Apr 15, 2022 at 5:54 PM Dmitry Baryshkov
 wrote:
>
> >>> * 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.

Right. So I guess I was thinking that we _could_ have modeled the
backlight as a device which lists dp_aux_bus_type as dev->bus_type.
AKA:

1. We could have had a second node in the sc7180-trogdor-homestar
device tree under the DP controller for the DP AUX backlight.

2. Instead of manually calling drm_panel_dp_aux_backlight() from
panel-edp.c and panel-samsung-atna33xc20.c the backlight could have
just probed on its own.

3. In the device tree, the panel could have had a link to the
backlight's phandle which would have made the existing
drm_panel_of_backlight() "just work" and we wouldn't have needed the
manual call to drm_panel_dp_aux_backlight().

Oh. But. Maybe. Not.

We couldn't really have done that because we would have been able to
do the DP AUX transactions for the backlight without powering on the
panel. So we couldn't really have probed them separately. OK, you guys
win this round. ;-)


> > 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 spent a bunch of time searching and I couldn't find more than a
reference, like "hey we came up with this idea and we're gonna write
down in the spec that you could totally do USB over the AUX channel,
but u, we haven't actually implemented it yet". ;-) I certainly
could be wrong, but all of the references I could find were distinctly
lacking in details or pointers to other docs w/ more info.

...but while searching I _did_ find a lot of details (in the eDP 1.4
spec) about "Multi-touch over AUX". That looks like something that's
actually more well thought out and maybe even implemented somewhere.

>From what I can tell though, it looks as if it's the same thing as the
backlight. In other words it's only available when the panel is
powered.

I don't think we want to do anything so drastic like moving the
ownership of panel power to the AUX bus or anything, so I guess this
means that:

a) The panel driver will remain in charge of powering the panel
(including anything on the DP AUX bus) on and off and getting the
power sequencing right.

b) That means that we can really think of the panel as the _only_
thing on the DP AUX bus.

c) Anything else on the DP AUX bus will be underneath the panel driver.


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

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

2022-04-18 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(>event_q) to probe()
-- move spin_lock_init(>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.

Changes in v10:
-- delete extra  DRM_ERROR("failed to create DP event thread\n");

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 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 39 +
 1 file changed, 31 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..4dc0758 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(>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,17 @@ 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(_priv->event_q);
-   spin_lock_init(_priv->event_lock);
+   /* set event q to empty */
+   dp_priv->event_gndx = 0;
+   dp_priv->event_pndx = 0;
 
-   kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");
+   dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, 
"dp_hpd_handler");
+   if (IS_ERR(dp_priv->ev_tsk))
+   return PTR_ERR(dp_priv->ev_tsk);
+
+   return 0;
 }
 
 static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
@@ -1266,7 +1288,10 @@ static int dp_display_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
 
+   /* setup event q */
mutex_init(>event_mutex);
+   init_waitqueue_head(>event_q);
+   spin_lock_init(>event_lock);
 
/* Store DP audio handle inside DP display */
dp->dp_display.dp_audio = dp->audio;
@@ -1441,8 +1466,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 

Re: [PATCH v2 0/5] drm/ttm: Introduce TTM res manager debugfs helpers

2022-04-18 Thread Zack Rusin
On Tue, 2022-04-12 at 11:15 +0200, Christian König wrote:
> 
> Hi Zack,
> 
> Reviewed-by: Christian König  for the
> entire
> series.
> 
> One nit pick is that I want to get rid of using ttm_manager_type() in
> drivers and use pointers to the members directly. But that's
> something
> for a later cleanup anyway.

That sounds good to me. Let me know if you'd like me to hold off on
pushing this until the ttm_manager_type changes are ready, otherwise
I'll push it to drm-misc-next tomorrow.

z



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

2022-04-18 Thread Biju Das
Hi Laurent,

Thanks for the feedback.

> Subject: Re: [PATCH v2 2/2] drm: rcar-du: Add RZ/G2L DSI driver
> 
> 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:
> >  *
> > ---
> >  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 

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

2022-04-18 Thread Biju Das
Hi Laurent,

Thanks for the feedback.

> Subject: Re: [PATCH v2 1/2] dt-bindings: display: bridge: Document RZ/G2L
> MIPI DSI TX bindings
> 
> 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:-
> >  *
> > ---
> >  .../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.yam
> > +++ l
> > @@ -0,0 +1,175 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id:
> >
> > +
> > +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 ?

Yep, There is a mismatch between clk document and hardware manual. 
I have reported this issue to HW team for fixing the clk document.

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

OK.

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

[PATCH] drm/amd/display: add virtual_setup_stream_attribute decl to header

2022-04-18 Thread Tom Rix
Smatch reports this issue
virtual_link_hwss.c:32:6: warning: symbol
  'virtual_setup_stream_attribute' was not declared.
  Should it be static?

virtual_setup_stream_attribute is only used in
virtual_link_hwss.c, but the other functions in the
file are declared in the header file and used elsewhere.
For consistency, add the virtual_setup_stream_attribute
decl to virtual_link_hwss.h.

Signed-off-by: Tom Rix 
---
 drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h 
b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h
index e6bcb4bb0f3a..fbcbc5afb47d 100644
--- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h
+++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h
@@ -28,6 +28,7 @@
 #include "core_types.h"
 
 void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx);
+void virtual_setup_stream_attribute(struct pipe_ctx *pipe_ctx);
 void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx);
 const struct link_hwss *get_virtual_link_hwss(void);
 
-- 
2.27.0



Re: [PATCH 04/11] drm/ttm: move default BO destructor into VMWGFX

2022-04-18 Thread Zack Rusin
On Tue, 2022-03-29 at 13:02 +0200, Christian König wrote:
> ⚠ External Email
> 
> It's the only driver using this.
> 
> Signed-off-by: Christian König 

Looks good. A small suggestion underneath.

Reviewed-by: Zack Rusin 

> ---
>  drivers/gpu/drm/ttm/ttm_bo.c   |  9 +
>  drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 11 ++-
>  2 files changed, 11 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c
> b/drivers/gpu/drm/ttm/ttm_bo.c
> index e5fd0f2c0299..7598d59423bf 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -44,12 +44,6 @@
> 
>  #include "ttm_module.h"
> 
> -/* default destructor */
> -static void ttm_bo_default_destroy(struct ttm_buffer_object *bo)
> -{
> -   kfree(bo);
> -}
> -
>  static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo,
>     struct ttm_placement
> *placement)
>  {
> @@ -938,8 +932,7 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
>     bool locked;
>     int ret;
> 
> -   bo->destroy = destroy ? destroy : ttm_bo_default_destroy;
> -
> +   bo->destroy = destroy;
>     kref_init(>kref);
>     INIT_LIST_HEAD(>ddestroy);
>     bo->bdev = bdev;
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
> b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
> index 31aecc46624b..60dcc6a75248 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
> @@ -378,6 +378,12 @@ void vmw_bo_bo_free(struct ttm_buffer_object
> *bo)
>     kfree(vmw_bo);
>  }
> 
> +/* default destructor */
> +static void vmw_bo_default_destroy(struct ttm_buffer_object *bo)
> +{
> +   kfree(bo);
> +}
> +
>  /**
>   * vmw_bo_create_kernel - Create a pinned BO for internal kernel
> use.
>   *
> @@ -410,7 +416,7 @@ int vmw_bo_create_kernel(struct vmw_private
> *dev_priv, unsigned long size,
> 
>     ret = ttm_bo_init_reserved(_priv->bdev, bo, size,
>    ttm_bo_type_kernel, placement, 0,
> -  , NULL, NULL, NULL);
> +  , NULL, NULL,
> vmw_bo_default_destroy);
>     if (unlikely(ret))
>     goto error_free;
> 
> @@ -439,6 +445,9 @@ int vmw_bo_create(struct vmw_private *vmw,
>     return -ENOMEM;
>     }
> 
> +   if (!bo_free)
> +   bo_free = vmw_bo_default_destroy;
> +

If you could change this to just  BUG_ON(!bo_free) that'd be great.
bo_free == NULL should never happen here.

z


Re: [PATCH v4 09/15] drm/shmem-helper: Correct doc-comment of drm_gem_shmem_get_sg_table()

2022-04-18 Thread Dmitry Osipenko
On 4/18/22 21:25, Thomas Zimmermann wrote:
> Hi
> 
> Am 18.04.22 um 00:37 schrieb Dmitry Osipenko:
>> drm_gem_shmem_get_sg_table() never returns NULL on error, but a ERR_PTR.
>> Correct the doc comment which says that it returns NULL on error.
>>
>> Signed-off-by: Dmitry Osipenko 
> 
> 
>> ---
>>   drivers/gpu/drm/drm_gem_shmem_helper.c | 5 +++--
>>   1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c
>> b/drivers/gpu/drm/drm_gem_shmem_helper.c
>> index 8ad0e02991ca..30ee46348a99 100644
>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>> @@ -662,7 +662,7 @@ EXPORT_SYMBOL(drm_gem_shmem_print_info);
>>    * drm_gem_shmem_get_pages_sgt() instead.
>>    *
>>    * Returns:
>> - * A pointer to the scatter/gather table of pinned pages or NULL on
>> failure.
>> + * A pointer to the scatter/gather table of pinned pages or errno on
>> failure.
> 
> ', or an ERR_PTR()-encoded errno code on failure'
> 
>>    */
>>   struct sg_table *drm_gem_shmem_get_sg_table(struct
>> drm_gem_shmem_object *shmem)
>>   {
>> @@ -688,7 +688,8 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
>>    * drm_gem_shmem_get_sg_table() should not be directly called by
>> drivers.
>>    *
>>    * Returns:
>> - * A pointer to the scatter/gather table of pinned pages or errno on
>> failure.
>> + * A pointer to the scatter/gather table of pinned pages
>> ERR_PTR()-encoded
> 
> ', or an' before ERR_PTR
> 
> With the improved grammar:
> 
> Acked-by: Thomas Zimmermann 

Thanks, something went wrong with these comments in this patch and I
haven't noticed that :)



[PATCH] drm/vmwgfx: Fix gem refcounting and memory evictions

2022-04-18 Thread Zack Rusin
From: Zack Rusin 

The initial GEM port broke refcounting on shareable (prime) surfaces and
memory evictions. The prime surfaces broke because the parent surfaces
weren't increasing the ref count on GEM surfaces, which meant that
the memory backing textures could have been deleted while the texture
was still accessible. The evictions broke due to a typo, the code was
supposed to exit if the passed buffers were not vmw_buffer_object
not if they were. They're tied because the evictions depend on having
memory to actually evict.

This fixes crashes with XA state tracker which is used for xrender
acceleration on xf86-video-vmware and apps/tests which use a lot of
memory (a good test being the piglit's streaming-texture-leak)

Signed-off-by: Zack Rusin 
Fixes: 8afa13a0583f ("drm/vmwgfx: Implement DRIVER_GEM")
Cc:  # v5.17+
Reviewed-by: Maaz Mombasawala 
Reviewed-by: Martin Krastev 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c  | 38 +++--
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c |  8 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |  7 -
 3 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
index 31aecc46624b..32326168b258 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
@@ -46,6 +46,21 @@ vmw_buffer_object(struct ttm_buffer_object *bo)
return container_of(bo, struct vmw_buffer_object, base);
 }
 
+/**
+ * bo_is_vmw - check if the buffer object is a _buffer_object
+ * @bo: ttm buffer object to be checked
+ *
+ * Uses destroy function associated with the object to determine if this is
+ * a _buffer_object.
+ *
+ * Returns:
+ * true if the object is of _buffer_object type, false if not.
+ */
+static bool bo_is_vmw(struct ttm_buffer_object *bo)
+{
+   return bo->destroy == _bo_bo_free ||
+  bo->destroy == _gem_destroy;
+}
 
 /**
  * vmw_bo_pin_in_placement - Validate a buffer to placement.
@@ -798,7 +813,7 @@ int vmw_dumb_create(struct drm_file *file_priv,
 void vmw_bo_swap_notify(struct ttm_buffer_object *bo)
 {
/* Is @bo embedded in a struct vmw_buffer_object? */
-   if (vmw_bo_is_vmw_bo(bo))
+   if (!bo_is_vmw(bo))
return;
 
/* Kill any cached kernel maps before swapout */
@@ -822,7 +837,7 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo,
struct vmw_buffer_object *vbo;
 
/* Make sure @bo is embedded in a struct vmw_buffer_object? */
-   if (vmw_bo_is_vmw_bo(bo))
+   if (!bo_is_vmw(bo))
return;
 
vbo = container_of(bo, struct vmw_buffer_object, base);
@@ -843,22 +858,3 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo,
if (mem->mem_type != VMW_PL_MOB && bo->resource->mem_type == VMW_PL_MOB)
vmw_resource_unbind_list(vbo);
 }
-
-/**
- * vmw_bo_is_vmw_bo - check if the buffer object is a _buffer_object
- * @bo: buffer object to be checked
- *
- * Uses destroy function associated with the object to determine if this is
- * a _buffer_object.
- *
- * Returns:
- * true if the object is of _buffer_object type, false if not.
- */
-bool vmw_bo_is_vmw_bo(struct ttm_buffer_object *bo)
-{
-   if (bo->destroy == _bo_bo_free ||
-   bo->destroy == _gem_destroy)
-   return true;
-
-   return false;
-}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 72a17618ba0a..0c12faa4e533 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1018,13 +1018,10 @@ static int vmw_driver_load(struct vmw_private 
*dev_priv, u32 pci_id)
goto out_no_fman;
}
 
-   drm_vma_offset_manager_init(_priv->vma_manager,
-   DRM_FILE_PAGE_OFFSET_START,
-   DRM_FILE_PAGE_OFFSET_SIZE);
ret = ttm_device_init(_priv->bdev, _bo_driver,
  dev_priv->drm.dev,
  dev_priv->drm.anon_inode->i_mapping,
- _priv->vma_manager,
+ dev_priv->drm.vma_offset_manager,
  dev_priv->map_mode == vmw_dma_alloc_coherent,
  false);
if (unlikely(ret != 0)) {
@@ -1195,7 +1192,6 @@ static void vmw_driver_unload(struct drm_device *dev)
vmw_devcaps_destroy(dev_priv);
vmw_vram_manager_fini(dev_priv);
ttm_device_fini(_priv->bdev);
-   drm_vma_offset_manager_destroy(_priv->vma_manager);
vmw_release_device_late(dev_priv);
vmw_fence_manager_takedown(dev_priv->fman);
if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
@@ -1419,7 +1415,7 @@ vmw_get_unmapped_area(struct file *file, unsigned long 
uaddr,
struct vmw_private *dev_priv = vmw_priv(file_priv->minor->dev);
 
return drm_get_unmapped_area(file, uaddr, len, pgoff, flags,
-

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

2022-04-18 Thread Stephen Boyd
Quoting Kuogee Hsieh (2022-04-15 16:47:25)
> 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
> @@ -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");

One thread DRM_ERROR()

> +   goto end;
> +   }
> +
> +   return 0;
>  end:
> return rc;
>  }
> @@ -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(_priv->event_q);
> -   spin_lock_init(_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");

And another thread creation DRM_ERROR(). Can we just have one please
instead of two lines for something that probably never happens?

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


Re: [PATCH v4 10/15] drm/shmem-helper: Take reservation lock instead of drm_gem_shmem locks

2022-04-18 Thread Dmitry Osipenko
Hello,

On 4/18/22 21:38, Thomas Zimmermann wrote:
> Hi
> 
> Am 18.04.22 um 00:37 schrieb Dmitry Osipenko:
>> Replace drm_gem_shmem locks with the reservation lock to make GEM
>> lockings more consistent.
>>
>> Previously drm_gem_shmem_vmap() and drm_gem_shmem_get_pages() were
>> protected by separate locks, now it's the same lock, but it doesn't
>> make any difference for the current GEM SHMEM users. Only Panfrost
>> and Lima drivers use vmap() and they do it in the slow code paths,
>> hence there was no practical justification for the usage of separate
>> lock in the vmap().
>>
>> Suggested-by: Daniel Vetter 
>> Signed-off-by: Dmitry Osipenko 
>> ---
...
>>   @@ -310,7 +306,7 @@ static int drm_gem_shmem_vmap_locked(struct
>> drm_gem_shmem_object *shmem,
>>   } else {
>>   pgprot_t prot = PAGE_KERNEL;
>>   -    ret = drm_gem_shmem_get_pages(shmem);
>> +    ret = drm_gem_shmem_get_pages_locked(shmem);
>>   if (ret)
>>   goto err_zero_use;
>>   @@ -360,11 +356,11 @@ int drm_gem_shmem_vmap(struct
>> drm_gem_shmem_object *shmem,
>>   {
>>   int ret;
>>   -    ret = mutex_lock_interruptible(>vmap_lock);
>> +    ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
>>   if (ret)
>>   return ret;
>>   ret = drm_gem_shmem_vmap_locked(shmem, map);
> 
> Within drm_gem_shmem_vmap_locked(), there's a call to dma_buf_vmap() for
> imported pages. If the exporter side also holds/acquires the same
> reservation lock as our object, the whole thing can deadlock. We cannot
> move dma_buf_vmap() out of the CS, because we still need to increment
> the reference counter. I honestly don't know how to easily fix this
> problem. There's a TODO item about replacing these locks at [1]. As
> Daniel suggested this patch, we should talk to him about the issue.
> 
> Best regards
> Thomas
> 
> [1]
> https://www.kernel.org/doc/html/latest/gpu/todo.html#move-buffer-object-locking-to-dma-resv-lock

Indeed, good catch! Perhaps we could simply use a separate lock for the
vmapping of the *imported* GEMs? The vmap_use_count is used only by
vmap/vunmap, so it doesn't matter which lock is used by these functions
in the case of imported GEMs since we only need to protect the
vmap_use_count.


Re: [PATCH] drm/nouveau/gr/gf100-: change gf108_gr_fwif from global to static

2022-04-18 Thread Lyude Paul
Reviewed-by: Lyude Paul 

Will push to the appropriate branch in a moment

On Mon, 2022-04-18 at 11:28 -0400, Tom Rix wrote:
> Smatch reports this issue
> gf108.c:147:1: warning: symbol 'gf108_gr_fwif'
>   was not declared. Should it be static?
> 
> gf108_gr_fwif is only used in gf108.c.  Single
> file variables should not be global so change
> gf108_gr_fwif's storage-class specifier to static.
> 
> Signed-off-by: Tom Rix 
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
> b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
> index 030640bb3dca..ab3760e804b8 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
> @@ -143,7 +143,7 @@ gf108_gr = {
> }
>  };
>  
> -const struct gf100_gr_fwif
> +static const struct gf100_gr_fwif
>  gf108_gr_fwif[] = {
> { -1, gf100_gr_load, _gr },
> { -1, gf100_gr_nofw, _gr },

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [PATCH] drm/nouveau: change base917c_format from global to static

2022-04-18 Thread Lyude Paul
Reviewed-by: Lyude Paul 

Will push this to the appropriate branch in a little bit

On Mon, 2022-04-18 at 10:18 -0400, Tom Rix wrote:
> Smatch reports this issue
> base917c.c:26:1: warning: symbol 'base917c_format'
>   was not declared. Should it be static?
> 
> base917c_format is only used in base917.c.  Single
> file variables should not be global so change
> base917c_format's storage-class specifier to static.
> 
> Signed-off-by: Tom Rix 
> ---
>  drivers/gpu/drm/nouveau/dispnv50/base917c.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/base917c.c
> b/drivers/gpu/drm/nouveau/dispnv50/base917c.c
> index a1baed4fe0e9..ca260509a4f1 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/base917c.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/base917c.c
> @@ -22,7 +22,7 @@
>  #include "base.h"
>  #include "atom.h"
>  
> -const u32
> +static const u32
>  base917c_format[] = {
> DRM_FORMAT_C8,
> DRM_FORMAT_XRGB,

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [PATCH v4 10/15] drm/shmem-helper: Take reservation lock instead of drm_gem_shmem locks

2022-04-18 Thread Thomas Zimmermann

Hi

Am 18.04.22 um 00:37 schrieb Dmitry Osipenko:

Replace drm_gem_shmem locks with the reservation lock to make GEM
lockings more consistent.

Previously drm_gem_shmem_vmap() and drm_gem_shmem_get_pages() were
protected by separate locks, now it's the same lock, but it doesn't
make any difference for the current GEM SHMEM users. Only Panfrost
and Lima drivers use vmap() and they do it in the slow code paths,
hence there was no practical justification for the usage of separate
lock in the vmap().

Suggested-by: Daniel Vetter 
Signed-off-by: Dmitry Osipenko 
---
  drivers/gpu/drm/drm_gem_shmem_helper.c  | 38 -
  drivers/gpu/drm/lima/lima_gem.c |  8 +++---
  drivers/gpu/drm/panfrost/panfrost_mmu.c | 15 ++
  include/drm/drm_gem_shmem_helper.h  | 10 ---
  4 files changed, 31 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 30ee46348a99..3ecef571eff3 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -86,8 +86,6 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, 
bool private)
if (ret)
goto err_release;
  
-	mutex_init(>pages_lock);

-   mutex_init(>vmap_lock);
INIT_LIST_HEAD(>madv_list);
  
  	if (!private) {

@@ -157,8 +155,6 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
WARN_ON(shmem->pages_use_count);
  
  	drm_gem_object_release(obj);

-   mutex_destroy(>pages_lock);
-   mutex_destroy(>vmap_lock);
kfree(shmem);
  }
  EXPORT_SYMBOL_GPL(drm_gem_shmem_free);
@@ -209,11 +205,11 @@ int drm_gem_shmem_get_pages(struct drm_gem_shmem_object 
*shmem)
  
  	WARN_ON(shmem->base.import_attach);
  
-	ret = mutex_lock_interruptible(>pages_lock);

+   ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
if (ret)
return ret;
ret = drm_gem_shmem_get_pages_locked(shmem);
-   mutex_unlock(>pages_lock);
+   dma_resv_unlock(shmem->base.resv);
  
  	return ret;

  }
@@ -248,9 +244,9 @@ static void drm_gem_shmem_put_pages_locked(struct 
drm_gem_shmem_object *shmem)
   */
  void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem)
  {
-   mutex_lock(>pages_lock);
+   dma_resv_lock(shmem->base.resv, NULL);
drm_gem_shmem_put_pages_locked(shmem);
-   mutex_unlock(>pages_lock);
+   dma_resv_unlock(shmem->base.resv);
  }
  EXPORT_SYMBOL(drm_gem_shmem_put_pages);
  
@@ -310,7 +306,7 @@ static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem,

} else {
pgprot_t prot = PAGE_KERNEL;
  
-		ret = drm_gem_shmem_get_pages(shmem);

+   ret = drm_gem_shmem_get_pages_locked(shmem);
if (ret)
goto err_zero_use;
  
@@ -360,11 +356,11 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem,

  {
int ret;
  
-	ret = mutex_lock_interruptible(>vmap_lock);

+   ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
if (ret)
return ret;
ret = drm_gem_shmem_vmap_locked(shmem, map);


Within drm_gem_shmem_vmap_locked(), there's a call to dma_buf_vmap() for 
imported pages. If the exporter side also holds/acquires the same 
reservation lock as our object, the whole thing can deadlock. We cannot 
move dma_buf_vmap() out of the CS, because we still need to increment 
the reference counter. I honestly don't know how to easily fix this 
problem. There's a TODO item about replacing these locks at [1]. As 
Daniel suggested this patch, we should talk to him about the issue.


Best regards
Thomas

[1] 
https://www.kernel.org/doc/html/latest/gpu/todo.html#move-buffer-object-locking-to-dma-resv-lock





-   mutex_unlock(>vmap_lock);
+   dma_resv_unlock(shmem->base.resv);
  
  	return ret;

  }
@@ -385,7 +381,7 @@ static void drm_gem_shmem_vunmap_locked(struct 
drm_gem_shmem_object *shmem,
dma_buf_vunmap(obj->import_attach->dmabuf, map);
} else {
vunmap(shmem->vaddr);
-   drm_gem_shmem_put_pages(shmem);
+   drm_gem_shmem_put_pages_locked(shmem);
}
  
  	shmem->vaddr = NULL;

@@ -406,9 +402,11 @@ static void drm_gem_shmem_vunmap_locked(struct 
drm_gem_shmem_object *shmem,
  void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem,
  struct iosys_map *map)
  {
-   mutex_lock(>vmap_lock);
+   dma_resv_lock(shmem->base.resv, NULL);
drm_gem_shmem_vunmap_locked(shmem, map);
-   mutex_unlock(>vmap_lock);
+   dma_resv_unlock(shmem->base.resv);
+
+   drm_gem_shmem_update_purgeable_status(shmem);
  }
  EXPORT_SYMBOL(drm_gem_shmem_vunmap);
  
@@ -442,14 +440,14 @@ drm_gem_shmem_create_with_handle(struct drm_file *file_priv,

   */
  int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv)
  {
-   mutex_lock(>pages_lock);
+   

Re: [PATCH v4 09/15] drm/shmem-helper: Correct doc-comment of drm_gem_shmem_get_sg_table()

2022-04-18 Thread Thomas Zimmermann

Hi

Am 18.04.22 um 00:37 schrieb Dmitry Osipenko:

drm_gem_shmem_get_sg_table() never returns NULL on error, but a ERR_PTR.
Correct the doc comment which says that it returns NULL on error.

Signed-off-by: Dmitry Osipenko 




---
  drivers/gpu/drm/drm_gem_shmem_helper.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 8ad0e02991ca..30ee46348a99 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -662,7 +662,7 @@ EXPORT_SYMBOL(drm_gem_shmem_print_info);
   * drm_gem_shmem_get_pages_sgt() instead.
   *
   * Returns:
- * A pointer to the scatter/gather table of pinned pages or NULL on failure.
+ * A pointer to the scatter/gather table of pinned pages or errno on failure.


', or an ERR_PTR()-encoded errno code on failure'


   */
  struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object 
*shmem)
  {
@@ -688,7 +688,8 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
   * drm_gem_shmem_get_sg_table() should not be directly called by drivers.
   *
   * Returns:
- * A pointer to the scatter/gather table of pinned pages or errno on failure.
+ * A pointer to the scatter/gather table of pinned pages ERR_PTR()-encoded


', or an' before ERR_PTR

With the improved grammar:

Acked-by: Thomas Zimmermann 



+ * error code on failure.
   */
  struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object 
*shmem)
  {


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH 3/8] drm/display: Introduce a DRM display-helper module

2022-04-18 Thread Thomas Zimmermann

Hi Jani

Am 07.04.22 um 10:45 schrieb Jani Nikula:
...


I think another idea that could work is to use an intermediate symbol.
For DP, drivers would select the tristate DP_HELPER, which in turn
selects tristate DISPLAY_HELPER and boolean DISPLAY_DP_HELPER.  But this
would require a 'useless' symbol DP_HELPER only for convenience.  It's
an even less optimal solution, it seems.


Documentation/kbuild/kconfig-language.rst:

   Note:
select should be used with care. select will force
a symbol to a value without visiting the dependencies.
By abusing select you are able to select a symbol FOO even
if FOO depends on BAR that is not set.
-->  In general use select only for non-visible symbols
-->  (no prompts anywhere) and for symbols with no dependencies.
That will limit the usefulness but on the other hand avoid
the illegal configurations all over.

Most of the difficult Kconfig issues I've encountered over the years
come from not following the above two rules. People break those rules
for "convenience", causing a lot of inconvenience down the line.


I have meanwhile updated the patchset and all new boolean options are 
internal. No select will be performed on 'visible' symbols. So it should 
be fine.


Best regards
Thomas




BR,
Jani.




Best regards
Thomas


   --
Best regards,

Javier Martinez Canillas
Linux Engineering
Red Hat





--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH 1/2] of: Create platform devices for OF framebuffers

2022-04-18 Thread Thomas Zimmermann

Hi

Am 13.04.22 um 14:51 schrieb Rob Herring:
...

+
  /**
   * of_platform_populate() - Populate platform_devices from device tree data
   * @root: parent of the first level to probe or NULL for the root of the tree
@@ -541,9 +595,7 @@ static int __init of_platform_default_populate_init(void)
 of_node_put(node);
 }

-   node = of_get_compatible_child(of_chosen, "simple-framebuffer");
-   of_platform_device_create(node, NULL, NULL);
-   of_node_put(node);
+   of_platform_populate_framebuffers();

 /* Populate everything else. */
 of_platform_default_populate(NULL, NULL, NULL);


I'm pretty sure it's just this call that's the problem for PPC though
none of the above existed when adding this caused a regression. Can we
remove the ifdef and just make this call conditional on
!IS_ENABLED(CONFIG_PPC).


That didn't work. The boot process stops at some point. I'll send you an 
updated patch that covers most of the function with IS_ENABLED(CONFIG_PPC)


Best regards
Thomas





@@ -551,6 +603,20 @@ static int __init of_platform_default_populate_init(void)
 return 0;
  }
  arch_initcall_sync(of_platform_default_populate_init);
+#else
+static int __init of_platform_default_populate_init(void)
+{
+   device_links_supplier_sync_state_pause();
+
+   if (!of_have_populated_dt())
+   return -ENODEV;
+
+   of_platform_populate_framebuffers();
+
+   return 0;
+}
+arch_initcall_sync(of_platform_default_populate_init);
+#endif

  static int __init of_platform_sync_state_init(void)
  {
@@ -558,7 +624,6 @@ static int __init of_platform_sync_state_init(void)
 return 0;
  }
  late_initcall_sync(of_platform_sync_state_init);
-#endif

  int of_platform_device_destroy(struct device *dev, void *data)
  {


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


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

2022-04-18 Thread Doug Anderson
Hi,

On Fri, Apr 15, 2022 at 5:14 PM Dmitry Baryshkov
 wrote:
>
> 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.

Breadcrumbs: I've posted this as:

https://lore.kernel.org/r/20220418171757.2282651-1-diand...@chromium.org

-Doug


[PATCH v3 4/4] drm/bridge: parade-ps8640: Provide wait_hpd_asserted() in struct drm_dp_aux

2022-04-18 Thread Douglas Anderson
This implements the callback added by the patch ("drm/dp: Add
wait_hpd_asserted() callback to struct drm_dp_aux").

With this change and all the two "DP AUX Endpoint" drivers changed to
use wait_hpd_asserted(), we no longer need to have an long delay in
the AUX transfer function. It's up to the panel code to make sure that
the panel is powered now. If someone tried to call the aux transfer
function without making sure the panel is powered we'll just get a
normal transfer failure.

We'll still keep the wait for HPD in the pre_enable() function. Though
it's probably not actually needed there, this driver is used in the
old mode (pre-DP AUX Endpoints) and it may be important for those
cases. If nothing else, it shouldn't cause any big problems.

Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Change is_hpd_asserted() to wait_hpd_asserted()

 drivers/gpu/drm/bridge/parade-ps8640.c | 34 --
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index 9766cbbd62ad..2f19a8c89880 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -168,23 +168,30 @@ static bool ps8640_of_panel_on_aux_bus(struct device *dev)
return true;
 }
 
-static int ps8640_ensure_hpd(struct ps8640 *ps_bridge)
+static int _ps8640_wait_hpd_asserted(struct ps8640 *ps_bridge, unsigned long 
wait_us)
 {
struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
-   struct device *dev = _bridge->page[PAGE2_TOP_CNTL]->dev;
int status;
-   int ret;
 
/*
 * Apparently something about the firmware in the chip signals that
 * HPD goes high by reporting GPIO9 as high (even though HPD isn't
 * actually connected to GPIO9).
 */
-   ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
-  status & PS_GPIO9, 20 * 1000, 200 * 
1000);
+   return regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
+   status & PS_GPIO9, wait_us / 10, 
wait_us);
+}
 
-   if (ret < 0)
-   dev_warn(dev, "HPD didn't go high: %d\n", ret);
+static int ps8640_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long 
wait_us)
+{
+   struct ps8640 *ps_bridge = aux_to_ps8640(aux);
+   struct device *dev = _bridge->page[PAGE0_DP_CNTL]->dev;
+   int ret;
+
+   pm_runtime_get_sync(dev);
+   ret = _ps8640_wait_hpd_asserted(ps_bridge, wait_us);
+   pm_runtime_mark_last_busy(dev);
+   pm_runtime_put_autosuspend(dev);
 
return ret;
 }
@@ -323,9 +330,7 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
int ret;
 
pm_runtime_get_sync(dev);
-   ret = ps8640_ensure_hpd(ps_bridge);
-   if (!ret)
-   ret = ps8640_aux_transfer_msg(aux, msg);
+   ret = ps8640_aux_transfer_msg(aux, msg);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
 
@@ -369,8 +374,8 @@ static int __maybe_unused ps8640_resume(struct device *dev)
 * Mystery 200 ms delay for the "MCU to be ready". It's unclear if
 * this is truly necessary since the MCU will already signal that
 * things are "good to go" by signaling HPD on "gpio 9". See
-* ps8640_ensure_hpd(). For now we'll keep this mystery delay just in
-* case.
+* _ps8640_wait_hpd_asserted(). For now we'll keep this mystery delay
+* just in case.
 */
msleep(200);
 
@@ -406,7 +411,9 @@ static void ps8640_pre_enable(struct drm_bridge *bridge)
int ret;
 
pm_runtime_get_sync(dev);
-   ps8640_ensure_hpd(ps_bridge);
+   ret = _ps8640_wait_hpd_asserted(ps_bridge, 200 * 1000);
+   if (ret < 0)
+   dev_warn(dev, "HPD didn't go high: %d\n", ret);
 
/*
 * The Manufacturer Command Set (MCS) is a device dependent interface
@@ -652,6 +659,7 @@ static int ps8640_probe(struct i2c_client *client)
ps_bridge->aux.name = "parade-ps8640-aux";
ps_bridge->aux.dev = dev;
ps_bridge->aux.transfer = ps8640_aux_transfer;
+   ps_bridge->aux.wait_hpd_asserted = ps8640_wait_hpd_asserted;
drm_dp_aux_init(_bridge->aux);
 
pm_runtime_enable(dev);
-- 
2.36.0.rc0.470.gd361397f0d-goog



[PATCH v3 3/4] drm/panel: atna33xc20: Take advantage of wait_hpd_asserted() in struct drm_dp_aux

2022-04-18 Thread Douglas Anderson
Let's add support for being able to read the HPD pin even if it's
hooked directly to the controller. This will let us take away the
waiting in the AUX transfer functions of the eDP controller drivers.

Signed-off-by: Douglas Anderson 
---

Changes in v3:
- Don't check "hpd_asserted" boolean when unset.
- Handle errors from gpiod_get_value_cansleep() properly.

Changes in v2:
- Change is_hpd_asserted() to wait_hpd_asserted()

 .../gpu/drm/panel/panel-samsung-atna33xc20.c  | 41 +--
 1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c 
b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
index 20666b6217e7..5ef1b4032c56 100644
--- a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
+++ b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
@@ -19,6 +19,10 @@
 #include 
 #include 
 
+/* T3 VCC to HPD high is max 200 ms */
+#define HPD_MAX_MS 200
+#define HPD_MAX_US (HPD_MAX_MS * 1000)
+
 struct atana33xc20_panel {
struct drm_panel base;
bool prepared;
@@ -30,6 +34,7 @@ struct atana33xc20_panel {
 
struct regulator *supply;
struct gpio_desc *el_on3_gpio;
+   struct drm_dp_aux *aux;
 
struct edid *edid;
 
@@ -79,7 +84,7 @@ static int atana33xc20_suspend(struct device *dev)
 static int atana33xc20_resume(struct device *dev)
 {
struct atana33xc20_panel *p = dev_get_drvdata(dev);
-   bool hpd_asserted = false;
+   int hpd_asserted;
int ret;
 
/* T12 (Power off time) is min 500 ms */
@@ -91,20 +96,28 @@ static int atana33xc20_resume(struct device *dev)
p->powered_on_time = ktime_get();
 
/*
-* Handle HPD. Note: if HPD is hooked up to a dedicated pin on the
-* eDP controller then "no_hpd" will be false _and_ "hpd_gpio" will be
-* NULL. It's up to the controller driver to wait for HPD after
-* preparing the panel in that case.
+* Note that it's possible that no_hpd is false, hpd_gpio is
+* NULL, and wait_hpd_asserted is NULL. This is because
+* wait_hpd_asserted() is optional even if HPD is hooked up to
+* a dedicated pin on the eDP controller. In this case we just
+* assume that the controller driver will wait for HPD at the
+* right times.
 */
if (p->no_hpd) {
-   /* T3 VCC to HPD high is max 200 ms */
-   msleep(200);
-   } else if (p->hpd_gpio) {
-   ret = readx_poll_timeout(gpiod_get_value_cansleep, p->hpd_gpio,
-hpd_asserted, hpd_asserted,
-1000, 20);
-   if (!hpd_asserted)
-   dev_warn(dev, "Timeout waiting for HPD\n");
+   msleep(HPD_MAX_MS);
+   } else {
+   if (p->hpd_gpio) {
+   ret = readx_poll_timeout(gpiod_get_value_cansleep,
+p->hpd_gpio, hpd_asserted,
+hpd_asserted, 1000, 
HPD_MAX_US);
+   if (hpd_asserted < 0)
+   ret = hpd_asserted;
+   } else if (p->aux->wait_hpd_asserted) {
+   ret = p->aux->wait_hpd_asserted(p->aux, HPD_MAX_US);
+   }
+
+   if (ret)
+   dev_warn(dev, "Error waiting for HPD: %d\n", ret);
}
 
return 0;
@@ -263,6 +276,8 @@ static int atana33xc20_probe(struct dp_aux_ep_device 
*aux_ep)
return -ENOMEM;
dev_set_drvdata(dev, panel);
 
+   panel->aux = aux_ep->aux;
+
panel->supply = devm_regulator_get(dev, "power");
if (IS_ERR(panel->supply))
return dev_err_probe(dev, PTR_ERR(panel->supply),
-- 
2.36.0.rc0.470.gd361397f0d-goog



[PATCH v3 1/4] drm/dp: Add wait_hpd_asserted() callback to struct drm_dp_aux

2022-04-18 Thread Douglas Anderson
Sometimes it's useful for users of the DP AUX bus (like panels) to be
able to poll HPD. Let's add a callback that allows DP AUX busses
drivers to provide this.

Suggested-by: Dmitry Baryshkov 
Signed-off-by: Douglas Anderson 
---
Left Dmitry's Reviewed-by tag off since patch changed enough.

(no changes since v2)

Changes in v2:
- Change is_hpd_asserted() to wait_hpd_asserted()

 include/drm/dp/drm_dp_helper.h | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h
index 53d1e722f4de..0940c415db8c 100644
--- a/include/drm/dp/drm_dp_helper.h
+++ b/include/drm/dp/drm_dp_helper.h
@@ -2035,6 +2035,32 @@ struct drm_dp_aux {
ssize_t (*transfer)(struct drm_dp_aux *aux,
struct drm_dp_aux_msg *msg);
 
+   /**
+* @wait_hpd_asserted: wait for HPD to be asserted
+*
+* This is mainly useful for eDP panels drivers to wait for an eDP
+* panel to finish powering on. This is an optional function.
+*
+* This function will efficiently wait for up to `wait_us` microseconds
+* for HPD to be asserted and might sleep.
+*
+* This function returns 0 if HPD was asserted or -ETIMEDOUT if time
+* expired and HPD wasn't asserted. This function should not print
+* timeout errors to the log.
+*
+* The semantics of this function are designed to match the
+* readx_poll_timeout() function. That means a `wait_us` of 0 means
+* to wait forever. If you want to do a quick poll you could pass 1
+* for `wait_us`.
+*
+* NOTE: this function specifically reports the state of the HPD pin
+* that's associated with the DP AUX channel. This is different from
+* the HPD concept in much of the rest of DRM which is more about
+* physical presence of a display. For eDP, for instance, a display is
+* assumed always present even if the HPD pin is deasserted.
+*/
+   int (*wait_hpd_asserted)(struct drm_dp_aux *aux, unsigned long wait_us);
+
/**
 * @i2c_nack_count: Counts I2C NACKs, used for DP validation.
 */
-- 
2.36.0.rc0.470.gd361397f0d-goog



[PATCH v3 2/4] drm/panel-edp: Take advantage of wait_hpd_asserted() in struct drm_dp_aux

2022-04-18 Thread Douglas Anderson
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 
---

(no changes since v2)

Changes in v2:
- Change is_hpd_asserted() to wait_hpd_asserted()

 drivers/gpu/drm/panel/panel-edp.c | 33 +--
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-edp.c 
b/drivers/gpu/drm/panel/panel-edp.c
index 1732b4f56e38..086e0bf52fb9 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -417,6 +417,11 @@ 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->wait_hpd_asserted));
+}
+
 static int panel_edp_prepare_once(struct panel_edp *p)
 {
struct device *dev = p->base.dev;
@@ -441,17 +446,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,
-hpd_asserted, hpd_asserted,
-1000, hpd_wait_us);
-   if (hpd_asserted < 0)
-   err = hpd_asserted;
+   if (p->hpd_gpio) {
+   err = readx_poll_timeout(gpiod_get_value_cansleep,
+p->hpd_gpio, hpd_asserted,
+hpd_asserted, 1000, 
hpd_wait_us);
+   if (hpd_asserted < 0)
+   err = hpd_asserted;
+   } else {
+   err = p->aux->wait_hpd_asserted(p->aux, hpd_wait_us);
+   }
 
if (err) {
if (err != -ETIMEDOUT)
@@ -532,18 +541,22 @@ static int panel_edp_enable(struct drm_panel *panel)
/*
 * If there is a "prepare_to_enable" delay then that's supposed to be
 * the delay from HPD going high until we can turn the backlight on.
-* However, we can only count this if HPD is handled by the panel
-* driver, not if it goes to a dedicated pin on the controller.
+* However, we can only count this if HPD is readable by the panel
+* driver.
+*
 * If we aren't handling the HPD pin ourselves then the best we
 * can do is assume that HPD went high immediately before we were
-* called (and link training took zero time).
+* called (and link training took zero time). Note that "no-hpd"
+* actually counts as handling HPD ourselves since we're doing the
+* worst case delay (in prepare) ourselves.
 *
 * NOTE: if we ever end up in this "if" statement then we're
 * guaranteed that the panel_edp_wait() call below will do no delay.
 * It already handles that case, though, so we don't need any special
 * code for it.
 */
-   if (p->desc->delay.prepare_to_enable && !p->hpd_gpio && !p->no_hpd)
+   if (p->desc->delay.prepare_to_enable &&
+   !panel_edp_can_read_hpd(p) && !p->no_hpd)
delay = max(delay, p->desc->delay.prepare_to_enable);
 
if (delay)
-- 
2.36.0.rc0.470.gd361397f0d-goog



[PATCH v3 0/4] drm/dp: Introduce wait_hpd_asserted() for the DP AUX bus

2022-04-18 Thread Douglas Anderson
This is the 2nd four patches from my RFC series ("drm/dp: Improvements
for DP AUX channel") [1]. I've broken the series in two so we can make
progress on the two halves separately.

v2 of this series changes to add wait_hpd_asserted() instead of
is_hpd_asserted(). This allows us to move the extra delay needed for
ps8640 into the ps8640 driver itself.

The idea for this series came up during the review process of
Sankeerth's series trying to add eDP for Qualcomm SoCs [2].

This _doesn't_ attempt to fix the Analogix driver. If this works out,
ideally someone can post a patch up to do that.

[1] https://lore.kernel.org/r/20220409023628.2104952-1-diand...@chromium.org/
[2] 
https://lore.kernel.org/r/1648656179-10347-2-git-send-email-quic_sbill...@quicinc.com/

Changes in v3:
- Don't check "hpd_asserted" boolean when unset.
- Handle errors from gpiod_get_value_cansleep() properly.

Changes in v2:
- Change is_hpd_asserted() to wait_hpd_asserted()

Douglas Anderson (4):
  drm/dp: Add wait_hpd_asserted() callback to struct drm_dp_aux
  drm/panel-edp: Take advantage of wait_hpd_asserted() in struct
drm_dp_aux
  drm/panel: atna33xc20: Take advantage of wait_hpd_asserted() in struct
drm_dp_aux
  drm/bridge: parade-ps8640: Provide wait_hpd_asserted() in struct
drm_dp_aux

 drivers/gpu/drm/bridge/parade-ps8640.c| 34 +--
 drivers/gpu/drm/panel/panel-edp.c | 33 ++-
 .../gpu/drm/panel/panel-samsung-atna33xc20.c  | 41 +--
 include/drm/dp/drm_dp_helper.h| 26 
 4 files changed, 98 insertions(+), 36 deletions(-)

-- 
2.36.0.rc0.470.gd361397f0d-goog



Re: [PATCH v2 3/4] drm/panel: atna33xc20: Take advantage of wait_hpd_asserted() in struct drm_dp_aux

2022-04-18 Thread Doug Anderson
Hi,

On Mon, Apr 18, 2022 at 9:58 AM 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 let us take away the
> waiting in the AUX transfer functions of the eDP controller drivers.
>
> Signed-off-by: Douglas Anderson 
> ---
>
> Changes in v2:
> - Change is_hpd_asserted() to wait_hpd_asserted()
>
>  .../gpu/drm/panel/panel-samsung-atna33xc20.c  | 38 ---
>  1 file changed, 25 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c 
> b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
> index 20666b6217e7..7f9af3e9aeb8 100644
> --- a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
> +++ b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
> @@ -19,6 +19,10 @@
>  #include 
>  #include 
>
> +/* T3 VCC to HPD high is max 200 ms */
> +#define HPD_MAX_MS 200
> +#define HPD_MAX_US (HPD_MAX_MS * 1000)
> +
>  struct atana33xc20_panel {
> struct drm_panel base;
> bool prepared;
> @@ -30,6 +34,7 @@ struct atana33xc20_panel {
>
> struct regulator *supply;
> struct gpio_desc *el_on3_gpio;
> +   struct drm_dp_aux *aux;
>
> struct edid *edid;
>
> @@ -90,20 +95,25 @@ static int atana33xc20_resume(struct device *dev)
> return ret;
> p->powered_on_time = ktime_get();
>
> -   /*
> -* Handle HPD. Note: if HPD is hooked up to a dedicated pin on the
> -* eDP controller then "no_hpd" will be false _and_ "hpd_gpio" will be
> -* NULL. It's up to the controller driver to wait for HPD after
> -* preparing the panel in that case.
> -*/
> if (p->no_hpd) {
> -   /* T3 VCC to HPD high is max 200 ms */
> -   msleep(200);
> -   } else if (p->hpd_gpio) {
> -   ret = readx_poll_timeout(gpiod_get_value_cansleep, 
> p->hpd_gpio,
> -hpd_asserted, hpd_asserted,
> -1000, 20);
> -   if (!hpd_asserted)
> +   msleep(HPD_MAX_MS);
> +   } else {
> +   if (p->hpd_gpio)
> +   ret = readx_poll_timeout(gpiod_get_value_cansleep,
> +p->hpd_gpio, hpd_asserted,
> +hpd_asserted, 1000, 
> HPD_MAX_US);
> +   else if (p->aux->wait_hpd_asserted)
> +   ret = p->aux->wait_hpd_asserted(p->aux, HPD_MAX_US);
> +
> +   /*
> +* Note that it's possible that no_hpd is false, hpd_gpio is
> +* NULL, and wait_hpd_asserted is NULL. This is because
> +* wait_hpd_asserted() is optional even if HPD is hooked up to
> +* a dedicated pin on the eDP controller. In this case we just
> +* assume that the controller driver will wait for HPD at the
> +* right times.
> +*/
> +   if (!hpd_asserted && (p->hpd_gpio || 
> p->aux->wait_hpd_asserted))
> dev_warn(dev, "Timeout waiting for HPD\n");

Ugh, right after I sent this out I found a bug! :( It should be
checking for "ret", not "hpd_asserted" in the above "if" test. I'll
spin out a quick v3 right away!

-Doug


[PATCH v2 4/4] drm/bridge: parade-ps8640: Provide wait_hpd_asserted() in struct drm_dp_aux

2022-04-18 Thread Douglas Anderson
This implements the callback added by the patch ("drm/dp: Add
wait_hpd_asserted() callback to struct drm_dp_aux").

With this change and all the two "DP AUX Endpoint" drivers changed to
use wait_hpd_asserted(), we no longer need to have an long delay in
the AUX transfer function. It's up to the panel code to make sure that
the panel is powered now. If someone tried to call the aux transfer
function without making sure the panel is powered we'll just get a
normal transfer failure.

We'll still keep the wait for HPD in the pre_enable() function. Though
it's probably not actually needed there, this driver is used in the
old mode (pre-DP AUX Endpoints) and it may be important for those
cases. If nothing else, it shouldn't cause any big problems.

Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Change is_hpd_asserted() to wait_hpd_asserted()

 drivers/gpu/drm/bridge/parade-ps8640.c | 34 --
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index 9766cbbd62ad..2f19a8c89880 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -168,23 +168,30 @@ static bool ps8640_of_panel_on_aux_bus(struct device *dev)
return true;
 }
 
-static int ps8640_ensure_hpd(struct ps8640 *ps_bridge)
+static int _ps8640_wait_hpd_asserted(struct ps8640 *ps_bridge, unsigned long 
wait_us)
 {
struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
-   struct device *dev = _bridge->page[PAGE2_TOP_CNTL]->dev;
int status;
-   int ret;
 
/*
 * Apparently something about the firmware in the chip signals that
 * HPD goes high by reporting GPIO9 as high (even though HPD isn't
 * actually connected to GPIO9).
 */
-   ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
-  status & PS_GPIO9, 20 * 1000, 200 * 
1000);
+   return regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
+   status & PS_GPIO9, wait_us / 10, 
wait_us);
+}
 
-   if (ret < 0)
-   dev_warn(dev, "HPD didn't go high: %d\n", ret);
+static int ps8640_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long 
wait_us)
+{
+   struct ps8640 *ps_bridge = aux_to_ps8640(aux);
+   struct device *dev = _bridge->page[PAGE0_DP_CNTL]->dev;
+   int ret;
+
+   pm_runtime_get_sync(dev);
+   ret = _ps8640_wait_hpd_asserted(ps_bridge, wait_us);
+   pm_runtime_mark_last_busy(dev);
+   pm_runtime_put_autosuspend(dev);
 
return ret;
 }
@@ -323,9 +330,7 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
int ret;
 
pm_runtime_get_sync(dev);
-   ret = ps8640_ensure_hpd(ps_bridge);
-   if (!ret)
-   ret = ps8640_aux_transfer_msg(aux, msg);
+   ret = ps8640_aux_transfer_msg(aux, msg);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
 
@@ -369,8 +374,8 @@ static int __maybe_unused ps8640_resume(struct device *dev)
 * Mystery 200 ms delay for the "MCU to be ready". It's unclear if
 * this is truly necessary since the MCU will already signal that
 * things are "good to go" by signaling HPD on "gpio 9". See
-* ps8640_ensure_hpd(). For now we'll keep this mystery delay just in
-* case.
+* _ps8640_wait_hpd_asserted(). For now we'll keep this mystery delay
+* just in case.
 */
msleep(200);
 
@@ -406,7 +411,9 @@ static void ps8640_pre_enable(struct drm_bridge *bridge)
int ret;
 
pm_runtime_get_sync(dev);
-   ps8640_ensure_hpd(ps_bridge);
+   ret = _ps8640_wait_hpd_asserted(ps_bridge, 200 * 1000);
+   if (ret < 0)
+   dev_warn(dev, "HPD didn't go high: %d\n", ret);
 
/*
 * The Manufacturer Command Set (MCS) is a device dependent interface
@@ -652,6 +659,7 @@ static int ps8640_probe(struct i2c_client *client)
ps_bridge->aux.name = "parade-ps8640-aux";
ps_bridge->aux.dev = dev;
ps_bridge->aux.transfer = ps8640_aux_transfer;
+   ps_bridge->aux.wait_hpd_asserted = ps8640_wait_hpd_asserted;
drm_dp_aux_init(_bridge->aux);
 
pm_runtime_enable(dev);
-- 
2.36.0.rc0.470.gd361397f0d-goog



[PATCH v2 3/4] drm/panel: atna33xc20: Take advantage of wait_hpd_asserted() in struct drm_dp_aux

2022-04-18 Thread Douglas Anderson
Let's add support for being able to read the HPD pin even if it's
hooked directly to the controller. This will let us take away the
waiting in the AUX transfer functions of the eDP controller drivers.

Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Change is_hpd_asserted() to wait_hpd_asserted()

 .../gpu/drm/panel/panel-samsung-atna33xc20.c  | 38 ---
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c 
b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
index 20666b6217e7..7f9af3e9aeb8 100644
--- a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
+++ b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
@@ -19,6 +19,10 @@
 #include 
 #include 
 
+/* T3 VCC to HPD high is max 200 ms */
+#define HPD_MAX_MS 200
+#define HPD_MAX_US (HPD_MAX_MS * 1000)
+
 struct atana33xc20_panel {
struct drm_panel base;
bool prepared;
@@ -30,6 +34,7 @@ struct atana33xc20_panel {
 
struct regulator *supply;
struct gpio_desc *el_on3_gpio;
+   struct drm_dp_aux *aux;
 
struct edid *edid;
 
@@ -90,20 +95,25 @@ static int atana33xc20_resume(struct device *dev)
return ret;
p->powered_on_time = ktime_get();
 
-   /*
-* Handle HPD. Note: if HPD is hooked up to a dedicated pin on the
-* eDP controller then "no_hpd" will be false _and_ "hpd_gpio" will be
-* NULL. It's up to the controller driver to wait for HPD after
-* preparing the panel in that case.
-*/
if (p->no_hpd) {
-   /* T3 VCC to HPD high is max 200 ms */
-   msleep(200);
-   } else if (p->hpd_gpio) {
-   ret = readx_poll_timeout(gpiod_get_value_cansleep, p->hpd_gpio,
-hpd_asserted, hpd_asserted,
-1000, 20);
-   if (!hpd_asserted)
+   msleep(HPD_MAX_MS);
+   } else {
+   if (p->hpd_gpio)
+   ret = readx_poll_timeout(gpiod_get_value_cansleep,
+p->hpd_gpio, hpd_asserted,
+hpd_asserted, 1000, 
HPD_MAX_US);
+   else if (p->aux->wait_hpd_asserted)
+   ret = p->aux->wait_hpd_asserted(p->aux, HPD_MAX_US);
+
+   /*
+* Note that it's possible that no_hpd is false, hpd_gpio is
+* NULL, and wait_hpd_asserted is NULL. This is because
+* wait_hpd_asserted() is optional even if HPD is hooked up to
+* a dedicated pin on the eDP controller. In this case we just
+* assume that the controller driver will wait for HPD at the
+* right times.
+*/
+   if (!hpd_asserted && (p->hpd_gpio || p->aux->wait_hpd_asserted))
dev_warn(dev, "Timeout waiting for HPD\n");
}
 
@@ -263,6 +273,8 @@ static int atana33xc20_probe(struct dp_aux_ep_device 
*aux_ep)
return -ENOMEM;
dev_set_drvdata(dev, panel);
 
+   panel->aux = aux_ep->aux;
+
panel->supply = devm_regulator_get(dev, "power");
if (IS_ERR(panel->supply))
return dev_err_probe(dev, PTR_ERR(panel->supply),
-- 
2.36.0.rc0.470.gd361397f0d-goog



[PATCH v2 2/4] drm/panel-edp: Take advantage of wait_hpd_asserted() in struct drm_dp_aux

2022-04-18 Thread Douglas Anderson
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 
---

Changes in v2:
- Change is_hpd_asserted() to wait_hpd_asserted()

 drivers/gpu/drm/panel/panel-edp.c | 33 +--
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-edp.c 
b/drivers/gpu/drm/panel/panel-edp.c
index 1732b4f56e38..086e0bf52fb9 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -417,6 +417,11 @@ 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->wait_hpd_asserted));
+}
+
 static int panel_edp_prepare_once(struct panel_edp *p)
 {
struct device *dev = p->base.dev;
@@ -441,17 +446,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,
-hpd_asserted, hpd_asserted,
-1000, hpd_wait_us);
-   if (hpd_asserted < 0)
-   err = hpd_asserted;
+   if (p->hpd_gpio) {
+   err = readx_poll_timeout(gpiod_get_value_cansleep,
+p->hpd_gpio, hpd_asserted,
+hpd_asserted, 1000, 
hpd_wait_us);
+   if (hpd_asserted < 0)
+   err = hpd_asserted;
+   } else {
+   err = p->aux->wait_hpd_asserted(p->aux, hpd_wait_us);
+   }
 
if (err) {
if (err != -ETIMEDOUT)
@@ -532,18 +541,22 @@ static int panel_edp_enable(struct drm_panel *panel)
/*
 * If there is a "prepare_to_enable" delay then that's supposed to be
 * the delay from HPD going high until we can turn the backlight on.
-* However, we can only count this if HPD is handled by the panel
-* driver, not if it goes to a dedicated pin on the controller.
+* However, we can only count this if HPD is readable by the panel
+* driver.
+*
 * If we aren't handling the HPD pin ourselves then the best we
 * can do is assume that HPD went high immediately before we were
-* called (and link training took zero time).
+* called (and link training took zero time). Note that "no-hpd"
+* actually counts as handling HPD ourselves since we're doing the
+* worst case delay (in prepare) ourselves.
 *
 * NOTE: if we ever end up in this "if" statement then we're
 * guaranteed that the panel_edp_wait() call below will do no delay.
 * It already handles that case, though, so we don't need any special
 * code for it.
 */
-   if (p->desc->delay.prepare_to_enable && !p->hpd_gpio && !p->no_hpd)
+   if (p->desc->delay.prepare_to_enable &&
+   !panel_edp_can_read_hpd(p) && !p->no_hpd)
delay = max(delay, p->desc->delay.prepare_to_enable);
 
if (delay)
-- 
2.36.0.rc0.470.gd361397f0d-goog



[PATCH v2 1/4] drm/dp: Add wait_hpd_asserted() callback to struct drm_dp_aux

2022-04-18 Thread Douglas Anderson
Sometimes it's useful for users of the DP AUX bus (like panels) to be
able to poll HPD. Let's add a callback that allows DP AUX busses
drivers to provide this.

Suggested-by: Dmitry Baryshkov 
Signed-off-by: Douglas Anderson 
---
Left Dmitry's Reviewed-by tag off since patch changed enough.

Changes in v2:
- Change is_hpd_asserted() to wait_hpd_asserted()

 include/drm/dp/drm_dp_helper.h | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h
index 53d1e722f4de..0940c415db8c 100644
--- a/include/drm/dp/drm_dp_helper.h
+++ b/include/drm/dp/drm_dp_helper.h
@@ -2035,6 +2035,32 @@ struct drm_dp_aux {
ssize_t (*transfer)(struct drm_dp_aux *aux,
struct drm_dp_aux_msg *msg);
 
+   /**
+* @wait_hpd_asserted: wait for HPD to be asserted
+*
+* This is mainly useful for eDP panels drivers to wait for an eDP
+* panel to finish powering on. This is an optional function.
+*
+* This function will efficiently wait for up to `wait_us` microseconds
+* for HPD to be asserted and might sleep.
+*
+* This function returns 0 if HPD was asserted or -ETIMEDOUT if time
+* expired and HPD wasn't asserted. This function should not print
+* timeout errors to the log.
+*
+* The semantics of this function are designed to match the
+* readx_poll_timeout() function. That means a `wait_us` of 0 means
+* to wait forever. If you want to do a quick poll you could pass 1
+* for `wait_us`.
+*
+* NOTE: this function specifically reports the state of the HPD pin
+* that's associated with the DP AUX channel. This is different from
+* the HPD concept in much of the rest of DRM which is more about
+* physical presence of a display. For eDP, for instance, a display is
+* assumed always present even if the HPD pin is deasserted.
+*/
+   int (*wait_hpd_asserted)(struct drm_dp_aux *aux, unsigned long wait_us);
+
/**
 * @i2c_nack_count: Counts I2C NACKs, used for DP validation.
 */
-- 
2.36.0.rc0.470.gd361397f0d-goog



[PATCH v2 0/4] drm/dp: Introduce wait_hpd_asserted() for the DP AUX bus

2022-04-18 Thread Douglas Anderson
This is the 2nd four patches from my RFC series ("drm/dp: Improvements
for DP AUX channel") [1]. I've broken the series in two so we can make
progress on the two halves separately.

v2 of this series changes to add wait_hpd_asserted() instead of
is_hpd_asserted(). This allows us to move the extra delay needed for
ps8640 into the ps8640 driver itself.

The idea for this series came up during the review process of
Sankeerth's series trying to add eDP for Qualcomm SoCs [2].

This _doesn't_ attempt to fix the Analogix driver. If this works out,
ideally someone can post a patch up to do that.

[1] https://lore.kernel.org/r/20220409023628.2104952-1-diand...@chromium.org/
[2] 
https://lore.kernel.org/r/1648656179-10347-2-git-send-email-quic_sbill...@quicinc.com/

Changes in v2:
- Change is_hpd_asserted() to wait_hpd_asserted()

Douglas Anderson (4):
  drm/dp: Add wait_hpd_asserted() callback to struct drm_dp_aux
  drm/panel-edp: Take advantage of wait_hpd_asserted() in struct
drm_dp_aux
  drm/panel: atna33xc20: Take advantage of wait_hpd_asserted() in struct
drm_dp_aux
  drm/bridge: parade-ps8640: Provide wait_hpd_asserted() in struct
drm_dp_aux

 drivers/gpu/drm/bridge/parade-ps8640.c| 34 ++---
 drivers/gpu/drm/panel/panel-edp.c | 33 +++-
 .../gpu/drm/panel/panel-samsung-atna33xc20.c  | 38 ---
 include/drm/dp/drm_dp_helper.h| 26 +
 4 files changed, 95 insertions(+), 36 deletions(-)

-- 
2.36.0.rc0.470.gd361397f0d-goog



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

2022-04-18 Thread Dmitry Baryshkov

On 16/04/2022 02:47, 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(>event_q) to probe()
-- move spin_lock_init(>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 


Reviewed-by: Dmitry Baryshkov 


---
  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(>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(_priv->event_q);
-   spin_lock_init(_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(>event_mutex);
+   init_waitqueue_head(>event_q);
+   spin_lock_init(>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);
  }
  



--
With best wishes
Dmitry


Re: [PATCH 1/9] vfio: Make vfio_(un)register_notifier accept a vfio_device

2022-04-18 Thread Jason Gunthorpe
On Mon, Apr 18, 2022 at 11:28:30AM -0400, Tony Krowiak wrote:
> > diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
> > index a4555014bd1e72..8a5c46aa2bef61 100644
> > +++ b/drivers/vfio/vfio.c
> > @@ -2484,19 +2484,15 @@ static int vfio_unregister_group_notifier(struct 
> > vfio_group *group,
> > return ret;
> >   }
> > -int vfio_register_notifier(struct device *dev, enum vfio_notify_type type,
> > +int vfio_register_notifier(struct vfio_device *dev, enum vfio_notify_type 
> > type,
> >unsigned long *events, struct notifier_block *nb)
> >   {
> > -   struct vfio_group *group;
> > +   struct vfio_group *group = dev->group;
> 
> Is there a guarantee that dev != NULL? The original code below checks
> the value of dev, so why is that check eliminated here?

Yes, no kernel driver calls this with null dev. The original code
should have been a WARN_ON as it is just protecting against a buggy
driver. In this case if the driver is buggy we simply generate a
backtrace through a null deref panic.

Jason


[PATCH] drm/nouveau/gr/gf100-: change gf108_gr_fwif from global to static

2022-04-18 Thread Tom Rix
Smatch reports this issue
gf108.c:147:1: warning: symbol 'gf108_gr_fwif'
  was not declared. Should it be static?

gf108_gr_fwif is only used in gf108.c.  Single
file variables should not be global so change
gf108_gr_fwif's storage-class specifier to static.

Signed-off-by: Tom Rix 
---
 drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
index 030640bb3dca..ab3760e804b8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
@@ -143,7 +143,7 @@ gf108_gr = {
}
 };
 
-const struct gf100_gr_fwif
+static const struct gf100_gr_fwif
 gf108_gr_fwif[] = {
{ -1, gf100_gr_load, _gr },
{ -1, gf100_gr_nofw, _gr },
-- 
2.27.0



[PATCH v2 2/2] drm: bridge: ldb: Implement simple NXP i.MX8M LDB bridge

2022-04-18 Thread Marek Vasut
The i.MX8MP contains two syscon registers which are responsible
for configuring the on-SoC DPI-to-LVDS serializer. Implement a
simple bridge driver for this serializer.

Signed-off-by: Marek Vasut 
Cc: Laurent Pinchart 
Cc: Lucas Stach 
Cc: Maxime Ripard 
Cc: Peng Fan 
Cc: Robby Cai 
Cc: Robert Foss 
Cc: Sam Ravnborg 
Cc: Thomas Zimmermann 
To: dri-devel@lists.freedesktop.org
--
V2: - Rename syscon to fsl,syscon
---
 drivers/gpu/drm/bridge/Kconfig   |   8 +
 drivers/gpu/drm/bridge/Makefile  |   1 +
 drivers/gpu/drm/bridge/nxp-ldb.c | 343 +++
 3 files changed, 352 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/nxp-ldb.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 20f9bc7f4be54..7fe7088a2bef5 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -185,6 +185,14 @@ config DRM_NWL_MIPI_DSI
  This enables the Northwest Logic MIPI DSI Host controller as
  for example found on NXP's i.MX8 Processors.
 
+config DRM_NXP_LDB
+   tristate "NXP i.MX8M LDB bridge"
+   depends on OF
+   select DRM_KMS_HELPER
+   select DRM_PANEL_BRIDGE
+   help
+ Support for i.MX8M DPI-to-LVDS on-SoC encoder.
+
 config DRM_NXP_PTN3460
tristate "NXP PTN3460 DP/LVDS bridge"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index bdffad2a7ed3a..f800b2331d9e0 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
 obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o
 obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o
 obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += 
megachips-stdp-ge-b850v3-fw.o
+obj-$(CONFIG_DRM_NXP_LDB) += nxp-ldb.o
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
 obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
diff --git a/drivers/gpu/drm/bridge/nxp-ldb.c b/drivers/gpu/drm/bridge/nxp-ldb.c
new file mode 100644
index 0..7b8de235876ea
--- /dev/null
+++ b/drivers/gpu/drm/bridge/nxp-ldb.c
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2022 Marek Vasut 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define LDB_CTRL   0x5c
+#define LDB_CTRL_CH0_ENABLEBIT(0)
+#define LDB_CTRL_CH0_DI_SELECT BIT(1)
+#define LDB_CTRL_CH1_ENABLEBIT(2)
+#define LDB_CTRL_CH1_DI_SELECT BIT(3)
+#define LDB_CTRL_SPLIT_MODEBIT(4)
+#define LDB_CTRL_CH0_DATA_WIDTHBIT(5)
+#define LDB_CTRL_CH0_BIT_MAPPING   BIT(6)
+#define LDB_CTRL_CH1_DATA_WIDTHBIT(7)
+#define LDB_CTRL_CH1_BIT_MAPPING   BIT(8)
+#define LDB_CTRL_DI0_VSYNC_POLARITYBIT(9)
+#define LDB_CTRL_DI1_VSYNC_POLARITYBIT(10)
+#define LDB_CTRL_REG_CH0_FIFO_RESETBIT(11)
+#define LDB_CTRL_REG_CH1_FIFO_RESETBIT(12)
+#define LDB_CTRL_ASYNC_FIFO_ENABLE BIT(24)
+#define LDB_CTRL_ASYNC_FIFO_THRESHOLD_MASK GENMASK(27, 25)
+
+#define LVDS_CTRL  0x128
+#define LVDS_CTRL_CH0_EN   BIT(0)
+#define LVDS_CTRL_CH1_EN   BIT(1)
+#define LVDS_CTRL_VBG_EN   BIT(2)
+#define LVDS_CTRL_HS_ENBIT(3)
+#define LVDS_CTRL_PRE_EMPH_EN  BIT(4)
+#define LVDS_CTRL_PRE_EMPH_ADJ(n)  (((n) & 0x7) << 5)
+#define LVDS_CTRL_PRE_EMPH_ADJ_MASKGENMASK(7, 5)
+#define LVDS_CTRL_CM_ADJ(n)(((n) & 0x7) << 8)
+#define LVDS_CTRL_CM_ADJ_MASK  GENMASK(10, 8)
+#define LVDS_CTRL_CC_ADJ(n)(((n) & 0x7) << 11)
+#define LVDS_CTRL_CC_ADJ_MASK  GENMASK(13, 11)
+#define LVDS_CTRL_SLEW_ADJ(n)  (((n) & 0x7) << 14)
+#define LVDS_CTRL_SLEW_ADJ_MASKGENMASK(16, 14)
+#define LVDS_CTRL_VBG_ADJ(n)   (((n) & 0x7) << 17)
+#define LVDS_CTRL_VBG_ADJ_MASK GENMASK(19, 17)
+
+struct nxp_ldb {
+   struct device *dev;
+   struct drm_bridge bridge;
+   struct drm_bridge *panel_bridge;
+   struct clk *clk;
+   struct regmap *regmap;
+   bool lvds_dual_link;
+};
+
+static inline struct nxp_ldb *to_nxp_ldb(struct drm_bridge *bridge)
+{
+   return container_of(bridge, struct nxp_ldb, bridge);
+}
+
+static int nxp_ldb_attach(struct drm_bridge *bridge,
+   enum drm_bridge_attach_flags flags)
+{
+   struct nxp_ldb *nxp_ldb = to_nxp_ldb(bridge);
+
+   return drm_bridge_attach(bridge->encoder, nxp_ldb->panel_bridge,
+bridge, flags);
+}
+

[PATCH v2 1/2] dt-bindings: display: bridge: ldb: Implement simple NXP i.MX8M LDB bridge

2022-04-18 Thread Marek Vasut
The i.MX8MP contains two syscon registers which are responsible
for configuring the on-SoC DPI-to-LVDS serializer. Add DT binding
which represents this serializer as a bridge.

Signed-off-by: Marek Vasut 
Cc: Laurent Pinchart 
Cc: Lucas Stach 
Cc: Maxime Ripard 
Cc: Peng Fan 
Cc: Rob Herring 
Cc: Robby Cai 
Cc: Robert Foss 
Cc: Sam Ravnborg 
Cc: Thomas Zimmermann 
Cc: devicet...@vger.kernel.org
To: dri-devel@lists.freedesktop.org
---
V2: - Consistently use fsl,imx8mp-ldb as compatible
- Drop items: from compatible:
- Replace minItems with maxItems in clocks:
- Drop quotes from clock-names const: ldb
- Rename syscon to fsl,syscon
- Use generic name of ldb-lvds in example
---
 .../bindings/display/bridge/nxp,ldb.yaml  | 96 +++
 1 file changed, 96 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/nxp,ldb.yaml

diff --git a/Documentation/devicetree/bindings/display/bridge/nxp,ldb.yaml 
b/Documentation/devicetree/bindings/display/bridge/nxp,ldb.yaml
new file mode 100644
index 0..f3182566eb316
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/nxp,ldb.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/nxp,ldb.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8M DPI to LVDS bridge chip
+
+maintainers:
+  - Marek Vasut 
+
+description: |
+  The i.MX8MP contains two syscon registers which are responsible
+  for configuring the on-SoC DPI-to-LVDS serializer. This describes
+  those registers as bridge within the DT.
+
+properties:
+  compatible:
+const: fsl,imx8mp-ldb
+
+  clocks:
+maxItems: 1
+
+  clock-names:
+const: ldb
+
+  fsl,syscon:
+$ref: /schemas/types.yaml#/definitions/phandle
+description: A phandle to media block controller.
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Video port for DPI input.
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Video port for LVDS Channel-A output (panel or bridge).
+
+  port@2:
+$ref: /schemas/graph.yaml#/properties/port
+description: Video port for LVDS Channel-B output (panel or bridge).
+
+required:
+  - port@0
+  - port@1
+
+required:
+  - compatible
+  - clocks
+  - fsl,syscon
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+
+bridge {
+compatible = "fsl,imx8mp-ldb";
+clocks = < IMX8MP_CLK_MEDIA_LDB>;
+clock-names = "ldb";
+fsl,syscon = <_blk_ctrl>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+
+ldb_from_lcdif2: endpoint {
+remote-endpoint = <_to_ldb>;
+};
+};
+
+port@1 {
+reg = <1>;
+
+ldb_lvds_ch0: endpoint {
+remote-endpoint = <_to_lvdsx4panel>;
+};
+};
+
+port@2 {
+reg = <2>;
+
+ldb_lvds_ch1: endpoint {
+};
+};
+};
+};
-- 
2.35.1



[PATCH] drm/nouveau: change base917c_format from global to static

2022-04-18 Thread Tom Rix
Smatch reports this issue
base917c.c:26:1: warning: symbol 'base917c_format'
  was not declared. Should it be static?

base917c_format is only used in base917.c.  Single
file variables should not be global so change
base917c_format's storage-class specifier to static.

Signed-off-by: Tom Rix 
---
 drivers/gpu/drm/nouveau/dispnv50/base917c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/base917c.c 
b/drivers/gpu/drm/nouveau/dispnv50/base917c.c
index a1baed4fe0e9..ca260509a4f1 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/base917c.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/base917c.c
@@ -22,7 +22,7 @@
 #include "base.h"
 #include "atom.h"
 
-const u32
+static const u32
 base917c_format[] = {
DRM_FORMAT_C8,
DRM_FORMAT_XRGB,
-- 
2.27.0



[PATCH 4.9 133/218] video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow

2022-04-18 Thread Greg Kroah-Hartman
From: Tim Gardner 

[ Upstream commit 37a1a2e6eeeb101285cd34e12e48a881524701aa ]

Coverity complains of a possible buffer overflow. However,
given the 'static' scope of nvidia_setup_i2c_bus() it looks
like that can't happen after examiniing the call sites.

CID 19036 (#1 of 1): Copy into fixed size buffer (STRING_OVERFLOW)
1. fixed_size_dest: You might overrun the 48-character fixed-size string
  chan->adapter.name by copying name without checking the length.
2. parameter_as_source: Note: This defect has an elevated risk because the
  source argument is a parameter of the current function.
 89strcpy(chan->adapter.name, name);

Fix this warning by using strscpy() which will silence the warning and
prevent any future buffer overflows should the names used to identify the
channel become much longer.

Cc: Antonino Daplas 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Tim Gardner 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/nvidia/nv_i2c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/nvidia/nv_i2c.c 
b/drivers/video/fbdev/nvidia/nv_i2c.c
index d7994a173245..0b48965a6420 100644
--- a/drivers/video/fbdev/nvidia/nv_i2c.c
+++ b/drivers/video/fbdev/nvidia/nv_i2c.c
@@ -86,7 +86,7 @@ static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, 
const char *name,
 {
int rc;
 
-   strcpy(chan->adapter.name, name);
+   strscpy(chan->adapter.name, name, sizeof(chan->adapter.name));
chan->adapter.owner = THIS_MODULE;
chan->adapter.class = i2c_class;
chan->adapter.algo_data = >algo;
-- 
2.34.1





[PATCH 4.14 165/284] video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow

2022-04-18 Thread Greg Kroah-Hartman
From: Tim Gardner 

[ Upstream commit 37a1a2e6eeeb101285cd34e12e48a881524701aa ]

Coverity complains of a possible buffer overflow. However,
given the 'static' scope of nvidia_setup_i2c_bus() it looks
like that can't happen after examiniing the call sites.

CID 19036 (#1 of 1): Copy into fixed size buffer (STRING_OVERFLOW)
1. fixed_size_dest: You might overrun the 48-character fixed-size string
  chan->adapter.name by copying name without checking the length.
2. parameter_as_source: Note: This defect has an elevated risk because the
  source argument is a parameter of the current function.
 89strcpy(chan->adapter.name, name);

Fix this warning by using strscpy() which will silence the warning and
prevent any future buffer overflows should the names used to identify the
channel become much longer.

Cc: Antonino Daplas 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Tim Gardner 
Signed-off-by: Helge Deller 
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/nvidia/nv_i2c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/nvidia/nv_i2c.c 
b/drivers/video/fbdev/nvidia/nv_i2c.c
index d7994a173245..0b48965a6420 100644
--- a/drivers/video/fbdev/nvidia/nv_i2c.c
+++ b/drivers/video/fbdev/nvidia/nv_i2c.c
@@ -86,7 +86,7 @@ static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, 
const char *name,
 {
int rc;
 
-   strcpy(chan->adapter.name, name);
+   strscpy(chan->adapter.name, name, sizeof(chan->adapter.name));
chan->adapter.owner = THIS_MODULE;
chan->adapter.class = i2c_class;
chan->adapter.algo_data = >algo;
-- 
2.34.1





Re: [PATCH] drm/panel: newvision-nv3052c: Fix build

2022-04-18 Thread Dave Airlie
On Mon, 18 Apr 2022 at 17:07, Sam Ravnborg  wrote:
>
> On Sat, Apr 09, 2022 at 11:00:16AM +0100, Paul Cercueil wrote:
> > The driver was compile-tested then rebased on drm-misc-next, and not
> > compile-tested after the rebase; unfortunately the driver didn't compile
> > anymore when it hit drm-misc-next.
> >
> > Fixes: 49956b505c53 ("drm/panel: Add panel driver for NewVision NV3052C 
> > based LCDs")
> > Cc: Christophe Branchereau 
> > Cc: kbuild-all 
> > Cc: Stephen Rothwell 
> > Reported-by: kernel test robot 
> > Signed-off-by: Paul Cercueil 
> Acked-by: Sam Ravnborg 
> > ---

Backmerge drm-next. I fixed this up when I merged this driver in the
merge commit.

Dave.


[Bug 212499] nouveau locking issue - WARNING: possible circular locking dependency detected

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

Erhard F. (erhar...@mailbox.org) changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |OBSOLETE

--- Comment #2 from Erhard F. (erhar...@mailbox.org) ---
Sold the hardware, no longer able to test.

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

You are receiving this mail because:
You are on the CC list for the bug.
You are watching the assignee of the bug.

[Bug 212635] nouveau 0000:04:00.0: fifo: fault 00 [READ] at 0000000000380000 engine 00 [GR] client 14 [HUB/SCC] reason 02 [PTE] on channel 5 [007fabf000 X[570]]

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

Erhard F. (erhar...@mailbox.org) changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |OBSOLETE

--- Comment #2 from Erhard F. (erhar...@mailbox.org) ---
Sold the hardware, no longer able to test.

-- 
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: [PATCH] drm/panel: newvision-nv3052c: Fix build

2022-04-18 Thread Sam Ravnborg
On Sat, Apr 09, 2022 at 11:00:16AM +0100, Paul Cercueil wrote:
> The driver was compile-tested then rebased on drm-misc-next, and not
> compile-tested after the rebase; unfortunately the driver didn't compile
> anymore when it hit drm-misc-next.
> 
> Fixes: 49956b505c53 ("drm/panel: Add panel driver for NewVision NV3052C based 
> LCDs")
> Cc: Christophe Branchereau 
> Cc: kbuild-all 
> Cc: Stephen Rothwell 
> Reported-by: kernel test robot 
> Signed-off-by: Paul Cercueil 
Acked-by: Sam Ravnborg 
> ---
>  drivers/gpu/drm/panel/panel-newvision-nv3052c.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c 
> b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c
> index 127bcfdb59df..cf078f0d3cd3 100644
> --- a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c
> +++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c
> @@ -416,15 +416,13 @@ static int nv3052c_probe(struct spi_device *spi)
>   return 0;
>  }
>  
> -static int nv3052c_remove(struct spi_device *spi)
> +static void nv3052c_remove(struct spi_device *spi)
>  {
>   struct nv3052c *priv = spi_get_drvdata(spi);
>  
>   drm_panel_remove(>panel);
>   drm_panel_disable(>panel);
>   drm_panel_unprepare(>panel);
> -
> - return 0;
>  }
>  
>  static const struct drm_display_mode ltk035c5444t_modes[] = {
> -- 
> 2.35.1


Re: [PATCH 3/4] dt-bindings: drm/bridge: anx7625: Change bus-type to 7 (DPI)

2022-04-18 Thread Chen-Yu Tsai
Hi,

On Thu, Apr 14, 2022 at 10:27 AM Xin Ji  wrote:
>
> On Wed, Apr 13, 2022 at 04:28:51PM +0200, Robert Foss wrote:
> > On Sat, 9 Apr 2022 at 06:47, Xin Ji  wrote:
> > >
> > > On Mon, Apr 04, 2022 at 12:52:14PM -0500, Rob Herring wrote:
> > > > On Mon, Mar 28, 2022 at 08:09:54PM +0800, Xin Ji wrote:
> > > > > Change bus-type define for DPI.
> > > > >
> > > > > Fixes: a43661e7e819 ("dt-bindings:drm/bridge:anx7625:add vendor 
> > > > > define")
> > > > >
> > > > > Signed-off-by: Xin Ji 
> > > > > ---
> > > > >  .../devicetree/bindings/display/bridge/analogix,anx7625.yaml  | 4 
> > > > > ++--
> > > > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git 
> > > > > a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> > > > >  
> > > > > b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> > > > > index 0d38d6fe3983..4590186c4a0b 100644
> > > > > --- 
> > > > > a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> > > > > +++ 
> > > > > b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> > > > > @@ -106,7 +106,7 @@ properties:
> > > > >remote-endpoint: true
> > > > >
> > > > >bus-type:
> > > > > -enum: [1, 5]
> > > > > +enum: [7]
> > > >
> > > > Changing is an ABI break, but didn't we revert adding this?
> > > Hi Rob, sorry, what do you mean about ABI break? Do I need remove this
> > > patch in this serial? Or do I need revert patch
> > > https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatchwork.freedesktop.org%2Fpatch%2F462331%2Fdata=04%7C01%7Cxji%40analogixsemi.com%7C10f5b0213f434592936008da1d59f566%7Cb099b0b4f26c4cf59a0fd5be9acab205%7C0%7C0%7C637854569490105386%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000sdata=vK0Vmb9S425kHZc1WurfnNhnoXDMbUGkkdY1PVnfS9g%3Dreserved=0,
> > >  I don't know how to do
> > > it.
> > >
> >
> > I contributed to the confusion about this, let's see if we can clear it up.
> >
> > An issue was found related to which enum values were used to represent
> > what late in the last release cycle. As a result a revert[1] patch for
> > everything touching bus-type in anx7625 was merged.
> >
> > This patch, does not apply to drm-misc-next due to the revert, and if
> > Xin Ji rebases his work on the drm-misc-next there should be no
> > ABI-change as this patch when fixed up will introduce bus-type to the
> > nax7625 ABI.
> >
> > Xin: Does this make sense to you?
> Hi Robert Foss, yes, my work is based on drm-misc-next, all I can do,
> just make a fix up patch(this patch) to change the bus-type define.

The revert was applied to the soc tree and merged into Linus's tree
in v5.17-rc8. It was not present in drm-misc-next until April 5 with
commit 9cbbd694a58b ("Merge drm/drm-next into drm-misc-next").

So please fetch the latest drm-misc-next, rebase your patches on top, and
resend.


Thanks
ChenYu


Re: [PATCH v6 2/2] arm64: dts: mt8192: Add node for the Mali GPU

2022-04-18 Thread Fei Shao
On Thu, Apr 14, 2022 at 10:53 AM Nick Fan  wrote:
>
> Add a basic GPU node for mt8192.
>
> Signed-off-by: Nick Fan 

Reviewed-by: Fei Shao