[PATCH v7 21/24] drm/rockchip: Make VOP driver optional

2022-02-24 Thread Sascha Hauer
With upcoming VOP2 support VOP won't be the only choice anymore, so make
the VOP driver optional.

Signed-off-by: Sascha Hauer 
---
 drivers/gpu/drm/rockchip/Kconfig| 8 
 drivers/gpu/drm/rockchip/Makefile   | 3 ++-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 +-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 9f1ecefc39332..b9b156308460a 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -21,8 +21,16 @@ config DRM_ROCKCHIP
 
 if DRM_ROCKCHIP
 
+config ROCKCHIP_VOP
+   bool "Rockchip VOP driver"
+   default y
+   help
+ This selects support for the VOP driver. You should enable it
+ on all older SoCs up to RK3399.
+
 config ROCKCHIP_ANALOGIX_DP
bool "Rockchip specific extensions for Analogix DP driver"
+   depends on ROCKCHIP_VOP
help
  This selects support for Rockchip SoC specific extensions
  for the Analogix Core DP driver. If you want to enable DP
diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index 1a56f696558ca..dfc5512fdb9f1 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -4,8 +4,9 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
-   rockchip_drm_gem.o rockchip_drm_vop.o rockchip_vop_reg.o
+   rockchip_drm_gem.o
 
+rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o
 rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 7920a4f44f693..cf8dba96a7dee 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -491,7 +491,7 @@ static int __init rockchip_drm_init(void)
int ret;
 
num_rockchip_sub_drivers = 0;
-   ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_DRM_ROCKCHIP);
+   ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_ROCKCHIP_VOP);
ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver,
CONFIG_ROCKCHIP_LVDS);
ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver,
-- 
2.30.2



[PATCH v7 09/24] dt-bindings: display: rockchip: dw-hdmi: Add regulator support

2022-02-24 Thread Sascha Hauer
The RK3568 has HDMI_TX_AVDD0V9 and HDMI_TX_AVDD_1V8 supply inputs
needed for the HDMI port. Add the binding for these supplies.

Signed-off-by: Sascha Hauer 
Acked-by: Rob Herring 
---

Notes:
Changes since v4:
- Add Robs Ack

 .../bindings/display/rockchip/rockchip,dw-hdmi.yaml   | 11 +++
 1 file changed, 11 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index e6b8437a1e2d1..38ebb69830287 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -28,6 +28,17 @@ properties:
   reg-io-width:
 const: 4
 
+  avdd-0v9-supply:
+description:
+  A 0.9V supply that powers up the SoC internal circuitry. The actual pin 
name
+  varies between the different SoCs and is usually HDMI_TX_AVDD_0V9 or 
sometimes
+  HDMI_AVDD_1V0.
+
+  avdd-1v8-supply:
+description:
+  A 1.8V supply that powers up the SoC internal circuitry. The pin name on 
the
+  SoC usually is HDMI_TX_AVDD_1V8.
+
   clocks:
 minItems: 2
 items:
-- 
2.30.2



[PATCH v7 04/24] dt-bindings: display: rockchip: dw-hdmi: use "ref" as clock name

2022-02-24 Thread Sascha Hauer
"vpll" is a misnomer. A clock input to a device should be named after
the usage in the device, not after the clock that drives it. On the
rk3568 the same clock is driven by the HPLL.
This patch adds "ref" as a new alternative clock name for "vpll"

Signed-off-by: Sascha Hauer 
Acked-by: Rob Herring 
---

Notes:
Changes since v4:
- Add Robs Ack

Changes since v3:
- Keep old clock name for compatibility reasons

 .../bindings/display/rockchip/rockchip,dw-hdmi.yaml  | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index da3b889ad8fcd..0400f67e5f2c9 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -36,7 +36,8 @@ properties:
   # order when present.
   - description: The HDMI CEC controller main clock
   - description: Power for GRF IO
-  - description: External clock for some HDMI PHY
+  - description: External clock for some HDMI PHY (old clock name, 
deprecated)
+  - description: External clock for some HDMI PHY (new name)
 
   clock-names:
 minItems: 2
@@ -47,10 +48,14 @@ properties:
   - cec
   - grf
   - vpll
+  - ref
   - enum:
   - grf
   - vpll
-  - const: vpll
+  - ref
+  - enum:
+  - vpll
+  - ref
 
   ddc-i2c-bus:
 $ref: /schemas/types.yaml#/definitions/phandle
-- 
2.30.2



[PATCH v7 16/24] dt-bindings: display: rockchip: dw-hdmi: Make unwedge pinctrl optional

2022-02-24 Thread Sascha Hauer
None of the upstream device tree files has a "unwedge" pinctrl
specified. Make it optional.

Signed-off-by: Sascha Hauer 
Acked-by: Rob Herring 
---

Notes:
Changes since v4:
- Add Robs Ack

 .../devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml   | 1 +
 1 file changed, 1 insertion(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index 67a76f51637a7..7dd753630b46a 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -94,6 +94,7 @@ properties:
   The unwedge pinctrl entry shall drive the DDC SDA line low. This is
   intended to work around a hardware errata that can cause the DDC I2C
   bus to be wedged.
+minItems: 1
 items:
   - const: default
   - const: unwedge
-- 
2.30.2



[PATCH v7 17/24] arm64: dts: rockchip: rk356x: Add VOP2 nodes

2022-02-24 Thread Sascha Hauer
The VOP2 is the display output controller on the RK3568. Add the node
for it to the dtsi file along with the required display-subsystem node
and the iommu node.

Signed-off-by: Sascha Hauer 
Acked-by: Rob Herring 
---

Notes:
Changes since v4:
- Add Robs Ack

Changes since v3:
- Bring back gamma_lut regs
- Drop redundant _vop suffix from clock names

 arch/arm64/boot/dts/rockchip/rk3566.dtsi |  4 ++
 arch/arm64/boot/dts/rockchip/rk3568.dtsi |  4 ++
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 51 
 include/dt-bindings/soc/rockchip,vop2.h  | 14 +++
 4 files changed, 73 insertions(+)
 create mode 100644 include/dt-bindings/soc/rockchip,vop2.h

diff --git a/arch/arm64/boot/dts/rockchip/rk3566.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3566.dtsi
index 3839eef5e4f76..595fa2562cb8e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566.dtsi
@@ -18,3 +18,7 @@ power-domain@RK3568_PD_PIPE {
#power-domain-cells = <0>;
};
 };
+
+ {
+   compatible = "rockchip,rk3566-vop";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
index 2fd313a295f8a..1e55efb6fcfde 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -95,3 +95,7 @@ power-domain@RK3568_PD_PIPE {
#power-domain-cells = <0>;
};
 };
+
+ {
+   compatible = "rockchip,rk3568-vop";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi 
b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index a68033a239750..19d8e67c4698b 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -129,6 +129,11 @@ opp-18 {
};
};
 
+   display_subsystem: display-subsystem {
+   compatible = "rockchip,display-subsystem";
+   ports = <_out>;
+   };
+
firmware {
scmi: scmi {
compatible = "arm,scmi-smc";
@@ -451,6 +456,52 @@ gmac1_mtl_tx_setup: tx-queues-config {
};
};
 
+   vop: vop@fe04 {
+   reg = <0x0 0xfe04 0x0 0x3000>, <0x0 0xfe044000 0x0 0x1000>;
+   reg-names = "regs", "gamma_lut";
+   interrupts = ;
+   clocks = < ACLK_VOP>, < HCLK_VOP>, < DCLK_VOP0>,
+< DCLK_VOP1>, < DCLK_VOP2>;
+   clock-names = "aclk", "hclk", "dclk_vp0", "dclk_vp1", 
"dclk_vp2";
+   iommus = <_mmu>;
+   power-domains = < RK3568_PD_VO>;
+   rockchip,grf = <>;
+   status = "disabled";
+
+   vop_out: ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   vp0: port@0 {
+   reg = <0>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+
+   vp1: port@1 {
+   reg = <1>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+
+   vp2: port@2 {
+   reg = <2>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
+   };
+   };
+
+   vop_mmu: iommu@fe043e00 {
+   compatible = "rockchip,rk3568-iommu";
+   reg = <0x0 0xfe043e00 0x0 0x100>, <0x0 0xfe043f00 0x0 0x100>;
+   interrupts = ;
+   clocks = < ACLK_VOP>, < HCLK_VOP>;
+   clock-names = "aclk", "iface";
+   #iommu-cells = <0>;
+   status = "disabled";
+   };
+
qos_gpu: qos@fe128000 {
compatible = "rockchip,rk3568-qos", "syscon";
reg = <0x0 0xfe128000 0x0 0x20>;
diff --git a/include/dt-bindings/soc/rockchip,vop2.h 
b/include/dt-bindings/soc/rockchip,vop2.h
new file mode 100644
index 0..6e66a802b96a5
--- /dev/null
+++ b/include/dt-bindings/soc/rockchip,vop2.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+
+#ifndef __DT_BINDINGS_ROCKCHIP_VOP2_H
+#define __DT_BINDINGS_ROCKCHIP_VOP2_H
+
+#define ROCKCHIP_VOP2_EP_RGB0  1
+#define ROCKCHIP_VOP2_EP_HDMI0 2
+#define ROCKCHIP_VOP2_EP_EDP0  3
+#define ROCKCHIP_VOP2_EP_MIPI0 4
+#define ROCKCHIP_VOP2_EP_LVDS0 5
+#define ROCKCHIP_VOP2_EP_MIPI1 6
+#define ROCKCHIP_VOP2_EP_LVDS1 7
+
+#endif /* __DT_BINDINGS_ROCKCHIP_VOP2_H */
-- 
2.30.2



[PATCH v7 01/24] drm/rockchip: Embed drm_encoder into rockchip_decoder

2022-02-24 Thread Sascha Hauer
The VOP2 driver needs rockchip specific information for a drm_encoder.

This patch creates a struct rockchip_encoder with a struct drm_encoder
embedded in it. This is used throughout the rockchip driver instead of
struct drm_encoder directly.

The information the VOP2 drivers needs is the of_graph endpoint node
of the encoder. To ease bisectability this is added here.

While at it convert the different encoder-to-driverdata macros to
static inline functions in order to gain type safety and readability.

Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v5:
- new patch

 .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 32 +++--
 drivers/gpu/drm/rockchip/cdn-dp-core.c| 18 ++
 drivers/gpu/drm/rockchip/cdn-dp-core.h|  2 +-
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 17 ++
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   | 11 --
 drivers/gpu/drm/rockchip/inno_hdmi.c  | 32 +++--
 drivers/gpu/drm/rockchip/rk3066_hdmi.c| 34 ---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   | 10 ++
 drivers/gpu/drm/rockchip/rockchip_lvds.c  | 26 --
 9 files changed, 122 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 8abb5ac26807e..bb33c6c217f77 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -40,8 +40,6 @@
 
 #define PSR_WAIT_LINE_FLAG_TIMEOUT_MS  100
 
-#define to_dp(nm)  container_of(nm, struct rockchip_dp_device, nm)
-
 /**
  * struct rockchip_dp_chip_data - splite the grf setting of kind of chips
  * @lcdsel_grf_reg: grf register offset of lcdc select
@@ -59,7 +57,7 @@ struct rockchip_dp_chip_data {
 struct rockchip_dp_device {
struct drm_device*drm_dev;
struct device*dev;
-   struct drm_encoder   encoder;
+   struct rockchip_encoder  encoder;
struct drm_display_mode  mode;
 
struct clk   *pclk;
@@ -73,6 +71,18 @@ struct rockchip_dp_device {
struct analogix_dp_plat_data plat_data;
 };
 
+static struct rockchip_dp_device *encoder_to_dp(struct drm_encoder *encoder)
+{
+   struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
+
+   return container_of(rkencoder, struct rockchip_dp_device, encoder);
+}
+
+static struct rockchip_dp_device *pdata_encoder_to_dp(struct 
analogix_dp_plat_data *plat_data)
+{
+   return container_of(plat_data, struct rockchip_dp_device, plat_data);
+}
+
 static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
 {
reset_control_assert(dp->rst);
@@ -84,7 +94,7 @@ static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
 
 static int rockchip_dp_poweron_start(struct analogix_dp_plat_data *plat_data)
 {
-   struct rockchip_dp_device *dp = to_dp(plat_data);
+   struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data);
int ret;
 
ret = clk_prepare_enable(dp->pclk);
@@ -105,7 +115,7 @@ static int rockchip_dp_poweron_start(struct 
analogix_dp_plat_data *plat_data)
 
 static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
 {
-   struct rockchip_dp_device *dp = to_dp(plat_data);
+   struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data);
 
clk_disable_unprepare(dp->pclk);
 
@@ -166,7 +176,7 @@ struct drm_crtc *rockchip_dp_drm_get_new_crtc(struct 
drm_encoder *encoder,
 static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
   struct drm_atomic_state *state)
 {
-   struct rockchip_dp_device *dp = to_dp(encoder);
+   struct rockchip_dp_device *dp = encoder_to_dp(encoder);
struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state;
int ret;
@@ -208,7 +218,7 @@ static void rockchip_dp_drm_encoder_enable(struct 
drm_encoder *encoder,
 static void rockchip_dp_drm_encoder_disable(struct drm_encoder *encoder,
struct drm_atomic_state *state)
 {
-   struct rockchip_dp_device *dp = to_dp(encoder);
+   struct rockchip_dp_device *dp = encoder_to_dp(encoder);
struct drm_crtc *crtc;
struct drm_crtc_state *new_crtc_state = NULL;
int ret;
@@ -297,7 +307,7 @@ static int rockchip_dp_of_probe(struct rockchip_dp_device 
*dp)
 
 static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
 {
-   struct drm_encoder *encoder = >encoder;
+   struct drm_encoder *encoder = >encoder.encoder;
struct drm_device *drm_dev = dp->drm_dev;
struct device *dev = dp->dev;
int ret;
@@ -333,7 +343,7 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
return ret;
}
 
-   dp->plat_data.encoder = >encoder;
+   dp->plat_data.encoder = >encoder.encoder;
 
ret = analogix_dp_bind(dp->adp, 

[PATCH v7 20/24] arm64: dts: rockchip: enable vop2 and hdmi tx on quartz64a

2022-02-24 Thread Sascha Hauer
From: Michael Riesch 

Enable the RK356x Video Output Processor (VOP) 2 on the Pine64
Quartz64 Model A.

Signed-off-by: Michael Riesch 
Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v5:
- Drop reg property from single endpoint node

Changes since v4:
- Sort nodes alphabetically

Changes since v3:
- Fix HDMI connector type

 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts 
b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index 166399b7f13f0..ddb7857bef099 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -4,6 +4,7 @@
 
 #include 
 #include 
+#include 
 #include "rk3566.dtsi"
 
 / {
@@ -35,6 +36,17 @@ fan: gpio_fan {
#cooling-cells = <2>;
};
 
+   hdmi-con {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
leds {
compatible = "gpio-leds";
 
@@ -205,6 +217,24 @@ _clkinout
status = "okay";
 };
 
+ {
+   avdd-0v9-supply = <_0v9>;
+   avdd-1v8-supply = <_1v8>;
+   status = "okay";
+};
+
+_in {
+   hdmi_in_vp0: endpoint {
+   remote-endpoint = <_out_hdmi>;
+   };
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
status = "okay";
 
@@ -551,3 +581,20 @@ bluetooth {
  {
status = "okay";
 };
+
+ {
+   assigned-clocks = < DCLK_VOP0>, < DCLK_VOP1>;
+   assigned-clock-parents = < PLL_HPLL>, < PLL_VPLL>;
+   status = "okay";
+};
+
+_mmu {
+   status = "okay";
+};
+
+ {
+   vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+   reg = ;
+   remote-endpoint = <_in_vp0>;
+   };
+};
-- 
2.30.2



[PATCH v7 11/24] dt-bindings: display: rockchip: dw-hdmi: Add additional clock

2022-02-24 Thread Sascha Hauer
The rk3568 HDMI has an additional clock that needs to be enabled for the
HDMI controller to work. The purpose of that clock is not clear. It is
named "hclk" in the downstream driver, so use the same name.

Signed-off-by: Sascha Hauer 
Acked-by: Rob Herring 
---

Notes:
Changes since v4:
- Add Robs Ack

 .../bindings/display/rockchip/rockchip,dw-hdmi.yaml| 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index 38ebb69830287..67a76f51637a7 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -44,12 +44,13 @@ properties:
 items:
   - {}
   - {}
-  # The next three clocks are all optional, but shall be specified in this
+  # The next four clocks are all optional, but shall be specified in this
   # order when present.
   - description: The HDMI CEC controller main clock
   - description: Power for GRF IO
   - description: External clock for some HDMI PHY (old clock name, 
deprecated)
   - description: External clock for some HDMI PHY (new name)
+  - description: hclk
 
   clock-names:
 minItems: 2
@@ -61,13 +62,17 @@ properties:
   - grf
   - vpll
   - ref
+  - hclk
   - enum:
   - grf
   - vpll
   - ref
+  - hclk
   - enum:
   - vpll
   - ref
+  - hclk
+  - const: hclk
 
   ddc-i2c-bus:
 $ref: /schemas/types.yaml#/definitions/phandle
-- 
2.30.2



[PATCH v7 23/24] dt-bindings: display: rockchip: Add binding for VOP2

2022-02-24 Thread Sascha Hauer
The VOP2 is found on newer Rockchip SoCs like the rk3568 or the rk3566.
The binding differs slightly from the existing VOP binding, so add a new
binding file for it.

Signed-off-by: Sascha Hauer 
Reviewed-by: Rob Herring 
---

Notes:
Changes since v5:
- Add Robs Reviewed-by:

Changes since v4:
- Fix clk names in example
- Drop unnecessary assigned-clocks, assigned-clock-rates and 
assigned-clock-parents

Changes since v3:
- drop redundant _vop suffix from clock names

Changes since v3:
- new patch

 .../display/rockchip/rockchip-vop2.yaml   | 140 ++
 1 file changed, 140 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
new file mode 100644
index 0..655d9b327f7d3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
@@ -0,0 +1,140 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/rockchip/rockchip-vop2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC display controller (VOP2)
+
+description:
+  VOP2 (Video Output Processor v2) is the display controller for the Rockchip
+  series of SoCs which transfers the image data from a video memory
+  buffer to an external LCD interface.
+
+maintainers:
+  - Sandy Huang 
+  - Heiko Stuebner 
+
+properties:
+  compatible:
+enum:
+  - rockchip,rk3566-vop
+  - rockchip,rk3568-vop
+
+  reg:
+minItems: 1
+items:
+  - description:
+  Must contain one entry corresponding to the base address and length
+  of the register space.
+  - description:
+  Can optionally contain a second entry corresponding to
+  the CRTC gamma LUT address.
+
+  interrupts:
+maxItems: 1
+description:
+  The VOP interrupt is shared by several interrupt sources, such as
+  frame start (VSYNC), line flag and other status interrupts.
+
+  clocks:
+items:
+  - description: Clock for ddr buffer transfer.
+  - description: Clock for the ahb bus to R/W the phy regs.
+  - description: Pixel clock for video port 0.
+  - description: Pixel clock for video port 1.
+  - description: Pixel clock for video port 2.
+
+  clock-names:
+items:
+  - const: aclk
+  - const: hclk
+  - const: dclk_vp0
+  - const: dclk_vp1
+  - const: dclk_vp2
+
+  rockchip,grf:
+$ref: /schemas/types.yaml#/definitions/phandle
+description:
+  Phandle to GRF regs used for misc control
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Output endpoint of VP0
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Output endpoint of VP1
+
+  port@2:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Output endpoint of VP2
+
+  iommus:
+maxItems: 1
+
+  power-domains:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+bus {
+#address-cells = <2>;
+#size-cells = <2>;
+vop: vop@fe04 {
+compatible = "rockchip,rk3568-vop";
+reg = <0x0 0xfe04 0x0 0x3000>, <0x0 0xfe044000 0x0 0x1000>;
+interrupts = ;
+clocks = < ACLK_VOP>,
+ < HCLK_VOP>,
+ < DCLK_VOP0>,
+ < DCLK_VOP1>,
+ < DCLK_VOP2>;
+clock-names = "aclk",
+  "hclk",
+  "dclk_vp0",
+  "dclk_vp1",
+  "dclk_vp2";
+power-domains = < RK3568_PD_VO>;
+iommus = <_mmu>;
+vop_out: ports {
+#address-cells = <1>;
+#size-cells = <0>;
+vp0: port@0 {
+reg = <0>;
+#address-cells = <1>;
+#size-cells = <0>;
+};
+vp1: port@1 {
+reg = <1>;
+#address-cells = <1>;
+#size-cells = <0>;
+};
+vp2: port@2 {
+reg = <2>;
+#address-cells = <1>;
+#size-cells = <0>;
+};
+};
+};
+};
-- 
2.30.2



[PATCH v7 08/24] drm/rockchip: dw_hdmi: add regulator support

2022-02-24 Thread Sascha Hauer
The RK3568 has HDMI_TX_AVDD0V9 and HDMI_TX_AVDD_1V8 supply inputs needed
for the HDMI port. add support for these to the driver for boards which
have them supplied by switchable regulators.

Signed-off-by: Sascha Hauer 
Reviewed-by: Dmitry Osipenko 
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 +++--
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index b64cc62c7b5af..fe4f9556239ac 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -76,6 +77,8 @@ struct rockchip_hdmi {
struct clk *ref_clk;
struct clk *grf_clk;
struct dw_hdmi *hdmi;
+   struct regulator *avdd_0v9;
+   struct regulator *avdd_1v8;
struct phy *phy;
 };
 
@@ -226,6 +229,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
return PTR_ERR(hdmi->grf_clk);
}
 
+   hdmi->avdd_0v9 = devm_regulator_get(hdmi->dev, "avdd-0v9");
+   if (IS_ERR(hdmi->avdd_0v9))
+   return PTR_ERR(hdmi->avdd_0v9);
+
+   hdmi->avdd_1v8 = devm_regulator_get(hdmi->dev, "avdd-1v8");
+   if (IS_ERR(hdmi->avdd_1v8))
+   return PTR_ERR(hdmi->avdd_1v8);
+
return 0;
 }
 
@@ -566,11 +577,23 @@ static int dw_hdmi_rockchip_bind(struct device *dev, 
struct device *master,
return ret;
}
 
+   ret = regulator_enable(hdmi->avdd_0v9);
+   if (ret) {
+   DRM_DEV_ERROR(hdmi->dev, "failed to enable avdd0v9: %d\n", ret);
+   goto err_avdd_0v9;
+   }
+
+   ret = regulator_enable(hdmi->avdd_1v8);
+   if (ret) {
+   DRM_DEV_ERROR(hdmi->dev, "failed to enable avdd1v8: %d\n", ret);
+   goto err_avdd_1v8;
+   }
+
ret = clk_prepare_enable(hdmi->ref_clk);
if (ret) {
DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI reference 
clock: %d\n",
  ret);
-   return ret;
+   goto err_clk;
}
 
if (hdmi->chip_data == _chip_data) {
@@ -594,10 +617,19 @@ static int dw_hdmi_rockchip_bind(struct device *dev, 
struct device *master,
 */
if (IS_ERR(hdmi->hdmi)) {
ret = PTR_ERR(hdmi->hdmi);
-   drm_encoder_cleanup(encoder);
-   clk_disable_unprepare(hdmi->ref_clk);
+   goto err_bind;
}
 
+   return 0;
+
+err_bind:
+   clk_disable_unprepare(hdmi->ref_clk);
+   drm_encoder_cleanup(encoder);
+err_clk:
+   regulator_disable(hdmi->avdd_1v8);
+err_avdd_1v8:
+   regulator_disable(hdmi->avdd_0v9);
+err_avdd_0v9:
return ret;
 }
 
@@ -608,6 +640,9 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, 
struct device *master,
 
dw_hdmi_unbind(hdmi->hdmi);
clk_disable_unprepare(hdmi->ref_clk);
+
+   regulator_disable(hdmi->avdd_1v8);
+   regulator_disable(hdmi->avdd_0v9);
 }
 
 static const struct component_ops dw_hdmi_rockchip_ops = {
-- 
2.30.2



[PATCH v7 24/24] dt-bindings: display: rockchip: dw-hdmi: fix ports description

2022-02-24 Thread Sascha Hauer
Current port description doesn't cover all possible cases. It currently
expects one single port with two endpoints.

When the HDMI connector is described in the device tree there can be two
ports, first one going to the VOP and the second one going to the connector.

Also on SoCs which only have a single VOP there will be only one
endpoint instead of two.

This patch addresses both issues. With this there can either be a single
port ("port") , or two of them ("port@0", "port@1") when the connector
is also in the device tree. Also the first or only port can either have
one endpoint ("endpoint") for single VOP SoCs or two ("endpoint@0",
"endpoint@1") for dual VOP SoCs.

Signed-off-by: Sascha Hauer 
Reviewed-by: Rob Herring 
---

Notes:
Changes since v6:
- Add Reviewed-by: Rob Herring 
Changes since v5:
- new patch

 .../display/rockchip/rockchip,dw-hdmi.yaml| 24 +++
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index 7dd753630b46a..fc26f1d4d001c 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -102,27 +102,21 @@ properties:
   ports:
 $ref: /schemas/graph.yaml#/properties/ports
 
-properties:
-  port:
-$ref: /schemas/graph.yaml#/$defs/port-base
-unevaluatedProperties: false
+patternProperties:
+  "^port(@0)?$":
+$ref: /schemas/graph.yaml#/properties/port
 description: Input of the DWC HDMI TX
-
 properties:
+  endpoint:
+description: Connection to the VOP
   endpoint@0:
-$ref: /schemas/graph.yaml#/properties/endpoint
 description: Connection to the VOPB
-
   endpoint@1:
-$ref: /schemas/graph.yaml#/properties/endpoint
 description: Connection to the VOPL
-
-required:
-  - endpoint@0
-  - endpoint@1
-
-required:
-  - port
+properties:
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Output of the DWC HDMI TX
 
   rockchip,grf:
 $ref: /schemas/types.yaml#/definitions/phandle
-- 
2.30.2



[PATCH v7 22/24] drm: rockchip: Add VOP2 driver

2022-02-24 Thread Sascha Hauer
From: Andy Yan 

The VOP2 unit is found on Rockchip SoCs beginning with rk3566/rk3568.
It replaces the VOP unit found in the older Rockchip SoCs.

This driver has been derived from the downstream Rockchip Kernel and
heavily modified:

- All nonstandard DRM properties have been removed
- dropped struct vop2_plane_state and pass around less data between
  functions
- Dropped all DRM_FORMAT_* not known on upstream
- rework register access to get rid of excessively used macros
- Drop all waiting for framesyncs

The driver is tested with HDMI and MIPI-DSI display on a RK3568-EVB
board. Overlay support is tested with the modetest utility. AFBC support
on the cluster windows is tested with weston-simple-dmabuf-egl on
weston using the (yet to be upstreamed) panfrost driver support.

Signed-off-by: Andy Yan 
Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v6:
- Drop device tree parsing during runtime
- Fix typo in Kconfig help text

Changes since v5:
- consistently use u8/u16/u32 rather than uint8_t/uint16_t/uint32_t
- Use spin_lock rather than spin_lock_irqsave
- replace printk with drm_dbg
- break some overlong lines

Changes since v4:
- Avoid stack frame overflow by not allocating big array on the stack

Changes since v3:
- Sort includes
- fix typos
- Drop spinlock
- Use regmap_set_bits()/regmap_clear_bits()
- simplify vop2_scale_factor()
- simplify vop2_afbc_transform_offset()

Changes since v4:
- Sort nodes alphabetically

Changes since v3:
- Fix HDMI connector type

Changes since v4:
- Add Robs Ack

Changes since v3:
- Bring back gamma_lut regs
- Drop redundant _vop suffix from clock names

Changes since v5:
- Drop unnecessary #size-cells/#address-cells from nodes with only single 
endpoint

Changes since v5:
- consistently use u8/u16/u32 rather than uint8_t/uint16_t/uint32_t
- Use spin_lock rather than spin_lock_irqsave
- replace printk with drm_dbg
- break some overlong lines

Changes since v4:
- Avoid stack frame overflow by not allocating big array on the stack

Changes since v3:
- Sort includes
- fix typos
- Drop spinlock
- Use regmap_set_bits()/regmap_clear_bits()
- simplify vop2_scale_factor()
- simplify vop2_afbc_transform_offset()

Changes since v4:
- Sort nodes alphabetically

Changes since v3:
- Fix HDMI connector type

 drivers/gpu/drm/rockchip/Kconfig |6 +
 drivers/gpu/drm/rockchip/Makefile|1 +
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c  |1 +
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h  |6 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c   |2 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h  |   15 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2686 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  477 
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c |  281 ++
 9 files changed, 3474 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index b9b156308460a..f033971103610 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -28,6 +28,12 @@ config ROCKCHIP_VOP
  This selects support for the VOP driver. You should enable it
  on all older SoCs up to RK3399.
 
+config ROCKCHIP_VOP2
+   bool "Rockchip VOP2 driver"
+   help
+ This selects support for the VOP2 driver. You should enable it
+ on all newer SoCs beginning from RK3568.
+
 config ROCKCHIP_ANALOGIX_DP
bool "Rockchip specific extensions for Analogix DP driver"
depends on ROCKCHIP_VOP
diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index dfc5512fdb9f1..3ff7b21c04149 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -6,6 +6,7 @@
 rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
rockchip_drm_gem.o
 
+rockchipdrm-$(CONFIG_ROCKCHIP_VOP2) += rockchip_drm_vop2.o rockchip_vop2_reg.o
 rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o
 rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index cf8dba96a7dee..7bebb293eb555 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -492,6 +492,7 @@ static int __init rockchip_drm_init(void)
 
num_rockchip_sub_drivers = 0;
ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_ROCKCHIP_VOP);
+  

[PATCH v7 07/24] dt-bindings: display: rockchip: dw-hdmi: Add compatible for rk3568 HDMI

2022-02-24 Thread Sascha Hauer
From: Benjamin Gaignard 

Define a new compatible for rk3568 HDMI.
This version of HDMI hardware block needs two new clocks hclk_vio and hclk
to provide phy reference clocks.

Signed-off-by: Benjamin Gaignard 
Reviewed-by: Rob Herring 
Signed-off-by: Sascha Hauer 
---
 .../devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml   | 1 +
 1 file changed, 1 insertion(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index 0400f67e5f2c9..e6b8437a1e2d1 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -23,6 +23,7 @@ properties:
   - rockchip,rk3288-dw-hdmi
   - rockchip,rk3328-dw-hdmi
   - rockchip,rk3399-dw-hdmi
+  - rockchip,rk3568-dw-hdmi
 
   reg-io-width:
 const: 4
-- 
2.30.2



[PATCH v7 06/24] drm/rockchip: dw_hdmi: add rk3568 support

2022-02-24 Thread Sascha Hauer
Add a new dw_hdmi_plat_data struct and new compatible for rk3568.

Signed-off-by: Benjamin Gaignard 
Signed-off-by: Sascha Hauer 
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 31 +
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 912181429880a..b64cc62c7b5af 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -50,6 +50,10 @@
 #define RK3399_GRF_SOC_CON20   0x6250
 #define RK3399_HDMI_LCDC_SEL   BIT(6)
 
+#define RK3568_GRF_VO_CON1 0x0364
+#define RK3568_HDMI_SDAIN_MSK  BIT(15)
+#define RK3568_HDMI_SCLIN_MSK  BIT(14)
+
 #define HIWORD_UPDATE(val, mask)   (val | (mask) << 16)
 
 /**
@@ -473,6 +477,19 @@ static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data 
= {
.use_drm_infoframe = true,
 };
 
+static struct rockchip_hdmi_chip_data rk3568_chip_data = {
+   .lcdsel_grf_reg = -1,
+};
+
+static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
+   .mode_valid = dw_hdmi_rockchip_mode_valid,
+   .mpll_cfg   = rockchip_mpll_cfg,
+   .cur_ctr= rockchip_cur_ctr,
+   .phy_config = rockchip_phy_config,
+   .phy_data = _chip_data,
+   .use_drm_infoframe = true,
+};
+
 static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
{ .compatible = "rockchip,rk3228-dw-hdmi",
  .data = _hdmi_drv_data
@@ -486,6 +503,9 @@ static const struct of_device_id dw_hdmi_rockchip_dt_ids[] 
= {
{ .compatible = "rockchip,rk3399-dw-hdmi",
  .data = _hdmi_drv_data
},
+   { .compatible = "rockchip,rk3568-dw-hdmi",
+ .data = _hdmi_drv_data
+   },
{},
 };
 MODULE_DEVICE_TABLE(of, dw_hdmi_rockchip_dt_ids);
@@ -520,6 +540,9 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct 
device *master,
encoder = >encoder.encoder;
 
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
+   rockchip_drm_encoder_set_crtc_endpoint_id(>encoder,
+ dev->of_node, 0, 0);
+
/*
 * If we failed to find the CRTC(s) which this encoder is
 * supposed to be connected to, it's because the CRTC has
@@ -550,6 +573,14 @@ static int dw_hdmi_rockchip_bind(struct device *dev, 
struct device *master,
return ret;
}
 
+   if (hdmi->chip_data == _chip_data) {
+   regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1,
+HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK |
+  RK3568_HDMI_SCLIN_MSK,
+  RK3568_HDMI_SDAIN_MSK |
+  RK3568_HDMI_SCLIN_MSK));
+   }
+
drm_encoder_helper_add(encoder, _hdmi_rockchip_encoder_helper_funcs);
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
-- 
2.30.2



[PATCH v7 10/24] drm/rockchip: dw_hdmi: Add support for hclk

2022-02-24 Thread Sascha Hauer
The rk3568 HDMI has an additional clock that needs to be enabled for the
HDMI controller to work. The purpose of that clock is not clear. It is
named "hclk" in the downstream driver, so use the same name.

Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v5:
- Use devm_clk_get_optional rather than devm_clk_get

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index fe4f9556239ac..c6c00e8779ab5 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -76,6 +76,7 @@ struct rockchip_hdmi {
const struct rockchip_hdmi_chip_data *chip_data;
struct clk *ref_clk;
struct clk *grf_clk;
+   struct clk *hclk_clk;
struct dw_hdmi *hdmi;
struct regulator *avdd_0v9;
struct regulator *avdd_1v8;
@@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
return PTR_ERR(hdmi->grf_clk);
}
 
+   hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
+   if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
+   return -EPROBE_DEFER;
+   } else if (IS_ERR(hdmi->hclk_clk)) {
+   DRM_DEV_ERROR(hdmi->dev, "failed to get hclk_clk clock\n");
+   return PTR_ERR(hdmi->hclk_clk);
+   }
+
hdmi->avdd_0v9 = devm_regulator_get(hdmi->dev, "avdd-0v9");
if (IS_ERR(hdmi->avdd_0v9))
return PTR_ERR(hdmi->avdd_0v9);
@@ -596,6 +605,13 @@ static int dw_hdmi_rockchip_bind(struct device *dev, 
struct device *master,
goto err_clk;
}
 
+   ret = clk_prepare_enable(hdmi->hclk_clk);
+   if (ret) {
+   DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI hclk clock: 
%d\n",
+ ret);
+   goto err_clk;
+   }
+
if (hdmi->chip_data == _chip_data) {
regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1,
 HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK |
-- 
2.30.2



[PATCH v7 19/24] arm64: dts: rockchip: rk3568-evb: Enable VOP2 and hdmi

2022-02-24 Thread Sascha Hauer
This enabled the VOP2 display controller along with hdmi and the
required port routes which is enough to get a picture out of the
hdmi port of the board.

Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v5:
- Drop reg property from single endpoint node

Changes since v4:
- Sort nodes alphabetically

Changes since v3:
- Fix HDMI connector type

 .../boot/dts/rockchip/rk3568-evb1-v10.dts | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts 
b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 184e2aa2416af..792735d424716 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 #include 
 #include 
+#include 
 #include "rk3568.dtsi"
 
 / {
@@ -33,6 +34,17 @@ dc_12v: dc-12v {
regulator-max-microvolt = <1200>;
};
 
+   hdmi-con {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
vcc3v3_sys: vcc3v3-sys {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_sys";
@@ -106,6 +118,24 @@ _rgmii_clk
status = "okay";
 };
 
+ {
+   avdd-0v9-supply = <_image>;
+   avdd-1v8-supply = <_image>;
+   status = "okay";
+};
+
+_in {
+   hdmi_in_vp0: endpoint {
+   remote-endpoint = <_out_hdmi>;
+   };
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
status = "okay";
 
@@ -390,3 +420,20 @@  {
  {
status = "okay";
 };
+
+ {
+   assigned-clocks = < DCLK_VOP0>, < DCLK_VOP1>;
+   assigned-clock-parents = < PLL_HPLL>, < PLL_VPLL>;
+   status = "okay";
+};
+
+_mmu {
+   status = "okay";
+};
+
+ {
+   vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+   reg = ;
+   remote-endpoint = <_in_vp0>;
+   };
+};
-- 
2.30.2



[PATCH v7 12/24] drm/rockchip: dw_hdmi: Use auto-generated tables

2022-02-24 Thread Sascha Hauer
From: Douglas Anderson 

The previous tables for mpll_cfg and curr_ctrl were created using the
20-pages of example settings provided by the PHY vendor.  Those
example settings weren't particularly dense, so there were places
where we were guessing what the settings would be for 10-bit and
12-bit (not that we use those anyway).  It was also always a lot of
extra work every time we wanted to add a new clock rate since we had
to cross-reference several tables.

In  I've gone through the work to figure
out how to generate this table automatically.  Let's now use the
automatically generated table and then we'll never need to look at it
again.

We only support 8-bit mode right now and only support a small number
of clock rates and I've verified that the only 8-bit rate that was
affected was 148.5.  That mode appears to have been wrong in the old
table.

Signed-off-by: Douglas Anderson 
Signed-off-by: Yakir Yang 
Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v5:
- Add missing Signed-off-by me

Changes since v3:
- new patch

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 130 +++-
 1 file changed, 69 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index c6c00e8779ab5..2f5264a7d558a 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -92,80 +92,88 @@ static struct rockchip_hdmi *to_rockchip_hdmi(struct 
drm_encoder *encoder)
 
 static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
{
-   2700, {
-   { 0x00b3, 0x},
-   { 0x2153, 0x},
-   { 0x40f3, 0x}
+   30666000, {
+   { 0x00b3, 0x },
+   { 0x2153, 0x },
+   { 0x40f3, 0x },
},
-   }, {
-   3600, {
-   { 0x00b3, 0x},
-   { 0x2153, 0x},
-   { 0x40f3, 0x}
+   },  {
+   3680, {
+   { 0x00b3, 0x },
+   { 0x2153, 0x },
+   { 0x40a2, 0x0001 },
},
-   }, {
-   4000, {
-   { 0x00b3, 0x},
-   { 0x2153, 0x},
-   { 0x40f3, 0x}
+   },  {
+   4600, {
+   { 0x00b3, 0x },
+   { 0x2142, 0x0001 },
+   { 0x40a2, 0x0001 },
},
-   }, {
-   5400, {
-   { 0x0072, 0x0001},
-   { 0x2142, 0x0001},
-   { 0x40a2, 0x0001},
+   },  {
+   61333000, {
+   { 0x0072, 0x0001 },
+   { 0x2142, 0x0001 },
+   { 0x40a2, 0x0001 },
},
-   }, {
-   6500, {
-   { 0x0072, 0x0001},
-   { 0x2142, 0x0001},
-   { 0x40a2, 0x0001},
+   },  {
+   7360, {
+   { 0x0072, 0x0001 },
+   { 0x2142, 0x0001 },
+   { 0x4061, 0x0002 },
},
-   }, {
-   6600, {
-   { 0x013e, 0x0003},
-   { 0x217e, 0x0002},
-   { 0x4061, 0x0002}
+   },  {
+   9200, {
+   { 0x0072, 0x0001 },
+   { 0x2145, 0x0002 },
+   { 0x4061, 0x0002 },
},
-   }, {
-   7425, {
-   { 0x0072, 0x0001},
-   { 0x2145, 0x0002},
-   { 0x4061, 0x0002}
+   },  {
+   122666000, {
+   { 0x0051, 0x0002 },
+   { 0x2145, 0x0002 },
+   { 0x4061, 0x0002 },
},
-   }, {
-   8350, {
-   { 0x0072, 0x0001},
+   },  {
+   14720, {
+   { 0x0051, 0x0002 },
+   { 0x2145, 0x0002 },
+   { 0x4064, 0x0003 },
},
-   }, {
-   10800, {
-   { 0x0051, 0x0002},
-   { 0x2145, 0x0002},
-   { 0x4061, 0x0002}
+   },  {
+   18400, {
+   { 0x0051, 0x0002 },
+   { 0x214c, 0x0003 },
+   { 0x4064, 0x0003 },
},
-   }, {
-   10650, {
-   { 0x0051, 0x0002},
-   { 0x2145, 0x0002},
-   { 0x4061, 0x0002}
+   },  {
+   22000, {

[PATCH v7 18/24] arm64: dts: rockchip: rk356x: Add HDMI nodes

2022-02-24 Thread Sascha Hauer
Add support for the HDMI port found on RK3568.

Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v5:
- Drop unnecessary #size-cells/#address-cells from nodes with only single 
endpoint

 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 32 
 1 file changed, 32 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi 
b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 19d8e67c4698b..229ed7a755f3b 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -502,6 +502,38 @@ vop_mmu: iommu@fe043e00 {
status = "disabled";
};
 
+   hdmi: hdmi@fe0a {
+   compatible = "rockchip,rk3568-dw-hdmi";
+   reg = <0x0 0xfe0a 0x0 0x2>;
+   interrupts = ;
+   clocks = < PCLK_HDMI_HOST>,
+< CLK_HDMI_SFR>,
+< CLK_HDMI_CEC>,
+< CLK_HDMI_REF>,
+< HCLK_VOP>;
+   clock-names = "iahb", "isfr", "cec", "ref", "hclk";
+   pinctrl-names = "default";
+   pinctrl-0 = <_scl _sda _cec>;
+   power-domains = < RK3568_PD_VO>;
+   reg-io-width = <4>;
+   rockchip,grf = <>;
+   #sound-dai-cells = <0>;
+   status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   hdmi_in: port@0 {
+   reg = <0>;
+   };
+
+   hdmi_out: port@1 {
+   reg = <1>;
+   };
+   };
+   };
+
qos_gpu: qos@fe128000 {
compatible = "rockchip,rk3568-qos", "syscon";
reg = <0x0 0xfe128000 0x0 0x20>;
-- 
2.30.2



[PATCH v7 03/24] drm/rockchip: dw_hdmi: rename vpll clock to reference clock

2022-02-24 Thread Sascha Hauer
"vpll" is a misnomer. A clock input to a device should be named after
the usage in the device, not after the clock that drives it. On the
rk3568 the same clock is driven by the HPLL.
To fix that, this patch renames the vpll clock to ref clock. The clock
name "vpll" is left for compatibility to old device trees.

Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v6:
- Simplify by using devm_clk_get_optional() instead of devm_clk_get()

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 27 +++--
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 06c9ddef6f362..912181429880a 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -69,7 +69,7 @@ struct rockchip_hdmi {
struct regmap *regmap;
struct rockchip_encoder encoder;
const struct rockchip_hdmi_chip_data *chip_data;
-   struct clk *vpll_clk;
+   struct clk *ref_clk;
struct clk *grf_clk;
struct dw_hdmi *hdmi;
struct phy *phy;
@@ -201,14 +201,15 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
return PTR_ERR(hdmi->regmap);
}
 
-   hdmi->vpll_clk = devm_clk_get(hdmi->dev, "vpll");
-   if (PTR_ERR(hdmi->vpll_clk) == -ENOENT) {
-   hdmi->vpll_clk = NULL;
-   } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) {
+   hdmi->ref_clk = devm_clk_get_optional(hdmi->dev, "ref");
+   if (!hdmi->ref_clk)
+   hdmi->ref_clk = devm_clk_get_optional(hdmi->dev, "vpll");
+
+   if (PTR_ERR(hdmi->ref_clk) == -EPROBE_DEFER) {
return -EPROBE_DEFER;
-   } else if (IS_ERR(hdmi->vpll_clk)) {
-   DRM_DEV_ERROR(hdmi->dev, "failed to get vpll clock\n");
-   return PTR_ERR(hdmi->vpll_clk);
+   } else if (IS_ERR(hdmi->ref_clk)) {
+   DRM_DEV_ERROR(hdmi->dev, "failed to get reference clock\n");
+   return PTR_ERR(hdmi->ref_clk);
}
 
hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf");
@@ -262,7 +263,7 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct 
drm_encoder *encoder,
 {
struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
 
-   clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000);
+   clk_set_rate(hdmi->ref_clk, adj_mode->clock * 1000);
 }
 
 static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
@@ -542,9 +543,9 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct 
device *master,
return ret;
}
 
-   ret = clk_prepare_enable(hdmi->vpll_clk);
+   ret = clk_prepare_enable(hdmi->ref_clk);
if (ret) {
-   DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n",
+   DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI reference 
clock: %d\n",
  ret);
return ret;
}
@@ -563,7 +564,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct 
device *master,
if (IS_ERR(hdmi->hdmi)) {
ret = PTR_ERR(hdmi->hdmi);
drm_encoder_cleanup(encoder);
-   clk_disable_unprepare(hdmi->vpll_clk);
+   clk_disable_unprepare(hdmi->ref_clk);
}
 
return ret;
@@ -575,7 +576,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, 
struct device *master,
struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
 
dw_hdmi_unbind(hdmi->hdmi);
-   clk_disable_unprepare(hdmi->vpll_clk);
+   clk_disable_unprepare(hdmi->ref_clk);
 }
 
 static const struct component_ops dw_hdmi_rockchip_ops = {
-- 
2.30.2



[PATCH v7 13/24] drm/rockchip: dw_hdmi: drop mode_valid hook

2022-02-24 Thread Sascha Hauer
The driver checks if the pixel clock of the given mode matches an entry
in the mpll config table. The frequencies in the mpll table are meant as
a frequency range up to which the entry works, not as a frequency that
must match the pixel clock. The downstream Kernel also does not have
this check, so drop it to allow for more display resolutions.

Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v3:
- new patch

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 25 -
 1 file changed, 25 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 2f5264a7d558a..d1fe4d9299c96 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -257,26 +257,6 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
return 0;
 }
 
-static enum drm_mode_status
-dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data,
-   const struct drm_display_info *info,
-   const struct drm_display_mode *mode)
-{
-   const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
-   int pclk = mode->clock * 1000;
-   bool valid = false;
-   int i;
-
-   for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
-   if (pclk == mpll_cfg[i].mpixelclock) {
-   valid = true;
-   break;
-   }
-   }
-
-   return (valid) ? MODE_OK : MODE_BAD;
-}
-
 static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder)
 {
 }
@@ -442,7 +422,6 @@ static struct rockchip_hdmi_chip_data rk3228_chip_data = {
 };
 
 static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
-   .mode_valid = dw_hdmi_rockchip_mode_valid,
.mpll_cfg = rockchip_mpll_cfg,
.cur_ctr = rockchip_cur_ctr,
.phy_config = rockchip_phy_config,
@@ -459,7 +438,6 @@ static struct rockchip_hdmi_chip_data rk3288_chip_data = {
 };
 
 static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = {
-   .mode_valid = dw_hdmi_rockchip_mode_valid,
.mpll_cfg   = rockchip_mpll_cfg,
.cur_ctr= rockchip_cur_ctr,
.phy_config = rockchip_phy_config,
@@ -479,7 +457,6 @@ static struct rockchip_hdmi_chip_data rk3328_chip_data = {
 };
 
 static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
-   .mode_valid = dw_hdmi_rockchip_mode_valid,
.mpll_cfg = rockchip_mpll_cfg,
.cur_ctr = rockchip_cur_ctr,
.phy_config = rockchip_phy_config,
@@ -497,7 +474,6 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = {
 };
 
 static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
-   .mode_valid = dw_hdmi_rockchip_mode_valid,
.mpll_cfg   = rockchip_mpll_cfg,
.cur_ctr= rockchip_cur_ctr,
.phy_config = rockchip_phy_config,
@@ -510,7 +486,6 @@ static struct rockchip_hdmi_chip_data rk3568_chip_data = {
 };
 
 static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
-   .mode_valid = dw_hdmi_rockchip_mode_valid,
.mpll_cfg   = rockchip_mpll_cfg,
.cur_ctr= rockchip_cur_ctr,
.phy_config = rockchip_phy_config,
-- 
2.30.2



[PATCH v7 02/24] drm/rockchip: Add crtc_endpoint_id to rockchip_encoder

2022-02-24 Thread Sascha Hauer
The VOP2 has an interface mux which decides to which encoder(s) a CRTC
is routed to. The encoders and CRTCs are connected via of_graphs in the
device tree. When given an encoder the VOP2 driver needs to know to
which internal register setting this encoder matches. For this the VOP2
binding offers different endpoints, one for each possible encoder. The
endpoint ids of these endpoints are used as a key from an encoders
device tree description to the internal register setting.

This patch adds the key aka endpoint id to struct rockchip_encoder plus
a function to read the endpoint id starting from the encoders device
node.

Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v6:
- new patch

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 33 +
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  4 ++-
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index bec207de45440..7920a4f44f693 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -236,6 +236,39 @@ static const struct dev_pm_ops rockchip_drm_pm_ops = {
 static struct platform_driver *rockchip_sub_drivers[MAX_ROCKCHIP_SUB_DRIVERS];
 static int num_rockchip_sub_drivers;
 
+/*
+ * Get the endpoint id of the remote endpoint of the given encoder. This
+ * information is used by the VOP2 driver to identify the encoder.
+ *
+ * @rkencoder: The encoder to get the remote endpoint id from
+ * @np: The encoder device node
+ * @port: The number of the port leading to the VOP2
+ * @reg: The endpoint number leading to the VOP2
+ */
+int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder 
*rkencoder,
+ struct device_node *np, int port, 
int reg)
+{
+   struct of_endpoint ep;
+   struct device_node *en, *ren;
+   int ret;
+
+   en = of_graph_get_endpoint_by_regs(np, port, reg);
+   if (!en)
+   return -ENOENT;
+
+   ren = of_graph_get_remote_endpoint(en);
+   if (!ren)
+   return -ENOENT;
+
+   ret = of_graph_parse_endpoint(ren, );
+   if (ret)
+   return ret;
+
+   rkencoder->crtc_endpoint_id = ep.id;
+
+   return 0;
+}
+
 /*
  * Check if a vop endpoint is leading to a rockchip subdriver or bridge.
  * Should be called from the component bind stage of the drivers
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 686f687a76a37..1f66a447acada 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -49,6 +49,7 @@ struct rockchip_drm_private {
 };
 
 struct rockchip_encoder {
+   int crtc_endpoint_id;
struct drm_encoder encoder;
 };
 
@@ -57,7 +58,8 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
struct device *dev);
 int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout);
-
+int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder 
*rencoder,
+ struct device_node *np, int port, 
int reg);
 int rockchip_drm_endpoint_is_subdriver(struct device_node *ep);
 extern struct platform_driver cdn_dp_driver;
 extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
-- 
2.30.2



[PATCH v7 00/24] drm/rockchip: RK356x VOP2 support

2022-02-24 Thread Sascha Hauer
Here is v7 of adding RK356x VOP2 support. The one big notable change this
time is that I moved the of_graph parsing from runtime code into
initialization, see patch 2/24. Other than that there are some smaller
changes due to the review feedback to v6.

Sascha

Changes since v6:
- Move of_graph parsing out of runtime code to initialization

Changes since v5:
- Add new patch to fix dw-hdmi of_graph binding
- Drop "drm/encoder: Add of_graph port to struct drm_encoder" and solve
  issue internally in the driver
- make checkpatch cleaner

Changes since v4:
- Reorder patches in a way that binding/dts/driver patches are closer together
- Drop clk patches already applied by Heiko

Changes since v3:
- added changelog to each patch
- Add 4k support to hdmi driver
- rebase on v5.17-rc1

Changes since v2:
- Add pin names to HDMI supply pin description
- Add hclk support to HDMI driver
- Dual license rockchip-vop2 binding, update binding
- Add HDMI connector to board dts files
- drop unnecessary gamma_lut registers from vop2
- Update dclk_vop[012] clock handling, no longer hacks needed
- Complete regmap conversion

Changes since v1:
- drop all unnecessary waiting for frames within atomic modeset and plane update
- Cluster subwin support removed
- gamma support removed
- unnecessary irq_lock removed
- interrupt handling simplified
- simplified zpos handling
- drop is_alpha_support(), use fb->format->has_alpha instead
- use devm_regulator_get() rather than devm_regulator_get_optional() for hdmi 
regulators
- Use fixed number of planes per video port
- Drop homegrown regmap code from vop2 driver (not complete yet)
- Add separate include file for vop2 driver to not pollute the vop include

Andy Yan (1):
  drm: rockchip: Add VOP2 driver

Benjamin Gaignard (1):
  dt-bindings: display: rockchip: dw-hdmi: Add compatible for rk3568
HDMI

Douglas Anderson (2):
  drm/rockchip: dw_hdmi: Use auto-generated tables
  drm/rockchip: dw_hdmi: Set cur_ctr to 0 always

Michael Riesch (1):
  arm64: dts: rockchip: enable vop2 and hdmi tx on quartz64a

Nickey Yang (1):
  drm/rockchip: dw_hdmi: add default 594Mhz clk for 4K@60hz

Sascha Hauer (18):
  drm/rockchip: Embed drm_encoder into rockchip_decoder
  drm/rockchip: Add crtc_endpoint_id to rockchip_encoder
  drm/rockchip: dw_hdmi: rename vpll clock to reference clock
  dt-bindings: display: rockchip: dw-hdmi: use "ref" as clock name
  arm64: dts: rockchip: rk3399: rename HDMI ref clock to 'ref'
  drm/rockchip: dw_hdmi: add rk3568 support
  drm/rockchip: dw_hdmi: add regulator support
  dt-bindings: display: rockchip: dw-hdmi: Add regulator support
  drm/rockchip: dw_hdmi: Add support for hclk
  dt-bindings: display: rockchip: dw-hdmi: Add additional clock
  drm/rockchip: dw_hdmi: drop mode_valid hook
  dt-bindings: display: rockchip: dw-hdmi: Make unwedge pinctrl optional
  arm64: dts: rockchip: rk356x: Add VOP2 nodes
  arm64: dts: rockchip: rk356x: Add HDMI nodes
  arm64: dts: rockchip: rk3568-evb: Enable VOP2 and hdmi
  drm/rockchip: Make VOP driver optional
  dt-bindings: display: rockchip: Add binding for VOP2
  dt-bindings: display: rockchip: dw-hdmi: fix ports description

 .../display/rockchip/rockchip,dw-hdmi.yaml|   53 +-
 .../display/rockchip/rockchip-vop2.yaml   |  140 +
 arch/arm64/boot/dts/rockchip/rk3399.dtsi  |2 +-
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   |   47 +
 arch/arm64/boot/dts/rockchip/rk3566.dtsi  |4 +
 .../boot/dts/rockchip/rk3568-evb1-v10.dts |   47 +
 arch/arm64/boot/dts/rockchip/rk3568.dtsi  |4 +
 arch/arm64/boot/dts/rockchip/rk356x.dtsi  |   83 +
 drivers/gpu/drm/rockchip/Kconfig  |   14 +
 drivers/gpu/drm/rockchip/Makefile |4 +-
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   |   32 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.c|   18 +-
 drivers/gpu/drm/rockchip/cdn-dp-core.h|2 +-
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   |   17 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   |  292 +-
 drivers/gpu/drm/rockchip/inno_hdmi.c  |   32 +-
 drivers/gpu/drm/rockchip/rk3066_hdmi.c|   34 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |   36 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |   20 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c|2 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h   |   15 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  | 2686 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h  |  477 +++
 drivers/gpu/drm/rockchip/rockchip_lvds.c  |   26 +-
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c  |  281 ++
 include/dt-bindings/soc/rockchip,vop2.h   |   14 +
 26 files changed, 4186 insertions(+), 196 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
 create 

[PATCH v7 14/24] drm/rockchip: dw_hdmi: Set cur_ctr to 0 always

2022-02-24 Thread Sascha Hauer
From: Douglas Anderson 

Jitter was improved by lowering the MPLL bandwidth to account for high
frequency noise in the rk3288 PLL.  In each case MPLL bandwidth was
lowered only enough to get us a comfortable margin.  We believe that
lowering the bandwidth like this is safe given sufficient testing.

Signed-off-by: Douglas Anderson 
Signed-off-by: Yakir Yang 
Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v3:
- new patch

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++--
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index d1fe4d9299c96..e97ba072a097b 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -181,20 +181,8 @@ static const struct dw_hdmi_mpll_config 
rockchip_mpll_cfg[] = {
 static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
/*  pixelclkbpp8bpp10   bpp12 */
{
-   4000,  { 0x0018, 0x0018, 0x0018 },
-   }, {
-   6500,  { 0x0028, 0x0028, 0x0028 },
-   }, {
-   6600,  { 0x0038, 0x0038, 0x0038 },
-   }, {
-   7425,  { 0x0028, 0x0038, 0x0038 },
-   }, {
-   8350,  { 0x0028, 0x0038, 0x0038 },
-   }, {
-   14625, { 0x0038, 0x0038, 0x0038 },
-   }, {
-   14850, { 0x, 0x0038, 0x0038 },
-   }, {
+   6, { 0x, 0x, 0x },
+   },  {
~0UL,  { 0x, 0x, 0x},
}
 };
-- 
2.30.2



[PATCH v7 05/24] arm64: dts: rockchip: rk3399: rename HDMI ref clock to 'ref'

2022-02-24 Thread Sascha Hauer
The reference clock for the HDMI controller has been renamed to 'ref',
the previous 'vpll' name is only left for compatibility in the driver.
Rename the clock to the new name.

Signed-off-by: Sascha Hauer 
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 080457a68e3c7..d0add619b0d22 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1884,7 +1884,7 @@ hdmi: hdmi@ff94 {
 < SCLK_HDMI_CEC>,
 < PCLK_VIO_GRF>,
 < PLL_VPLL>;
-   clock-names = "iahb", "isfr", "cec", "grf", "vpll";
+   clock-names = "iahb", "isfr", "cec", "grf", "ref";
power-domains = < RK3399_PD_HDCP>;
reg-io-width = <4>;
rockchip,grf = <>;
-- 
2.30.2



[PATCH v7 15/24] drm/rockchip: dw_hdmi: add default 594Mhz clk for 4K@60hz

2022-02-24 Thread Sascha Hauer
From: Nickey Yang 

add 594Mhz configuration parameters in rockchip_phy_config

Signed-off-by: Nickey Yang 
Signed-off-by: Sascha Hauer 
---

Notes:
Changes since v3:
- new patch

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index e97ba072a097b..03cda7229e559 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -192,6 +192,7 @@ static const struct dw_hdmi_phy_config 
rockchip_phy_config[] = {
{ 7425,  0x8009, 0x0004, 0x0272},
{ 14850, 0x802b, 0x0004, 0x028d},
{ 29700, 0x8039, 0x0005, 0x028d},
+   { 59400, 0x8039, 0x, 0x019d},
{ ~0UL,  0x, 0x, 0x}
 };
 
-- 
2.30.2



[PATCH] dma-fance: Add dma_fence_assert_in_signalling_section

2022-02-24 Thread Daniel Vetter
Useful for checking for dma-fence signalling annotations since they
don't quite nest as freely as we'd like to.

Cc: Matthew Brost 
Signed-off-by: Daniel Vetter 
Cc: Sumit Semwal 
Cc: Gustavo Padovan 
Cc: "Christian König" 
Cc: linux-me...@vger.kernel.org
Cc: linaro-mm-...@lists.linaro.org
---
 drivers/dma-buf/dma-fence.c | 19 +++
 include/linux/dma-fence.h   |  2 ++
 2 files changed, 21 insertions(+)

diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 066400ed8841..2b7c3fc965e6 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -307,6 +307,25 @@ bool dma_fence_begin_signalling(void)
 }
 EXPORT_SYMBOL(dma_fence_begin_signalling);
 
+/**
+ * dma_fence_assert_in_signalling_section - check fence signalling annotations
+ *
+ * Since dma_fence_begin_signalling() and dma_fence_end_signalling() are built
+ * using lockdep annotations they have limitations on how freely they can be
+ * nested. Specifically, they cannot be on both inside and outside of locked
+ * sections, which in practice means the annotations often have to be pushed 
out
+ * to the top level callers.
+ *
+ * To ensure low-level functions are only called with the correction
+ * annotations, this function can be used to check for that.
+ */
+void dma_fence_assert_in_signalling_section(void)
+{
+   if (!in_atomic())
+   lockdep_assert(lock_is_held(_fence_lockdep_map));
+}
+EXPORT_SYMBOL(dma_fence_assert_in_signalling_section);
+
 /**
  * dma_fence_end_signalling - end a critical DMA fence signalling section
  * @cookie: opaque cookie from dma_fence_begin_signalling()
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index 775cdc0b4f24..7179a5692f72 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -356,6 +356,7 @@ dma_fence_get_rcu_safe(struct dma_fence __rcu **fencep)
 
 #ifdef CONFIG_LOCKDEP
 bool dma_fence_begin_signalling(void);
+void dma_fence_assert_in_signalling_section(void);
 void dma_fence_end_signalling(bool cookie);
 void __dma_fence_might_wait(void);
 #else
@@ -363,6 +364,7 @@ static inline bool dma_fence_begin_signalling(void)
 {
return true;
 }
+static inline void dma_fence_assert_in_signalling_section(void) {}
 static inline void dma_fence_end_signalling(bool cookie) {}
 static inline void __dma_fence_might_wait(void) {}
 #endif
-- 
2.34.1



Re: [PATCH v5 1/4] drm/i915/guc: Add fetch of hwconfig table

2022-02-24 Thread Jordan Justen
John Harrison  writes:

> On 2/22/2022 02:36, Jordan Justen wrote:
>> From: John Harrison 
>>
>> Implement support for fetching the hardware description table from the
>> GuC. The call is made twice - once without a destination buffer to
>> query the size and then a second time to fill in the buffer.
>>
>> Note that the table is only available on ADL-P and later platforms.
>>
>> v5 (of Jordan's posting):
>>   * Various changes made by Jordan and recommended by Michal
>> - Makefile ordering
>> - Adjust "struct intel_guc_hwconfig hwconfig" comment
>> - Set Copyright year to 2022 in intel_guc_hwconfig.c/.h
>> - Drop inline from hwconfig_to_guc()
>> - Replace hwconfig param with guc in __guc_action_get_hwconfig()
>> - Move zero size check into guc_hwconfig_discover_size()
>> - Change comment to say zero size offset/size is needed to get size
>> - Add has_guc_hwconfig to devinfo and drop has_table()
>> - Change drm_err to notice in __uc_init_hw() and use %pe
>>
>> Cc: Michal Wajdeczko 
>> Signed-off-by: Rodrigo Vivi 
>> Signed-off-by: John Harrison 
>> Reviewed-by: Matthew Brost 
>> Acked-by: Jon Bloomfield 
>> Signed-off-by: Jordan Justen 
>> ---
>>   
>> +ret = intel_guc_hwconfig_init(>hwconfig);
>> +if (ret)
>> +drm_notice(>drm, "Failed to retrieve hwconfig table: 
>> %pe\n",
> Why only drm_notice? As you are keen to point out, the UMDs won't work 
> if the table is not available. All the failure paths in your own 
> verification function are 'drm_err'. So why is it only a 'notice' if 
> there is no table at all?

This was requested by Michal in my v3 posting:

https://patchwork.freedesktop.org/patch/472936/?series=99787=3

I don't think that it should be a failure for i915 if it is unable to
read the table, or if the table read is invalid. I think it should be up
to the UMD to react to the missing hwconfig however they think is
appropriate, but I would like the i915 to guarantee & document the
format returned to userspace to whatever extent is feasible.

As you point out there is a discrepancy, and I think I should be
consistent with whatever is used here in my "drm/i915/guc: Verify
hwconfig blob matches supported format" patch.

I guess I'd tend to agree with Michal that "maybe drm_notice since we
continue probe", but I would go along with either if you two want to
discuss further.

> Note that this function is called as part of the reset path. The reset 
> path is not allowed to allocate memory. The table is stored in a 
> dynamically allocated object. Hence the IGT test failure. The table 
> query has to be done elsewhere at driver init time only.

Thanks for clearing this up. I did notice on dg2 that gpu resets were
causing a re-read of the hwconfig from GuC, but it definitely was not
clear to me that there would be a connection to the IGT failure that you
pointed out.

>
>> +   ERR_PTR(ret));
>> +
>>  ret = guc_enable_communication(guc);
>>  if (ret)
>>  goto err_log_capture;
>> @@ -562,6 +567,8 @@ static void __uc_fini_hw(struct intel_uc *uc)
>>  if (intel_uc_uses_guc_submission(uc))
>>  intel_guc_submission_disable(guc);
>>   
>> +intel_guc_hwconfig_fini(>hwconfig);
>> +
>>  __uc_sanitize(uc);
>>   }
>>   
>> diff --git a/drivers/gpu/drm/i915/i915_pci.c 
>> b/drivers/gpu/drm/i915/i915_pci.c
>> index 76e590fcb903..1d31e35a5154 100644
>> --- a/drivers/gpu/drm/i915/i915_pci.c
>> +++ b/drivers/gpu/drm/i915/i915_pci.c
>> @@ -990,6 +990,7 @@ static const struct intel_device_info adl_p_info = {
>>  BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2),
>>  .ppgtt_size = 48,
>>  .dma_mask_size = 39,
>> +.has_guc_hwconfig = 1,
> Who requested this change? It was previously done this way but the 
> instruction was that i915_pci.c is for hardware features only but that 
> this, as you seem extremely keen about pointing out at every 
> opportunity, is a software feature.

This was requested by Michal as well. I definitely agree it is a
software feature, but I was not aware that "i915_pci.c is for hardware
features only".

Michal, do you agree with this and returning to the previous method for
enabling the feature?

-Jordan


Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment

2022-02-24 Thread Abhinav Kumar




On 2/24/2022 8:22 PM, Dmitry Baryshkov wrote:

On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar  wrote:




On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:

On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar  wrote:




On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:

On 19/02/2022 02:56, Stephen Boyd wrote:

Quoting Dmitry Baryshkov (2022-02-11 14:40:02)

In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
enable and disable") the DP driver received a drm_bridge instance, which
is always attached to the encoder as a root bridge. However it conflicts
with the panel_bridge support for eDP panels. The panel bridge attaches
to the encoder before the "dp" bridge has a chace to do so. Change


s/chace/chance/


panel_bridge attachment to come after dp_bridge attachment.


s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
is the "DP driver's drm_bridge instance created in
msm_dp_bridge_init()"?

My understanding is that we want to pass the bridge created in
msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
panel bridge to the output of the DP bridge that's attached to the
encoder.


Thanks! I'll update the commit log when pushing the patches.


Please correct if i am missing something here.

You are right that the eDP panel's panel bridge attaches to the encoder
in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
hence it will attach directly to the encoder.

But we are talking about different encoders here. DP's dp_display has a
different encoder compared to the EDP's dp_display.


The encoders are different. However both encoders use the same
codepath, which includes dp_bridge. It controls dp_display by calling
msm_dp_display_foo() functions.




So DP's bridge will still be attached to its encoder's root.


There is one dp_bridge per each encoder. Consider sc8180x which has 3
DP controllers (and thus 3 dp_bridges).



Sorry, but I still didnt follow this.

So for eDP, dp_drm_connector_init() will attach the panel_bridge
and then msm_dp_bridge_init() will add a drm_bridge.

And yes in that case, the drm_bridge will be after the panel_bridge

But since panel_bridge is at the root for eDP it should be okay.


No. It is not.
For both DP and eDP the chain should be:
dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
-> [other bridges] -> connector

Otherwise drm_bridge_chain_foo() functions would be called in the
incorrect order.


Agreed. For drm_bridge_chain_foo() ordering to be correct, for eDP chain 
the order should be what you mentioned and panel_bridge should be at the 
end ( should be the last one ).


For the above reason,

Reviewed-by: Abhinav Kumar 

I still didnt understand what gets affected by this for the 
msm_dp_display_foo() functions you mentioned earlier and wanted to get 
some clarity on that.


Thus the dp_bridge should be attached directly to the encoder
(drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
bridge.



Agreed.


For example, for the DP port one can use a display-connector (which
actually implements drm_bridge) as an external bridge to provide hpd
or dp power GPIOs.

Note, that the current dp_connector breaks layering. It makes calls
directly into dp_display, not allowing external bridge (and other
bridges) to override get_modes/mode_valid and other callbacks.
Thus one of the next patches in series (the one that Kuogee had issues
with) tries to replace the chain with the following one:
dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
-> drm_bridge_connector.





So originally the plan was always that the DP connector layer intercepts 
the call because panel-eDP file did not support reading of the EDID ( we 
have not provided the aux bus ). So it was intended that we did not want 
to goto the eDP panel to get the modes. Not an error but something which 
we wanted to cleanup later when we moved to panel-eDP completely.


Till then we wanted the dp_connector to read the EDID and get the modes.

So this was actually intended to happen till the point where we moved to 
panel-eDP to get the modes.


Hence what you have mentioned in your cover letter is right that the 
chain was broken but there was no loss of functionality due to that today.


Now that these changes are made, we can still goto panel-eDP file for 
the modes because of the below change from Sankeerth where the mode is 
hard-coded:


https://patchwork.freedesktop.org/patch/473431/

With this change cherry-picked it should work for kuogee. We will 
re-test that with this change.




Your commit text was mentioning about DP.

For DP, for each controller in the catalog, we will call modeset_init()
which should skip this part for DP

if (dp_display->panel_bridge) {
  ret = drm_bridge_attach(dp_display->encoder,
  dp_display->panel_bridge, NULL,


as you see, NULL is incorrect. It should be a pointer to dp_bridge instead


  

Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment

2022-02-24 Thread Dmitry Baryshkov
On Fri, 25 Feb 2022 at 05:01, Abhinav Kumar  wrote:
>
>
>
> On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:
> > On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar  
> > wrote:
> >>
> >>
> >>
> >> On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:
> >>> On 19/02/2022 02:56, Stephen Boyd wrote:
>  Quoting Dmitry Baryshkov (2022-02-11 14:40:02)
> > In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> > enable and disable") the DP driver received a drm_bridge instance, which
> > is always attached to the encoder as a root bridge. However it conflicts
> > with the panel_bridge support for eDP panels. The panel bridge attaches
> > to the encoder before the "dp" bridge has a chace to do so. Change
> 
>  s/chace/chance/
> 
> > panel_bridge attachment to come after dp_bridge attachment.
> 
>  s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
>  is the "DP driver's drm_bridge instance created in
>  msm_dp_bridge_init()"?
> 
>  My understanding is that we want to pass the bridge created in
>  msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
>  panel bridge to the output of the DP bridge that's attached to the
>  encoder.
> >>>
> >>> Thanks! I'll update the commit log when pushing the patches.
> >>
> >> Please correct if i am missing something here.
> >>
> >> You are right that the eDP panel's panel bridge attaches to the encoder
> >> in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
> >> hence it will attach directly to the encoder.
> >>
> >> But we are talking about different encoders here. DP's dp_display has a
> >> different encoder compared to the EDP's dp_display.
> >
> > The encoders are different. However both encoders use the same
> > codepath, which includes dp_bridge. It controls dp_display by calling
> > msm_dp_display_foo() functions.
> >

> >> So DP's bridge will still be attached to its encoder's root.
> >
> > There is one dp_bridge per each encoder. Consider sc8180x which has 3
> > DP controllers (and thus 3 dp_bridges).
> >
>
> Sorry, but I still didnt follow this.
>
> So for eDP, dp_drm_connector_init() will attach the panel_bridge
> and then msm_dp_bridge_init() will add a drm_bridge.
>
> And yes in that case, the drm_bridge will be after the panel_bridge
>
> But since panel_bridge is at the root for eDP it should be okay.

No. It is not.
For both DP and eDP the chain should be:
dpu_encoder -> dp_bridge -> external (panel) bridge, optional for DP
-> [other bridges] -> connector

Otherwise drm_bridge_chain_foo() functions would be called in the
incorrect order.

Thus the dp_bridge should be attached directly to the encoder
(drm_encoder) and panel_bridge should use dp_bridge as the 'previous'
bridge.

For example, for the DP port one can use a display-connector (which
actually implements drm_bridge) as an external bridge to provide hpd
or dp power GPIOs.

Note, that the current dp_connector breaks layering. It makes calls
directly into dp_display, not allowing external bridge (and other
bridges) to override get_modes/mode_valid and other callbacks.
Thus one of the next patches in series (the one that Kuogee had issues
with) tries to replace the chain with the following one:
dpu_encoder -> dp_bridge -> external (panel) bridge -> [other bridges]
-> drm_bridge_connector.

>
> Your commit text was mentioning about DP.
>
> For DP, for each controller in the catalog, we will call modeset_init()
> which should skip this part for DP
>
>if (dp_display->panel_bridge) {
>  ret = drm_bridge_attach(dp_display->encoder,
>  dp_display->panel_bridge, NULL,

as you see, NULL is incorrect. It should be a pointer to dp_bridge instead

>  DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>  if (ret < 0) {
>  DRM_ERROR("failed to attach panel bridge: %d\n", ret);
>  return ERR_PTR(ret);
>  }
>  }
>
> Followed by calling msm_dp_bridge_init() which will actually attach the
> bridge:
>
> drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);

And this bridge should be attached before the external bridge.

>
> Now, even for 3 DP controllers, this shall be true as there will be 3
> separate encoders and 3 dp_displays and hence 3 drm_bridges.
>
> What am i missing here?
>
> >>
> >> So what are we achieving with this change?
> >>
> >>>
> 
> >
> > Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
> > enable and disable")
> > Cc: Kuogee Hsieh 
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> 
>  Reviewed-by: Stephen Boyd 
> 
> >drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++--
> >1 file changed, 11 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
> > b/drivers/gpu/drm/msm/dp/dp_drm.c
> > index d4d360d19eba..26ef41a4c1b6 100644
> > --- 

[PATCH v3 0/2] drm/dp: Fix out-of-bounds reads

2022-02-24 Thread Kees Cook
Hi,

I'm sending these again, as they still need fixing. They have been
rebased due to the drm_dp_helper code being moved into a subdirectory.

Can someone please apply these? :)

Thanks!

-Kees

v1: https://patchwork.freedesktop.org/patch/465200/
https://patchwork.freedesktop.org/patch/465201/
v2: https://patchwork.freedesktop.org/patch/468350/
https://patchwork.freedesktop.org/patch/468351/
v3:
 - add review tags
 - rebase to drm/drm-next

Kees Cook (2):
  drm/dp: Fix off-by-one in register cache size
  drm/dp: Fix OOB read when handling Post Cursor2 register

 drivers/gpu/drm/dp/drm_dp.c| 10 --
 drivers/gpu/drm/tegra/dp.c | 11 ++-
 include/drm/dp/drm_dp_helper.h |  4 +---
 3 files changed, 11 insertions(+), 14 deletions(-)

-- 
2.30.2



[PATCH v3 1/2] drm/dp: Fix off-by-one in register cache size

2022-02-24 Thread Kees Cook
The pcon_dsc_dpcd array holds 13 registers (0x92 through 0x9E). Fix the
math to calculate the max size. Found from a -Warray-bounds build:

drivers/gpu/drm/drm_dp_helper.c: In function 'drm_dp_pcon_dsc_bpp_incr':
drivers/gpu/drm/drm_dp_helper.c:3130:28: error: array subscript 12 is outside 
array bounds of 'const u8[12]' {aka 'const unsigned char[12]'} 
[-Werror=array-bounds]
 3130 | buf = pcon_dsc_dpcd[DP_PCON_DSC_BPP_INCR - DP_PCON_DSC_ENCODER];
  |   ~^~~~
drivers/gpu/drm/drm_dp_helper.c:3126:39: note: while referencing 'pcon_dsc_dpcd'
 3126 | int drm_dp_pcon_dsc_bpp_incr(const u8 
pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
  |  
~^~~

Cc: Daniel Vetter 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
Cc: David Airlie 
Cc: dri-devel@lists.freedesktop.org
Fixes: e2e16da398d9 ("drm/dp_helper: Add support for Configuring DSC for 
HDMI2.1 Pcon")
Cc: sta...@vger.kernel.org
Reviewed-by: Gustavo A. R. Silva 
Link: https://lore.kernel.org/lkml/20211214001849.GA62559@embeddedor/
Signed-off-by: Kees Cook 
Link: https://lore.kernel.org/r/20220105173310.2420598-1-keesc...@chromium.org
---
 include/drm/dp/drm_dp_helper.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h
index 69487bd8ed56..2a0e75e69e80 100644
--- a/include/drm/dp/drm_dp_helper.h
+++ b/include/drm/dp/drm_dp_helper.h
@@ -456,7 +456,7 @@ struct drm_panel;
 #define DP_FEC_CAPABILITY_10x091   /* 2.0 */
 
 /* DP-HDMI2.1 PCON DSC ENCODER SUPPORT */
-#define DP_PCON_DSC_ENCODER_CAP_SIZE0xC/* 0x9E - 0x92 */
+#define DP_PCON_DSC_ENCODER_CAP_SIZE0xD/* 0x92 through 0x9E */
 #define DP_PCON_DSC_ENCODER 0x092
 # define DP_PCON_DSC_ENCODER_SUPPORTED  (1 << 0)
 # define DP_PCON_DSC_PPS_ENC_OVERRIDE   (1 << 1)
-- 
2.30.2



[PATCH v3 2/2] drm/dp: Fix OOB read when handling Post Cursor2 register

2022-02-24 Thread Kees Cook
The link_status array was not large enough to read the Adjust Request
Post Cursor2 register, so remove the common helper function to avoid
an OOB read, found with a -Warray-bounds build:

drivers/gpu/drm/drm_dp_helper.c: In function 
'drm_dp_get_adjust_request_post_cursor':
drivers/gpu/drm/drm_dp_helper.c:59:27: error: array subscript 10 is outside 
array bounds of 'const u8[6]' {aka 'const unsigned char[6]'} 
[-Werror=array-bounds]
   59 | return link_status[r - DP_LANE0_1_STATUS];
  |~~~^~~
drivers/gpu/drm/drm_dp_helper.c:147:51: note: while referencing 'link_status'
  147 | u8 drm_dp_get_adjust_request_post_cursor(const u8 
link_status[DP_LINK_STATUS_SIZE],
  |  
~^~~~

Replace the only user of the helper with an open-coded fetch and decode,
similar to drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c.

Cc: Daniel Vetter 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
Cc: David Airlie 
Cc: dri-devel@lists.freedesktop.org
Fixes: 79465e0ffeb9 ("drm/dp: Add helper to get post-cursor adjustments")
Signed-off-by: Kees Cook 
Reviewed-by: Gustavo A. R. Silva 
Reviewed-by: Jani Nikula 
Link: https://lore.kernel.org/r/20220105173507.2420910-1-keesc...@chromium.org
---
 drivers/gpu/drm/dp/drm_dp.c| 10 --
 drivers/gpu/drm/tegra/dp.c | 11 ++-
 include/drm/dp/drm_dp_helper.h |  2 --
 3 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/dp/drm_dp.c b/drivers/gpu/drm/dp/drm_dp.c
index e159b81800d4..703972ae14c6 100644
--- a/drivers/gpu/drm/dp/drm_dp.c
+++ b/drivers/gpu/drm/dp/drm_dp.c
@@ -208,16 +208,6 @@ bool drm_dp_128b132b_link_training_failed(const u8 
link_status[DP_LINK_STATUS_SI
 }
 EXPORT_SYMBOL(drm_dp_128b132b_link_training_failed);
 
-u8 drm_dp_get_adjust_request_post_cursor(const u8 
link_status[DP_LINK_STATUS_SIZE],
-unsigned int lane)
-{
-   unsigned int offset = DP_ADJUST_REQUEST_POST_CURSOR2;
-   u8 value = dp_link_status(link_status, offset);
-
-   return (value >> (lane << 1)) & 0x3;
-}
-EXPORT_SYMBOL(drm_dp_get_adjust_request_post_cursor);
-
 static int __8b10b_clock_recovery_delay_us(const struct drm_dp_aux *aux, u8 
rd_interval)
 {
if (rd_interval > 4)
diff --git a/drivers/gpu/drm/tegra/dp.c b/drivers/gpu/drm/tegra/dp.c
index e4369e5b2943..7295975e5733 100644
--- a/drivers/gpu/drm/tegra/dp.c
+++ b/drivers/gpu/drm/tegra/dp.c
@@ -549,6 +549,15 @@ static void drm_dp_link_get_adjustments(struct drm_dp_link 
*link,
 {
struct drm_dp_link_train_set *adjust = >train.adjust;
unsigned int i;
+   u8 post_cursor;
+   int err;
+
+   err = drm_dp_dpcd_read(link->aux, DP_ADJUST_REQUEST_POST_CURSOR2,
+  _cursor, sizeof(post_cursor));
+   if (err < 0) {
+   DRM_ERROR("failed to read post_cursor2: %d\n", err);
+   post_cursor = 0;
+   }
 
for (i = 0; i < link->lanes; i++) {
adjust->voltage_swing[i] =
@@ -560,7 +569,7 @@ static void drm_dp_link_get_adjustments(struct drm_dp_link 
*link,
DP_TRAIN_PRE_EMPHASIS_SHIFT;
 
adjust->post_cursor[i] =
-   drm_dp_get_adjust_request_post_cursor(status, i);
+   (post_cursor >> (i << 1)) & 0x3;
}
 }
 
diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h
index 2a0e75e69e80..51e02cf75277 100644
--- a/include/drm/dp/drm_dp_helper.h
+++ b/include/drm/dp/drm_dp_helper.h
@@ -1530,8 +1530,6 @@ u8 drm_dp_get_adjust_request_pre_emphasis(const u8 
link_status[DP_LINK_STATUS_SI
  int lane);
 u8 drm_dp_get_adjust_tx_ffe_preset(const u8 link_status[DP_LINK_STATUS_SIZE],
   int lane);
-u8 drm_dp_get_adjust_request_post_cursor(const u8 
link_status[DP_LINK_STATUS_SIZE],
-unsigned int lane);
 
 #define DP_BRANCH_OUI_HEADER_SIZE  0xc
 #define DP_RECEIVER_CAP_SIZE   0xf
-- 
2.30.2



Re: [PATCH] drm/exynos: fimd: add BGR support for exynos4/5

2022-02-24 Thread Inki Dae
Hi Martin,

22. 2. 25. 08:27에 Martin Jücker 이(가) 쓴 글:
> Hello Inki,
> 
> On Thu, Feb 24, 2022 at 10:41:04AM +0900, Inki Dae wrote:
>> Hi Martin.
>>
>> I found that exynos4 and 5 data sheet include documented same register.
>> RGB_ORDER_E field of VIDCONx registers will do same thing.
> 
> If I read the manual correctly, this register combined with the
> RGB_ORDER_O makes it possible to map the whole RGB interface output to a
> different order. What my patch provides is a way to configure each
> hardware plane separately while maintaining a consistent output on the
> RGB interface.
> 

Understood. Your patch will allow BGR pixel order per a plane. Seems to be 
useful because a framebuffer with BGR pixel format can be displayed on screen 
without any color space conversion. :)

> Implementing the RGB_ORDER_O and E would need some logic to make sure
> that all planes are always using the same RGB order.
> 
>>
>> I'm not sure whether the use of undocumented register is safe or not - maybe 
>> some HW bug exists.
> 
> I see, that makes sense. Would it be possible then to introduce a new
> compatible, e.g. samsung,exynos4210-fimd-ext which can be used on tested

Seems providing a new compatible is not a good idea.

> devices? I know that some other Galaxy Note and S devices with the
> exynos4 chip have the same problem (and solution).

Could you give me more details about the same problem and its solution on the 
devices?
It would be useful for us to decide the upstream direction.

If necessary then we may need to contact HW engineer for clarity.

Thanks,
Inki Dae

> 
>>
>> Anyway, I'd like to recommend you to use documented register only.
>>
>> Sorry for late and thanks,
>> Inki Dae
> 
> Kind Regards
> Martin
> 
>>
>> 22. 1. 30. 07:01에 Martin Jücker 이(가) 쓴 글:
>>> In the downstream kernels for exynos4 and exynos5 devices, there is an
>>> undocumented register that controls the order of the RGB output. It can
>>> be set to either normal order or reversed, which enables BGR support for
>>> those SoCs.
>>>
>>> This patch enables the BGR support for all the SoCs that were found to
>>> have at least one device with this logic in the corresponding downstream
>>> kernels.
>>>
>>> Signed-off-by: Martin Jücker 
>>> ---
>>>  drivers/gpu/drm/exynos/exynos_drm_fimd.c | 42 ++--
>>>  include/video/samsung_fimd.h |  4 +++
>>>  2 files changed, 44 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c 
>>> b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
>>> index c735e53939d8..cb632360c968 100644
>>> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
>>> @@ -109,6 +109,7 @@ struct fimd_driver_data {
>>> unsigned int has_dp_clk:1;
>>> unsigned int has_hw_trigger:1;
>>> unsigned int has_trigger_per_te:1;
>>> +   unsigned int has_bgr_support:1;
>>>  };
>>>  
>>>  static struct fimd_driver_data s3c64xx_fimd_driver_data = {
>>> @@ -138,6 +139,7 @@ static struct fimd_driver_data exynos4_fimd_driver_data 
>>> = {
>>> .lcdblk_bypass_shift = 1,
>>> .has_shadowcon = 1,
>>> .has_vtsel = 1,
>>> +   .has_bgr_support = 1,
>>>  };
>>>  
>>>  static struct fimd_driver_data exynos5_fimd_driver_data = {
>>> @@ -149,6 +151,7 @@ static struct fimd_driver_data exynos5_fimd_driver_data 
>>> = {
>>> .has_vidoutcon = 1,
>>> .has_vtsel = 1,
>>> .has_dp_clk = 1,
>>> +   .has_bgr_support = 1,
>>>  };
>>>  
>>>  static struct fimd_driver_data exynos5420_fimd_driver_data = {
>>> @@ -162,6 +165,7 @@ static struct fimd_driver_data 
>>> exynos5420_fimd_driver_data = {
>>> .has_vtsel = 1,
>>> .has_mic_bypass = 1,
>>> .has_dp_clk = 1,
>>> +   .has_bgr_support = 1,
>>>  };
>>>  
>>>  struct fimd_context {
>>> @@ -226,6 +230,18 @@ static const uint32_t fimd_formats[] = {
>>> DRM_FORMAT_ARGB,
>>>  };
>>>  
>>> +static const uint32_t fimd_extended_formats[] = {
>>> +   DRM_FORMAT_C8,
>>> +   DRM_FORMAT_XRGB1555,
>>> +   DRM_FORMAT_XBGR1555,
>>> +   DRM_FORMAT_RGB565,
>>> +   DRM_FORMAT_BGR565,
>>> +   DRM_FORMAT_XRGB,
>>> +   DRM_FORMAT_XBGR,
>>> +   DRM_FORMAT_ARGB,
>>> +   DRM_FORMAT_ABGR,
>>> +};
>>> +
>>>  static const unsigned int capabilities[WINDOWS_NR] = {
>>> 0,
>>> EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
>>> @@ -673,21 +689,25 @@ static void fimd_win_set_pixfmt(struct fimd_context 
>>> *ctx, unsigned int win,
>>> val |= WINCONx_BYTSWP;
>>> break;
>>> case DRM_FORMAT_XRGB1555:
>>> +   case DRM_FORMAT_XBGR1555:
>>> val |= WINCON0_BPPMODE_16BPP_1555;
>>> val |= WINCONx_HAWSWP;
>>> val |= WINCONx_BURSTLEN_16WORD;
>>> break;
>>> case DRM_FORMAT_RGB565:
>>> +   case DRM_FORMAT_BGR565:
>>> val |= WINCON0_BPPMODE_16BPP_565;
>>> val |= WINCONx_HAWSWP;
>>> val |= WINCONx_BURSTLEN_16WORD;
>>> break;
>>> case 

[PATCH] drm/mediatek: Fix DPI component detection for MT8192

2022-02-24 Thread Chen-Yu Tsai
When support for MT8192 was added, the DPI device was not added to the
list of components to look for. This causes the secondary display
pipeline to not be able to fully bind, and the DRM driver subsequently
defers probing.

Add the DPI device compatible to list of DPI components to fix this.

Fixes: 01365f549c88 ("drm/mediatek: Add support for Mediatek SoC MT8192")
Signed-off-by: Chen-Yu Tsai 
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index b147797177c6..47ba18cbc5c8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -511,6 +511,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
  .data = (void *)MTK_DPI },
{ .compatible = "mediatek,mt8183-dpi",
  .data = (void *)MTK_DPI },
+   { .compatible = "mediatek,mt8192-dpi",
+ .data = (void *)MTK_DPI },
{ .compatible = "mediatek,mt2701-dsi",
  .data = (void *)MTK_DSI },
{ .compatible = "mediatek,mt8173-dsi",
-- 
2.35.1.574.g5d30c73bfb-goog



[PATCH v12 6/6] drm/i915/gt: replace cache_clflush_range

2022-02-24 Thread Michael Cheng
Replace all occurrence of cache_clflush_range with drm_clflush_virt_range.
This will prevent compile errors on non-x86 platforms.

Signed-off-by: Michael Cheng 
Reviewed-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/gen8_ppgtt.c | 12 ++--
 drivers/gpu/drm/i915/gt/intel_execlists_submission.c |  2 +-
 drivers/gpu/drm/i915/gt/intel_gtt.c  |  2 +-
 drivers/gpu/drm/i915/gt/intel_ppgtt.c|  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c|  2 +-
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c 
b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
index f574da00eff1..c7bd5d71b03e 100644
--- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
@@ -454,11 +454,11 @@ gen8_ppgtt_insert_pte(struct i915_ppgtt *ppgtt,
pd = pdp->entry[gen8_pd_index(idx, 2)];
}
 
-   clflush_cache_range(vaddr, PAGE_SIZE);
+   drm_clflush_virt_range(vaddr, PAGE_SIZE);
vaddr = px_vaddr(i915_pt_entry(pd, gen8_pd_index(idx, 
1)));
}
} while (1);
-   clflush_cache_range(vaddr, PAGE_SIZE);
+   drm_clflush_virt_range(vaddr, PAGE_SIZE);
 
return idx;
 }
@@ -631,7 +631,7 @@ static void gen8_ppgtt_insert_huge(struct 
i915_address_space *vm,
}
} while (rem >= page_size && index < I915_PDES);
 
-   clflush_cache_range(vaddr, PAGE_SIZE);
+   drm_clflush_virt_range(vaddr, PAGE_SIZE);
 
/*
 * Is it safe to mark the 2M block as 64K? -- Either we have
@@ -647,7 +647,7 @@ static void gen8_ppgtt_insert_huge(struct 
i915_address_space *vm,
  I915_GTT_PAGE_SIZE_2M {
vaddr = px_vaddr(pd);
vaddr[maybe_64K] |= GEN8_PDE_IPS_64K;
-   clflush_cache_range(vaddr, PAGE_SIZE);
+   drm_clflush_virt_range(vaddr, PAGE_SIZE);
page_size = I915_GTT_PAGE_SIZE_64K;
 
/*
@@ -668,7 +668,7 @@ static void gen8_ppgtt_insert_huge(struct 
i915_address_space *vm,
for (i = 1; i < index; i += 16)
memset64(vaddr + i, encode, 15);
 
-   clflush_cache_range(vaddr, PAGE_SIZE);
+   drm_clflush_virt_range(vaddr, PAGE_SIZE);
}
}
 
@@ -722,7 +722,7 @@ static void gen8_ppgtt_insert_entry(struct 
i915_address_space *vm,
 
vaddr = px_vaddr(pt);
vaddr[gen8_pd_index(idx, 0)] = gen8_pte_encode(addr, level, flags);
-   clflush_cache_range([gen8_pd_index(idx, 0)], sizeof(*vaddr));
+   drm_clflush_virt_range([gen8_pd_index(idx, 0)], sizeof(*vaddr));
 }
 
 static void __xehpsdv_ppgtt_insert_entry_lm(struct i915_address_space *vm,
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 89aef3ce53f0..d6f02dce45a0 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -2823,7 +2823,7 @@ static void execlists_sanitize(struct intel_engine_cs 
*engine)
sanitize_hwsp(engine);
 
/* And scrub the dirty cachelines for the HWSP */
-   clflush_cache_range(engine->status_page.addr, PAGE_SIZE);
+   drm_clflush_virt_range(engine->status_page.addr, PAGE_SIZE);
 
intel_engine_reset_pinned_contexts(engine);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c 
b/drivers/gpu/drm/i915/gt/intel_gtt.c
index c548c193cd35..fc314946d426 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -268,7 +268,7 @@ fill_page_dma(struct drm_i915_gem_object *p, const u64 val, 
unsigned int count)
void *vaddr = __px_vaddr(p);
 
memset64(vaddr, val, count);
-   clflush_cache_range(vaddr, PAGE_SIZE);
+   drm_clflush_virt_range(vaddr, PAGE_SIZE);
 }
 
 static void poison_scratch_page(struct drm_i915_gem_object *scratch)
diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c 
b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
index d91e2beb7517..d8b94d638559 100644
--- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
@@ -91,7 +91,7 @@ write_dma_entry(struct drm_i915_gem_object * const pdma,
u64 * const vaddr = __px_vaddr(pdma);
 
vaddr[idx] = encoded_entry;
-   clflush_cache_range([idx], sizeof(u64));
+   drm_clflush_virt_range([idx], sizeof(u64));
 }
 
 void
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index b3a429a92c0d..89020706adc4 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ 

[PATCH v12 5/6] drm/i915/: Re-work clflush_write32

2022-02-24 Thread Michael Cheng
Use drm_clflush_virt_range instead of clflushopt and remove the memory
barrier, since drm_clflush_virt_range takes care of that.

v2(Michael Cheng): Use sizeof(*addr) instead of sizeof(addr) to get the
   actual size of the page. Thanks to Matt Roper for
   pointing this out.

Signed-off-by: Michael Cheng 
Reviewed-by: Matt Roper 
---
 drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 89aa0557ade1..0ca6c3d810da 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1333,10 +1333,8 @@ static void *reloc_vaddr(struct i915_vma *vma,
 static void clflush_write32(u32 *addr, u32 value, unsigned int flushes)
 {
if (unlikely(flushes & (CLFLUSH_BEFORE | CLFLUSH_AFTER))) {
-   if (flushes & CLFLUSH_BEFORE) {
-   clflushopt(addr);
-   mb();
-   }
+   if (flushes & CLFLUSH_BEFORE)
+   drm_clflush_virt_range(addr, sizeof(*addr));
 
*addr = value;
 
@@ -1348,7 +1346,7 @@ static void clflush_write32(u32 *addr, u32 value, 
unsigned int flushes)
 * to ensure ordering of clflush wrt to the system.
 */
if (flushes & CLFLUSH_AFTER)
-   clflushopt(addr);
+   drm_clflush_virt_range(addr, sizeof(*addr));
} else
*addr = value;
 }
-- 
2.25.1



[PATCH v12 4/6] drm/i915/gt: Re-work reset_csb

2022-02-24 Thread Michael Cheng
Use drm_clflush_virt_range instead of directly invoking clflush. This
will prevent compiler errors when building for non-x86 architectures.

v2(Michael Cheng): Remove extra clflush

v3(Michael Cheng): Remove memory barrier since drm_clflush_virt_range
   takes care of it.

v4(Michael Cheng): Get the size of value and not the size of the pointer
   when passing in execlists->csb_write. Thanks to Matt
   Roper for pointing this out.

Signed-off-by: Michael Cheng 
Reviewed-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_execlists_submission.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index e5e73a1b2e4e..89aef3ce53f0 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -2945,9 +2945,8 @@ reset_csb(struct intel_engine_cs *engine, struct 
i915_request **inactive)
 {
struct intel_engine_execlists * const execlists = >execlists;
 
-   mb(); /* paranoia: read the CSB pointers from after the reset */
-   clflush(execlists->csb_write);
-   mb();
+   drm_clflush_virt_range(execlists->csb_write,
+  sizeof(execlists->csb_write[0]));
 
inactive = process_csb(engine, inactive); /* drain preemption events */
 
-- 
2.25.1



[PATCH v12 0/6] Use drm_clflush* instead of clflush

2022-02-24 Thread Michael Cheng
This patch series re-work a few i915 functions to use drm_clflush_virt_range
instead of calling clflush or clflushopt directly. This will prevent errors
when building for non-x86 architectures.

v2: s/PAGE_SIZE/sizeof(value) for Re-work intel_write_status_page and added
more patches to convert additional clflush/clflushopt to use drm_clflush*.
(Michael Cheng)

v3: Drop invalidate_csb_entries and directly invoke drm_clflush_virt_ran

v4: Remove extra memory barriers

v5: s/cache_clflush_range/drm_clflush_virt_range

v6: Fix up "Drop invalidate_csb_entries" to use correct parameters. Also
added in arm64 support for drm_clflush_virt_range.

v7: Re-order patches, and use correct macro for dcache flush for arm64.

v8: Remove ifdef for asm/cacheflush.

v9: Rebased

v10: Replaced asm/cacheflush with linux/cacheflush

v11: Correctly get the sizeof certian addresses. Also rebased to the latest.

v12: Drop include of cacheflush.h and use caches_clean_inval_pou instead of
dcache_clean_inval_poc, since it is not exported for other modules to use.

Michael Cheng (6):
  drm: Add arch arm64 for drm_clflush_virt_range
  drm/i915/gt: Re-work intel_write_status_page
  drm/i915/gt: Drop invalidate_csb_entries
  drm/i915/gt: Re-work reset_csb
  drm/i915/: Re-work clflush_write32
  drm/i915/gt: replace cache_clflush_range

 drivers/gpu/drm/drm_cache.c   |  5 +
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|  8 +++-
 drivers/gpu/drm/i915/gt/gen8_ppgtt.c  | 12 +--
 drivers/gpu/drm/i915/gt/intel_engine.h| 13 
 .../drm/i915/gt/intel_execlists_submission.c  | 20 +++
 drivers/gpu/drm/i915/gt/intel_gtt.c   |  2 +-
 drivers/gpu/drm/i915/gt/intel_ppgtt.c |  2 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  2 +-
 8 files changed, 28 insertions(+), 36 deletions(-)

-- 
2.25.1



[PATCH v12 3/6] drm/i915/gt: Drop invalidate_csb_entries

2022-02-24 Thread Michael Cheng
Drop invalidate_csb_entries and directly call drm_clflush_virt_range.
This allows for one less function call, and prevent complier errors when
building for non-x86 architectures.

v2(Michael Cheng): Drop invalidate_csb_entries function and directly
   invoke drm_clflush_virt_range. Thanks to Tvrtko for the
   sugguestion.

v3(Michael Cheng): Use correct parameters for drm_clflush_virt_range.
   Thanks to Tvrtko for pointing this out.

v4(Michael Cheng): Simplify >csb_status[0] to
   execlists->csb_status. Thanks to Matt Roper for the
   suggestion.

Signed-off-by: Michael Cheng 
Reviewed-by: Matt Roper 
---
 .../gpu/drm/i915/gt/intel_execlists_submission.c| 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 961d795220a3..e5e73a1b2e4e 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -1646,12 +1646,6 @@ cancel_port_requests(struct intel_engine_execlists * 
const execlists,
return inactive;
 }
 
-static void invalidate_csb_entries(const u64 *first, const u64 *last)
-{
-   clflush((void *)first);
-   clflush((void *)last);
-}
-
 /*
  * Starting with Gen12, the status has a new format:
  *
@@ -1999,7 +1993,7 @@ process_csb(struct intel_engine_cs *engine, struct 
i915_request **inactive)
 * the wash as hardware, working or not, will need to do the
 * invalidation before.
 */
-   invalidate_csb_entries([0], [num_entries - 1]);
+   drm_clflush_virt_range([0], num_entries * sizeof(buf[0]));
 
/*
 * We assume that any event reflects a change in context flow
@@ -2783,8 +2777,9 @@ static void reset_csb_pointers(struct intel_engine_cs 
*engine)
 
/* Check that the GPU does indeed update the CSB entries! */
memset(execlists->csb_status, -1, (reset_value + 1) * sizeof(u64));
-   invalidate_csb_entries(>csb_status[0],
-  >csb_status[reset_value]);
+   drm_clflush_virt_range(execlists->csb_status,
+  execlists->csb_size *
+  sizeof(execlists->csb_status));
 
/* Once more for luck and our trusty paranoia */
ENGINE_WRITE(engine, RING_CONTEXT_STATUS_PTR,
-- 
2.25.1



[PATCH v12 1/6] drm: Add arch arm64 for drm_clflush_virt_range

2022-02-24 Thread Michael Cheng
Add arm64 support for drm_clflush_virt_range. caches_clean_inval_pou
performs a flush by first performing a clean, follow by an invalidation
operation.

v2 (Michael Cheng): Use correct macro for cleaning and invalidation the
dcache. Thanks Tvrtko for the suggestion.

v3 (Michael Cheng): Replace asm/cacheflush.h with linux/cacheflush.h

v4 (Michael Cheng): Arm64 does not export dcache_clean_inval_poc as a
symbol that could be use by other modules, thus use
caches_clean_inval_pou instead. Also this version
removes include for cacheflush, since its already
included base on architecture type.

Signed-off-by: Michael Cheng 
Reviewed-by: Matt Roper 
---
 drivers/gpu/drm/drm_cache.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index c3e6e615bf09..81c28714f930 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -174,6 +174,11 @@ drm_clflush_virt_range(void *addr, unsigned long length)
 
if (wbinvd_on_all_cpus())
pr_err("Timed out waiting for cache flush\n");
+
+#elif defined(CONFIG_ARM64)
+   void *end = addr + length;
+   caches_clean_inval_pou((unsigned long)addr, (unsigned long)end);
+
 #else
WARN_ONCE(1, "Architecture has no drm_cache.c support\n");
 #endif
-- 
2.25.1



[PATCH v12 2/6] drm/i915/gt: Re-work intel_write_status_page

2022-02-24 Thread Michael Cheng
Re-work intel_write_status_page to use drm_clflush_virt_range. This
will prevent compiler errors when building for non-x86 architectures.

Signed-off-by: Michael Cheng 
Reviewed-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_engine.h | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h 
b/drivers/gpu/drm/i915/gt/intel_engine.h
index be4b1e65442f..818468e0a02e 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -4,6 +4,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -143,15 +144,9 @@ intel_write_status_page(struct intel_engine_cs *engine, 
int reg, u32 value)
 * of extra paranoia to try and ensure that the HWS takes the value
 * we give and that it doesn't end up trapped inside the CPU!
 */
-   if (static_cpu_has(X86_FEATURE_CLFLUSH)) {
-   mb();
-   clflush(>status_page.addr[reg]);
-   engine->status_page.addr[reg] = value;
-   clflush(>status_page.addr[reg]);
-   mb();
-   } else {
-   WRITE_ONCE(engine->status_page.addr[reg], value);
-   }
+   drm_clflush_virt_range(>status_page.addr[reg], sizeof(value));
+   WRITE_ONCE(engine->status_page.addr[reg], value);
+   drm_clflush_virt_range(>status_page.addr[reg], sizeof(value));
 }
 
 /*
-- 
2.25.1



Re: [RFC v4 02/11] drm/amdgpu: Move scheduler init to after XGMI is ready

2022-02-24 Thread JingWen Chen
Hi Andrey,

Sorry for the misleading, I mean the whole patch series. We are depending on 
this patch series to fix the concurrency issue within SRIOV TDR sequence.



On 2/25/22 1:26 AM, Andrey Grodzovsky wrote:
> No problem if so but before I do,
>
>
> JingWen - why you think this patch is needed as a standalone now ? It has no 
> use without the
> entire feature together with it. Is it some changes you want to do on top of 
> that code ?
>
>
> Andrey
>
>
> On 2022-02-24 12:12, Deucher, Alexander wrote:
>>
>> [Public]
>>
>>
>> If it applies cleanly, feel free to drop it in.  I'll drop those patches for 
>> drm-next since they are already in drm-misc.
>>
>> Alex
>>
>> 
>> *From:* amd-gfx  on behalf of Andrey 
>> Grodzovsky 
>> *Sent:* Thursday, February 24, 2022 11:24 AM
>> *To:* Chen, JingWen ; Christian König 
>> ; dri-devel@lists.freedesktop.org 
>> ; amd-...@lists.freedesktop.org 
>> 
>> *Cc:* Liu, Monk ; Chen, Horace ; 
>> Lazar, Lijo ; Koenig, Christian 
>> ; dan...@ffwll.ch 
>> *Subject:* Re: [RFC v4 02/11] drm/amdgpu: Move scheduler init to after XGMI 
>> is ready
>> No because all the patch-set including this patch was landed into
>> drm-misc-next and will reach amd-staging-drm-next on the next upstream
>> rebase i guess.
>>
>> Andrey
>>
>> On 2022-02-24 01:47, JingWen Chen wrote:
>> > Hi Andrey,
>> >
>> > Will you port this patch into amd-staging-drm-next?
>> >
>> > on 2/10/22 2:06 AM, Andrey Grodzovsky wrote:
>> >> All comments are fixed and code pushed. Thanks for everyone
>> >> who helped reviewing.
>> >>
>> >> Andrey
>> >>
>> >> On 2022-02-09 02:53, Christian König wrote:
>> >>> Am 09.02.22 um 01:23 schrieb Andrey Grodzovsky:
>>  Before we initialize schedulers we must know which reset
>>  domain are we in - for single device there iis a single
>>  domain per device and so single wq per device. For XGMI
>>  the reset domain spans the entire XGMI hive and so the
>>  reset wq is per hive.
>> 
>>  Signed-off-by: Andrey Grodzovsky 
>> >>> One more comment below, with that fixed Reviewed-by: Christian König 
>> >>> .
>> >>>
>>  ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 45 ++
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c  | 34 ++--
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h   |  2 +
>>     3 files changed, 51 insertions(+), 30 deletions(-)
>> 
>>  diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
>>  b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>  index 9704b0e1fd82..00123b0013d3 100644
>>  --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>  +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>  @@ -2287,6 +2287,47 @@ static int amdgpu_device_fw_loading(struct 
>>  amdgpu_device *adev)
>>     return r;
>>     }
>>     +static int amdgpu_device_init_schedulers(struct amdgpu_device *adev)
>>  +{
>>  +    long timeout;
>>  +    int r, i;
>>  +
>>  +    for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
>>  +    struct amdgpu_ring *ring = adev->rings[i];
>>  +
>>  +    /* No need to setup the GPU scheduler for rings that don't 
>>  need it */
>>  +    if (!ring || ring->no_scheduler)
>>  +    continue;
>>  +
>>  +    switch (ring->funcs->type) {
>>  +    case AMDGPU_RING_TYPE_GFX:
>>  +    timeout = adev->gfx_timeout;
>>  +    break;
>>  +    case AMDGPU_RING_TYPE_COMPUTE:
>>  +    timeout = adev->compute_timeout;
>>  +    break;
>>  +    case AMDGPU_RING_TYPE_SDMA:
>>  +    timeout = adev->sdma_timeout;
>>  +    break;
>>  +    default:
>>  +    timeout = adev->video_timeout;
>>  +    break;
>>  +    }
>>  +
>>  +    r = drm_sched_init(>sched, _sched_ops,
>>  + ring->num_hw_submission, amdgpu_job_hang_limit,
>>  +   timeout, adev->reset_domain.wq, ring->sched_score, 
>>  ring->name);
>>  +    if (r) {
>>  +    DRM_ERROR("Failed to create scheduler on ring %s.\n",
>>  +  ring->name);
>>  +    return r;
>>  +    }
>>  +    }
>>  +
>>  +    return 0;
>>  +}
>>  +
>>  +
>>     /**
>>      * amdgpu_device_ip_init - run init for hardware IPs
>>      *
>>  @@ -2419,6 +2460,10 @@ static int amdgpu_device_ip_init(struct 
>>  amdgpu_device *adev)
>>     }
>>     }
>>     +    r = amdgpu_device_init_schedulers(adev);
>>  +    if (r)
>>  +    goto init_failed;
>>  +
>>     /* Don't init kfd if whole hive need to be reset during init */
>>     if (!adev->gmc.xgmi.pending_reset)
>>  amdgpu_amdkfd_device_init(adev);
>>  diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
>>  

Re: [PATCH] drm/imx: dw_hdmi-imx: Fix bailout in error cases of probe

2022-02-24 Thread Liu Ying
Hi Philipp,

On Fri, 2022-01-28 at 17:19 +0800, Liu Ying wrote:
> In dw_hdmi_imx_probe(), if error happens after dw_hdmi_probe() returns
> successfully, dw_hdmi_remove() should be called where necessary as
> bailout.
> 
> Fixes: c805ec7eb210 ("drm/imx: dw_hdmi-imx: move initialization into probe")
> Cc: Philipp Zabel 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Cc: Shawn Guo 
> Cc: Sascha Hauer 
> Cc: Pengutronix Kernel Team 
> Cc: Fabio Estevam 
> Cc: NXP Linux Team 
> Signed-off-by: Liu Ying 

Any comments?  Can you please pick this up?

Regards,
Liu Ying

> ---
>  drivers/gpu/drm/imx/dw_hdmi-imx.c | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
> b/drivers/gpu/drm/imx/dw_hdmi-imx.c
> index 87428fb23d9f..a2277a0d6d06 100644
> --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
> +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
> @@ -222,6 +222,7 @@ static int dw_hdmi_imx_probe(struct platform_device *pdev)
>   struct device_node *np = pdev->dev.of_node;
>   const struct of_device_id *match = of_match_node(dw_hdmi_imx_dt_ids, 
> np);
>   struct imx_hdmi *hdmi;
> + int ret;
>  
>   hdmi = devm_kzalloc(>dev, sizeof(*hdmi), GFP_KERNEL);
>   if (!hdmi)
> @@ -243,10 +244,15 @@ static int dw_hdmi_imx_probe(struct platform_device 
> *pdev)
>   hdmi->bridge = of_drm_find_bridge(np);
>   if (!hdmi->bridge) {
>   dev_err(hdmi->dev, "Unable to find bridge\n");
> + dw_hdmi_remove(hdmi->hdmi);
>   return -ENODEV;
>   }
>  
> - return component_add(>dev, _hdmi_imx_ops);
> + ret = component_add(>dev, _hdmi_imx_ops);
> + if (ret)
> + dw_hdmi_remove(hdmi->hdmi);
> +
> + return ret;
>  }
>  
>  static int dw_hdmi_imx_remove(struct platform_device *pdev)



[PATCH] drm/i915/guc: Add fetch of hwconfig table

2022-02-24 Thread John . C . Harrison
From: John Harrison 

Implement support for fetching the hardware description table from the
GuC. The call is made twice - once without a destination buffer to
query the size and then a second time to fill in the buffer.

The table is stored in the GT structure so that it can be fetched once
at driver load time. Keeping inside a GuC structure would mean it
would be release and reloaded on a GuC reset (part of a full GT
reset). However, the table does not change just because the GT has been
reset and the GuC reloaded. Also, dynamic memory allocations inside
the reset path are a problem.

Note that the table is only available on ADL-P and later platforms.

v2: Move to GT level to avoid memory allocation during reset path (and
unnecessary re-read of the table on a reset).

Cc: Michal Wajdeczko 
Signed-off-by: Rodrigo Vivi 
Signed-off-by: John Harrison 
Reviewed-by: Matthew Brost  (v1)

Mush: hwconf
---
 drivers/gpu/drm/i915/Makefile |   1 +
 drivers/gpu/drm/i915/gt/intel_gt.c|   6 +
 drivers/gpu/drm/i915/gt/intel_gt_types.h  |   4 +
 drivers/gpu/drm/i915/gt/intel_hwconfig.h  |  21 +++
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |   1 +
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |   4 +
 .../gpu/drm/i915/gt/uc/intel_guc_hwconfig.c   | 160 ++
 7 files changed, 197 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/gt/intel_hwconfig.h
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 713f59a88312..8da4a1fe8b36 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -193,6 +193,7 @@ i915-y += gt/uc/intel_uc.o \
  gt/uc/intel_guc_rc.o \
  gt/uc/intel_guc_slpc.o \
  gt/uc/intel_guc_submission.o \
+ gt/uc/intel_guc_hwconfig.o \
  gt/uc/intel_huc.o \
  gt/uc/intel_huc_debugfs.o \
  gt/uc/intel_huc_fw.o
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index e6f6bf7c3926..2ad55d7ffe53 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -711,6 +711,11 @@ int intel_gt_init(struct intel_gt *gt)
if (err)
goto err_uc_init;
 
+   /* Table failure is bad but not currently fatal */
+   err = intel_gt_init_hwconfig(gt);
+   if (err)
+   drm_err(>i915->drm, "Failed to retrieve hwconfig table: 
%d\n", err);
+
err = __engines_record_defaults(gt);
if (err)
goto err_gt;
@@ -792,6 +797,7 @@ void intel_gt_driver_release(struct intel_gt *gt)
intel_gt_pm_fini(gt);
intel_gt_fini_scratch(gt);
intel_gt_fini_buffer_pool(gt);
+   intel_gt_fini_hwconfig(gt);
 }
 
 void intel_gt_driver_late_release(struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h 
b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index f20687796490..514b92cff9b0 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -20,6 +20,7 @@
 #include "i915_vma.h"
 #include "intel_engine_types.h"
 #include "intel_gt_buffer_pool_types.h"
+#include "intel_hwconfig.h"
 #include "intel_llc_types.h"
 #include "intel_reset_types.h"
 #include "intel_rc6_types.h"
@@ -199,6 +200,9 @@ struct intel_gt {
struct sseu_dev_info sseu;
 
unsigned long mslice_mask;
+
+   /** @hwconfig: hardware configuration data */
+   struct intel_hwconfig hwconfig;
} info;
 
struct {
diff --git a/drivers/gpu/drm/i915/gt/intel_hwconfig.h 
b/drivers/gpu/drm/i915/gt/intel_hwconfig.h
new file mode 100644
index ..322290780b67
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_hwconfig.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef _INTEL_HWCONFIG_H_
+#define _INTEL_HWCONFIG_H_
+
+#include 
+
+struct intel_gt;
+
+struct intel_hwconfig {
+   u32 size;
+   void *ptr;
+};
+
+int intel_gt_init_hwconfig(struct intel_gt *gt);
+void intel_gt_fini_hwconfig(struct intel_gt *gt);
+
+#endif /* _INTEL_HWCONFIG_H_ */
diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h 
b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
index 7afdadc7656f..a9a329e53c35 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
@@ -129,6 +129,7 @@ enum intel_guc_action {
INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION = 0x1009,
INTEL_GUC_ACTION_SETUP_PC_GUCRC = 0x3004,
INTEL_GUC_ACTION_AUTHENTICATE_HUC = 0x4000,
+   INTEL_GUC_ACTION_GET_HWCONFIG = 0x4100,
INTEL_GUC_ACTION_REGISTER_CONTEXT = 0x4502,
INTEL_GUC_ACTION_DEREGISTER_CONTEXT = 0x4503,
INTEL_GUC_ACTION_REGISTER_COMMAND_TRANSPORT_BUFFER = 0x4505,
diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h 

Re: [PATCH v5 1/4] drm/i915/guc: Add fetch of hwconfig table

2022-02-24 Thread John Harrison

On 2/22/2022 02:36, Jordan Justen wrote:

From: John Harrison 

Implement support for fetching the hardware description table from the
GuC. The call is made twice - once without a destination buffer to
query the size and then a second time to fill in the buffer.

Note that the table is only available on ADL-P and later platforms.

v5 (of Jordan's posting):
  * Various changes made by Jordan and recommended by Michal
- Makefile ordering
- Adjust "struct intel_guc_hwconfig hwconfig" comment
- Set Copyright year to 2022 in intel_guc_hwconfig.c/.h
- Drop inline from hwconfig_to_guc()
- Replace hwconfig param with guc in __guc_action_get_hwconfig()
- Move zero size check into guc_hwconfig_discover_size()
- Change comment to say zero size offset/size is needed to get size
- Add has_guc_hwconfig to devinfo and drop has_table()
- Change drm_err to notice in __uc_init_hw() and use %pe

Cc: Michal Wajdeczko 
Signed-off-by: Rodrigo Vivi 
Signed-off-by: John Harrison 
Reviewed-by: Matthew Brost 
Acked-by: Jon Bloomfield 
Signed-off-by: Jordan Justen 
---
  drivers/gpu/drm/i915/Makefile |   1 +
  .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |   1 +
  .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |   4 +
  drivers/gpu/drm/i915/gt/uc/intel_guc.h|   3 +
  .../gpu/drm/i915/gt/uc/intel_guc_hwconfig.c   | 145 ++
  .../gpu/drm/i915/gt/uc/intel_guc_hwconfig.h   |  19 +++
  drivers/gpu/drm/i915/gt/uc/intel_uc.c |   7 +
  drivers/gpu/drm/i915/i915_pci.c   |   1 +
  drivers/gpu/drm/i915/intel_device_info.h  |   1 +
  9 files changed, 182 insertions(+)
  create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c
  create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index e9ce09620eb5..661f1afb51d7 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -188,6 +188,7 @@ i915-y += gt/uc/intel_uc.o \
  gt/uc/intel_guc_ct.o \
  gt/uc/intel_guc_debugfs.o \
  gt/uc/intel_guc_fw.o \
+ gt/uc/intel_guc_hwconfig.o \
  gt/uc/intel_guc_log.o \
  gt/uc/intel_guc_log_debugfs.o \
  gt/uc/intel_guc_rc.o \
diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h 
b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
index fe5d7d261797..4a61c819f32b 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
@@ -137,6 +137,7 @@ enum intel_guc_action {
INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION = 0x1009,
INTEL_GUC_ACTION_SETUP_PC_GUCRC = 0x3004,
INTEL_GUC_ACTION_AUTHENTICATE_HUC = 0x4000,
+   INTEL_GUC_ACTION_GET_HWCONFIG = 0x4100,
INTEL_GUC_ACTION_REGISTER_CONTEXT = 0x4502,
INTEL_GUC_ACTION_DEREGISTER_CONTEXT = 0x4503,
INTEL_GUC_ACTION_REGISTER_COMMAND_TRANSPORT_BUFFER = 0x4505,
diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h 
b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
index 488b6061ee89..f9e2a6aaef4a 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
@@ -8,6 +8,10 @@
  
  enum intel_guc_response_status {

INTEL_GUC_RESPONSE_STATUS_SUCCESS = 0x0,
+   INTEL_GUC_RESPONSE_NOT_SUPPORTED = 0x20,
+   INTEL_GUC_RESPONSE_NO_ATTRIBUTE_TABLE = 0x201,
+   INTEL_GUC_RESPONSE_NO_DECRYPTION_KEY = 0x202,
+   INTEL_GUC_RESPONSE_DECRYPTION_FAILED = 0x204,
INTEL_GUC_RESPONSE_STATUS_GENERIC_FAIL = 0xF000,
  };
  
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h

index f9240d4baa69..2058eb8c3d0c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -13,6 +13,7 @@
  #include "intel_guc_fw.h"
  #include "intel_guc_fwif.h"
  #include "intel_guc_ct.h"
+#include "intel_guc_hwconfig.h"
  #include "intel_guc_log.h"
  #include "intel_guc_reg.h"
  #include "intel_guc_slpc_types.h"
@@ -37,6 +38,8 @@ struct intel_guc {
struct intel_guc_ct ct;
/** @slpc: sub-structure containing SLPC related data and objects */
struct intel_guc_slpc slpc;
+   /** @hwconfig: data related to hardware configuration KLV blob */
+   struct intel_guc_hwconfig hwconfig;
  
  	/** @sched_engine: Global engine used to submit requests to GuC */

struct i915_sched_engine *sched_engine;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c
new file mode 100644
index ..ad289603460c
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_hwconfig.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#include "gt/intel_gt.h"
+#include "i915_drv.h"
+#include "i915_memcpy.h"
+#include "intel_guc_hwconfig.h"
+
+static struct intel_guc *hwconfig_to_guc(struct 

Re: [Freedreno] [RFC PATCH v2 1/5] drm/msm/dp: fix panel bridge attachment

2022-02-24 Thread Abhinav Kumar




On 2/24/2022 12:41 PM, Dmitry Baryshkov wrote:

On Thu, 24 Feb 2022 at 21:25, Abhinav Kumar  wrote:




On 2/18/2022 6:26 PM, Dmitry Baryshkov wrote:

On 19/02/2022 02:56, Stephen Boyd wrote:

Quoting Dmitry Baryshkov (2022-02-11 14:40:02)

In commit 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
enable and disable") the DP driver received a drm_bridge instance, which
is always attached to the encoder as a root bridge. However it conflicts
with the panel_bridge support for eDP panels. The panel bridge attaches
to the encoder before the "dp" bridge has a chace to do so. Change


s/chace/chance/


panel_bridge attachment to come after dp_bridge attachment.


s/panel_bridge/panel bridge/ possibly? And maybe clarify that dp_bridge
is the "DP driver's drm_bridge instance created in
msm_dp_bridge_init()"?

My understanding is that we want to pass the bridge created in
msm_dp_bridge_init() as the 'previous' bridge so that it attaches the
panel bridge to the output of the DP bridge that's attached to the
encoder.


Thanks! I'll update the commit log when pushing the patches.


Please correct if i am missing something here.

You are right that the eDP panel's panel bridge attaches to the encoder
in dp_drm_connector_init() which happens before msm_dp_bridge_init() and
hence it will attach directly to the encoder.

But we are talking about different encoders here. DP's dp_display has a
different encoder compared to the EDP's dp_display.


The encoders are different. However both encoders use the same
codepath, which includes dp_bridge. It controls dp_display by calling
msm_dp_display_foo() functions.


So DP's bridge will still be attached to its encoder's root.


There is one dp_bridge per each encoder. Consider sc8180x which has 3
DP controllers (and thus 3 dp_bridges).



Sorry, but I still didnt follow this.

So for eDP, dp_drm_connector_init() will attach the panel_bridge
and then msm_dp_bridge_init() will add a drm_bridge.

And yes in that case, the drm_bridge will be after the panel_bridge

But since panel_bridge is at the root for eDP it should be okay.

Your commit text was mentioning about DP.

For DP, for each controller in the catalog, we will call modeset_init() 
which should skip this part for DP


  if (dp_display->panel_bridge) {
ret = drm_bridge_attach(dp_display->encoder,
dp_display->panel_bridge, NULL,
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (ret < 0) {
DRM_ERROR("failed to attach panel bridge: %d\n", ret);
return ERR_PTR(ret);
}
}

Followed by calling msm_dp_bridge_init() which will actually attach the 
bridge:


drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);

Now, even for 3 DP controllers, this shall be true as there will be 3 
separate encoders and 3 dp_displays and hence 3 drm_bridges.


What am i missing here?



So what are we achieving with this change?







Fixes: 8a3b4c17f863 ("drm/msm/dp: employ bridge mechanism for display
enable and disable")
Cc: Kuogee Hsieh 
Signed-off-by: Dmitry Baryshkov 
---


Reviewed-by: Stephen Boyd 


   drivers/gpu/drm/msm/dp/dp_drm.c | 21 +++--
   1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
b/drivers/gpu/drm/msm/dp/dp_drm.c
index d4d360d19eba..26ef41a4c1b6 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -169,16 +169,6 @@ struct drm_connector
*dp_drm_connector_init(struct msm_dp *dp_display)

  drm_connector_attach_encoder(connector, dp_display->encoder);

-   if (dp_display->panel_bridge) {
-   ret = drm_bridge_attach(dp_display->encoder,
-   dp_display->panel_bridge, NULL,
-   DRM_BRIDGE_ATTACH_NO_CONNECTOR);
-   if (ret < 0) {
-   DRM_ERROR("failed to attach panel bridge:
%d\n", ret);
-   return ERR_PTR(ret);
-   }
-   }
-
  return connector;
   }

@@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct
msm_dp *dp_display, struct drm_devi
  return ERR_PTR(rc);
  }

+   if (dp_display->panel_bridge) {
+   rc = drm_bridge_attach(dp_display->encoder,
+   dp_display->panel_bridge,
bridge,
+   DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+   if (rc < 0) {
+   DRM_ERROR("failed to attach panel bridge:
%d\n", rc);
+   drm_bridge_remove(bridge);
+   return ERR_PTR(rc);
+   }
+   }
+
  return bridge;


Not a problem with this patch, but what is this pointer used for? I see
it's assigned to priv->bridges and num_bridges is incremented but nobody
seems to look at that.



That's on my todo list. to remove connectors array and to destroy
created bridges 

[PATCH v3] drm/i915/guc: Do not complain about stale reset notifications

2022-02-24 Thread John . C . Harrison
From: John Harrison 

It is possible for reset notifications to arrive for a context that is
in the process of being banned. So don't flag these as an error, just
report it as informational (because it is still useful to know that
resets are happening even if they are being ignored).

v2: Better wording for the message (review feedback from Tvrtko).
v3: Fix rebase issue (review feedback from Daniele).

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index b3a429a92c0d..d39d74d39794 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4022,10 +4022,9 @@ static void guc_handle_context_reset(struct intel_guc 
*guc,
capture_error_state(guc, ce);
guc_context_replay(ce);
} else {
-   drm_err(_to_gt(guc)->i915->drm,
-   "Invalid GuC engine reset notificaion for 0x%04X on %s: 
banned = %d, blocked = %d",
-   ce->guc_id.id, ce->engine->name, 
intel_context_is_banned(ce),
-   context_blocked(ce));
+   drm_info(_to_gt(guc)->i915->drm,
+"Ignoring context reset notification of banned context 
0x%04X on %s",
+ce->guc_id.id, ce->engine->name);
}
 }
 
-- 
2.25.1



[GIT PULL] exynos-drm-fixes for rc6

2022-02-24 Thread Inki Dae
Hi Dave and Daniel,

   Just fixups series.

   Ps. my previous git-pull request[1] isn't merged so I'm sending it again
   after rebasing on top of drm-fixes.

   Please kindly let me know if there is any problem.

Thanks,
Inki Dae

[1] https://www.spinics.net/lists/dri-devel/msg333237.html

The following changes since commit ecf8a99f4807c17fa310a83067a95964cedd9ac1:

  Merge tag 'drm-intel-fixes-2022-02-24' of 
git://anongit.freedesktop.org/drm/drm-intel into drm-fixes (2022-02-25 05:51:04 
+1000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos 
tags/exynos-drm-fixes-v5.17-rc6

for you to fetch changes up to 4188db23285e28d9e9b9096f856cdcd7868005ee:

  drm/exynos: Search for TE-gpio in DSI panel's node (2022-02-25 09:50:48 +0900)


Fixups
- Make display controller drivers for Exynos series to use
  platform_get_irq and platform_get_irq_byname functions
  to get the interrupt, which prevents irq chaning from messed up
  when using hierarchical interrupt domains which use "interrupts"
  property in the node.
- Fix two regressions to TE-gpio handling.


Lad Prabhakar (5):
  drm/exynos/exynos7_drm_decon: Use platform_get_irq_byname() to get the 
interrupt
  drm/exynos: mixer: Use platform_get_irq() to get the interrupt
  drm/exynos/exynos_drm_fimd: Use platform_get_irq_byname() to get the 
interrupt
  drm/exynos/fimc: Use platform_get_irq() to get the interrupt
  drm/exynos: gsc: Use platform_get_irq() to get the interrupt

Marek Szyprowski (2):
  drm/exynos: Don't fail if no TE-gpio is defined for DSI driver
  drm/exynos: Search for TE-gpio in DSI panel's node

 drivers/gpu/drm/exynos/exynos7_drm_decon.c | 12 +++-
 drivers/gpu/drm/exynos/exynos_drm_dsi.c|  6 --
 drivers/gpu/drm/exynos/exynos_drm_fimc.c   | 13 +
 drivers/gpu/drm/exynos/exynos_drm_fimd.c   | 13 -
 drivers/gpu/drm/exynos/exynos_drm_gsc.c| 10 +++---
 drivers/gpu/drm/exynos/exynos_mixer.c  | 14 ++
 6 files changed, 25 insertions(+), 43 deletions(-)


Re: [git pull] drm fixes for 5.17-rc6

2022-02-24 Thread pr-tracker-bot
The pull request you sent on Fri, 25 Feb 2022 09:01:30 +1000:

> git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2022-02-25

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/5ee3d0015a4cec798b44ceefc34245752104fc08

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


[PATCH v6 1/2] drm/vrr: Set VRR capable prop only if it is attached to connector

2022-02-24 Thread Manasi Navare
VRR capable property is not attached by default to the connector
It is attached only if VRR is supported.
So if the driver tries to call drm core set prop function without
it being attached that causes NULL dereference.

Cc: Jani Nikula 
Cc: Ville Syrjälä 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Manasi Navare 
---
 drivers/gpu/drm/drm_connector.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index a50c82bc2b2f..76a8c707c34b 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2330,6 +2330,9 @@ EXPORT_SYMBOL(drm_connector_atomic_hdr_metadata_equal);
 void drm_connector_set_vrr_capable_property(
struct drm_connector *connector, bool capable)
 {
+   if (!connector->vrr_capable_property)
+   return;
+
drm_object_property_set_value(>base,
  connector->vrr_capable_property,
  capable);
-- 
2.19.1



Re: [PATCH v5 3/7] PCI: Drop the `is_thunderbolt` attribute from PCI core

2022-02-24 Thread Bjorn Helgaas
On Thu, Feb 24, 2022 at 07:23:49PM -0600, Bjorn Helgaas wrote:
> On Thu, Feb 24, 2022 at 03:51:12PM -0600, Mario Limonciello wrote:
> > The `is_thunderbolt` attribute originally had a well defined list of
> > quirks that it existed for, but it has been overloaded with more
> > meaning.
> > 
> > Instead use the driver core removable attribute to indicate the
> > detail a device is attached to a thunderbolt or USB4 chain.
> ...

> If these things are not specifically related to Thunderbolt, I'd
> prefer to get rid of pci_is_thunderbolt_attached() and see if we can
> help the GPU folks figure out what they really need.

Ah.  Guess I should read the whole series before commenting :)  I see
that you *did* remove pci_is_thunderbolt_attached() in the last patch.
I'll look more at the rest tomorrow.

Bjorn


Re: [PATCH v5 3/7] PCI: Drop the `is_thunderbolt` attribute from PCI core

2022-02-24 Thread Bjorn Helgaas
On Thu, Feb 24, 2022 at 03:51:12PM -0600, Mario Limonciello wrote:
> The `is_thunderbolt` attribute originally had a well defined list of
> quirks that it existed for, but it has been overloaded with more
> meaning.
> 
> Instead use the driver core removable attribute to indicate the
> detail a device is attached to a thunderbolt or USB4 chain.
> 
> Signed-off-by: Mario Limonciello 
> ---
>  drivers/pci/probe.c   | 2 +-
>  drivers/platform/x86/apple-gmux.c | 2 +-
>  include/linux/pci.h   | 5 ++---
>  3 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 17a969942d37..1b752d425c47 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1584,7 +1584,7 @@ static void set_pcie_thunderbolt(struct pci_dev *dev)
>   /* Is the device part of a Thunderbolt controller? */
>   vsec = pci_find_vsec_capability(dev, PCI_VENDOR_ID_INTEL, 
> PCI_VSEC_ID_INTEL_TBT);
>   if (vsec)
> - dev->is_thunderbolt = 1;
> + dev->external_facing = true;

I assume there's a spec for the PCI_VSEC_ID_INTEL_TBT Capability.  Is
that public?  Does the spec say that a device with that capability
must be external-facing?

Even if it's not public, I think a citation (name, revision, section)
would be useful.

>  }
>  
>  static void set_pcie_untrusted(struct pci_dev *dev)
> diff --git a/drivers/platform/x86/apple-gmux.c 
> b/drivers/platform/x86/apple-gmux.c
> index 57553f9b4d1d..da0c39b0 100644
> --- a/drivers/platform/x86/apple-gmux.c
> +++ b/drivers/platform/x86/apple-gmux.c
> @@ -596,7 +596,7 @@ static int gmux_resume(struct device *dev)
>  
>  static int is_thunderbolt(struct device *dev, void *data)
>  {
> - return to_pci_dev(dev)->is_thunderbolt;
> + return to_pci_dev(dev)->external_facing;

This looks ... sort of weird.  I don't know anything about
apple-gmux.c, so I guess I don't care, but assuming any
external-facing device must be a Thunderbolt device seems like a
stretch.

Ugh.  This is used via "bus_for_each_dev(_bus_type)", which means
it's not hotplug-safe.  I'm sure we "know" implicitly that hotplug
isn't an issue in apple-gmux, but it's better not to have examples
that get copied to places where it *is* an issue.

>  }
>  
>  static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 1e5b769e42fc..d9719eb14654 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -442,7 +442,6 @@ struct pci_dev {
>   unsigned intis_virtfn:1;
>   unsigned intis_hotplug_bridge:1;
>   unsigned intshpc_managed:1; /* SHPC owned by shpchp */
> - unsigned intis_thunderbolt:1;   /* Thunderbolt controller */
>   unsigned intno_cmd_complete:1;  /* Lies about command completed 
> events */
>  
>   /*
> @@ -2447,11 +2446,11 @@ static inline bool pci_is_thunderbolt_attached(struct 
> pci_dev *pdev)
>  {
>   struct pci_dev *parent = pdev;
>  
> - if (pdev->is_thunderbolt)
> + if (dev_is_removable(>dev))
>   return true;
>  
>   while ((parent = pci_upstream_bridge(parent)))
> - if (parent->is_thunderbolt)
> + if (dev_is_removable(>dev))
>   return true;

I don't get this.  Plain old PCI devices can be removable, too.

pci_is_thunderbolt_attached() is only used by GPU drivers.  What
property of Thunderbolt do they care about?

nouveau_vga_init() and radeon_device_init() use it to decide to
register with vga_switcheroo.  So maybe that's something to do with
removability?  Of course, that's not specific to Thunderbolt, because
garden-variety PCIe devices are removable.

amdgpu_driver_load_kms() and radeon_driver_load_kms() apparently use
it for something related to power control.  I don't know what the
Thunderbolt connection is.

nbio_v2_3_enable_aspm() looks like it uses it to change some ASPM
parameters.  Seems like potentially a device erratum or quirk
material?

If these things are not specifically related to Thunderbolt, I'd
prefer to get rid of pci_is_thunderbolt_attached() and see if we can
help the GPU folks figure out what they really need.

>   return false;
> -- 
> 2.34.1
> 


Re: [PATCH v4 9/9] drm: vkms: Add support to the RGB565 format

2022-02-24 Thread Igor Torrente
Hi Pekka,

On Thu, Feb 10, 2022 at 6:50 AM Pekka Paalanen  wrote:

> On Fri, 21 Jan 2022 18:38:31 -0300
> Igor Torrente  wrote:
>
> > Adds this common format to vkms.
> >
> > This commit also adds new helper macros to deal with fixed-point
> > arithmetic.
> >
> > It was done to improve the precision of the conversion to ARGB16161616
> > since the "conversion ratio" is not an integer.
> >
> > Signed-off-by: Igor Torrente 
> > ---
> > V3: Adapt the handlers to the new format introduced in patch 7 V3.
> > ---
> >  drivers/gpu/drm/vkms/vkms_formats.c   | 74 +++
> >  drivers/gpu/drm/vkms/vkms_formats.h   |  6 +++
> >  drivers/gpu/drm/vkms/vkms_plane.c |  6 ++-
> >  drivers/gpu/drm/vkms/vkms_writeback.c |  3 +-
> >  4 files changed, 86 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/vkms/vkms_formats.c
> b/drivers/gpu/drm/vkms/vkms_formats.c
> > index 661da39d1276..dc612882dd8c 100644
> > --- a/drivers/gpu/drm/vkms/vkms_formats.c
> > +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> > @@ -11,6 +11,8 @@ format_transform_func get_fmt_transform_function(u32
> format)
> >   return _ARGB16161616;
> >   else if (format == DRM_FORMAT_XRGB16161616)
> >   return _to_ARGB16161616;
> > + else if (format == DRM_FORMAT_RGB565)
> > + return _to_ARGB16161616;
> >   else
> >   return _to_ARGB16161616;
> >  }
> > @@ -23,6 +25,8 @@ format_transform_func
> get_wb_fmt_transform_function(u32 format)
> >   return _to_ARGB16161616;
> >   else if (format == DRM_FORMAT_XRGB16161616)
> >   return _to_XRGB16161616;
> > + else if (format == DRM_FORMAT_RGB565)
> > + return _to_RGB565;
> >   else
> >   return _to_XRGB;
> >  }
> > @@ -33,6 +37,26 @@ static int pixel_offset(struct vkms_frame_info
> *frame_info, int x, int y)
> > + (x * frame_info->cpp);
> >  }
> >
> > +/*
> > + * FP stands for _Fixed Point_ and **not** _Float Point_
>
> Is it common in the kernel that FP always means fixed-point?
>

I cannot say for sure, but I don't think so. I put it for people like me
that goes automatically to Floating-Point because never worked with
fixed-point before.


>
> If there is any doubt about that, I'd suggest using "fixed" and "float"
> to avoid misunderstandings.
>
> And, since you are not supposed to use floats in the kernel unless you
> really really must and you do all the preparations necessary (which you
> don't here), maybe replace the "float" with a fraction.
>
> In other words, write a macro that takes (65535, 31) as arguments
> instead of a float, when converting to fixed-point. Then you don't have
> to use those strange decimal constants either.
>

It looks better, I will try to implement this.


> > + * LF stands for Long Float (i.e. double)
> > + * The following macros help doing fixed point arithmetic.
> > + */
> > +/*
> > + * With FP scale 15 we have 17 and 15 bits of integer and fractional
> parts
> > + * respectively.
> > + *  |     0.000    |
> > + * 31  0
> > + */
> > +#define FP_SCALE 15
> > +
> > +#define LF_TO_FP(a) ((a) * (u64)(1 << FP_SCALE))
> > +#define INT_TO_FP(a) ((a) << FP_SCALE)
> > +#define FP_MUL(a, b) ((s32)(((s64)(a) * (b)) >> FP_SCALE))
> > +#define FP_DIV(a, b) ((s32)(((s64)(a) << FP_SCALE) / (b)))
> > +/* This macro converts a fixed point number to int, and round half up
> it */
> > +#define FP_TO_INT_ROUND_UP(a) (((a) + (1 << (FP_SCALE - 1))) >>
> FP_SCALE)
> > +
> >  /*
> >   * packed_pixels_addr - Get the pointer to pixel of a given pair of
> coordinates
> >   *
> > @@ -125,6 +149,33 @@ void XRGB16161616_to_ARGB16161616(struct
> vkms_frame_info *frame_info, int y,
> >   }
> >  }
> >
> > +void RGB565_to_ARGB16161616(struct vkms_frame_info *frame_info, int y,
> > + struct line_buffer *stage_buffer)
> > +{
> > + u16 *src_pixels = get_packed_src_addr(frame_info, y);
> > + int x, x_limit = drm_rect_width(_info->dst);
> > +
> > + for (x = 0; x < x_limit; x++, src_pixels++) {
> > + u16 rgb_565 = le16_to_cpu(*src_pixels);
> > + int fp_r = INT_TO_FP((rgb_565 >> 11) & 0x1f);
> > + int fp_g = INT_TO_FP((rgb_565 >> 5) & 0x3f);
> > + int fp_b = INT_TO_FP(rgb_565 & 0x1f);
> > +
> > + /*
> > +  * The magic constants is the "conversion ratio" and is
> calculated
> > +  * dividing 65535(2^16 - 1) by 31(2^5 -1) and 63(2^6 - 1)
> > +  * respectively.
> > +  */
> > + int fp_rb_ratio = LF_TO_FP(2114.032258065);
> > + int fp_g_ratio = LF_TO_FP(1040.238095238);
> > +
> > + stage_buffer[x].a = (u16)0x;
> > + stage_buffer[x].r = FP_TO_INT_ROUND_UP(FP_MUL(fp_r,
> fp_rb_ratio));
> > + stage_buffer[x].g = FP_TO_INT_ROUND_UP(FP_MUL(fp_g,
> fp_g_ratio));
> > +  

Re: [PATCH] drm/msm: Avoid dirtyfb stalls on video mode displays (v2)

2022-02-24 Thread Dmitry Baryshkov
On Wed, 23 Feb 2022 at 22:11, Rob Clark  wrote:
>
> From: Rob Clark 
>
> Someone on IRC once asked an innocent enough sounding question:  Why
> with xf86-video-modesetting is es2gears limited at 120fps.
>
> So I broke out the perfetto tracing mesa MR and took a look.  It turns
> out the problem was drm_atomic_helper_dirtyfb(), which would end up
> waiting for vblank.. es2gears would rapidly push two frames to Xorg,
> which would blit them to screen and in idle hook (I assume) call the
> DIRTYFB ioctl.  Which in turn would do an atomic update to flush the
> dirty rects, which would stall until the next vblank.  And then the
> whole process would repeat.
>
> But this is a bit silly, we only need dirtyfb for command mode DSI
> panels.  So track in plane state whether dirtyfb is required, and
> track in the fb how many attached planes require dirtyfb so that we
> can skip it when not required.  (Note, mdp4 does not actually have
> cmd mode support.)
>
> Signed-off-by: Rob Clark 

I like the way it ended up being implemented. A really nice hack!

Reviewed-by: Dmitry Baryshkov 

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   | 20 ++-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c  |  5 +--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h  |  3 ++
>  drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c | 19 --
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c  |  8 +
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h   |  5 +++
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 21 +--
>  drivers/gpu/drm/msm/msm_atomic.c   | 15 
>  drivers/gpu/drm/msm/msm_drv.h  |  6 ++--
>  drivers/gpu/drm/msm/msm_fb.c   | 41 ++
>  10 files changed, 110 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 662b7bc9c219..7763558ef566 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1046,6 +1046,20 @@ struct plane_state {
> u32 pipe_id;
>  };
>
> +static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
> +{
> +   struct drm_crtc *crtc = cstate->crtc;
> +   struct drm_encoder *encoder;
> +
> +   drm_for_each_encoder_mask (encoder, crtc->dev, cstate->encoder_mask) {
> +   if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_CMD) {
> +   return true;
> +   }
> +   }
> +
> +   return false;
> +}
> +
>  static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
> struct drm_atomic_state *state)
>  {
> @@ -1066,6 +1080,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
> const struct drm_plane_state *pipe_staged[SSPP_MAX];
> int left_zpos_cnt = 0, right_zpos_cnt = 0;
> struct drm_rect crtc_rect = { 0 };
> +   bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
>
> pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
>
> @@ -1097,6 +1112,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>
>  /* get plane state for all drm planes associated with crtc state */
> drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) 
> {
> +   struct dpu_plane_state *dpu_pstate = 
> to_dpu_plane_state(pstate);
> struct drm_rect dst, clip = crtc_rect;
>
> if (IS_ERR_OR_NULL(pstate)) {
> @@ -1108,11 +1124,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
> if (cnt >= DPU_STAGE_MAX * 4)
> continue;
>
> -   pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
> +   pstates[cnt].dpu_pstate = dpu_pstate;
> pstates[cnt].drm_pstate = pstate;
> pstates[cnt].stage = pstate->normalized_zpos;
> pstates[cnt].pipe_id = dpu_plane_pipe(plane);
>
> +   dpu_pstate->needs_dirtyfb = needs_dirtyfb;
> +
> if (pipe_staged[pstates[cnt].pipe_id]) {
> multirect_plane[multirect_count].r0 =
> pipe_staged[pstates[cnt].pipe_id];
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index ca75089c9d61..6565682fe227 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -902,7 +902,7 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane,
>
> if (pstate->aspace) {
> ret = msm_framebuffer_prepare(new_state->fb,
> -   pstate->aspace);
> +   pstate->aspace, pstate->needs_dirtyfb);
> if (ret) {
> DPU_ERROR("failed to prepare framebuffer\n");
> return ret;
> @@ -933,7 +933,8 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
>
> DPU_DEBUG_PLANE(pdpu, "FB[%u]\n", 

Re: [PATCH v4 7/9] drm: vkms: Refactor the plane composer to accept new formats

2022-02-24 Thread Igor Torrente
Hi Pekka,

On 2/10/22 06:37, Pekka Paalanen wrote:
> On Fri, 21 Jan 2022 18:38:29 -0300
> Igor Torrente  wrote:
>
>> Currently the blend function only accepts XRGB_ and ARGB_
>> as a color input.
>>
>> This patch refactors all the functions related to the plane composition
>> to overcome this limitation.
>>
>> A new internal format(`struct pixel`) is introduced to deal with all
>> possible inputs. It consists of 16 bits fields that represent each of
>> the channels.
>>
>> The pixels blend is done using this internal format. And new handlers
>> are being added to convert a specific format to/from this internal format.
>>
>> So the blend operation depends on these handlers to convert to this common
>> format. The blended result, if necessary, is converted to the writeback
>> buffer format.
>>
>> This patch introduces three major differences to the blend function.
>> 1 - All the planes are blended at once.
>> 2 - The blend calculus is done as per line instead of per pixel.
>> 3 - It is responsible to calculates the CRC and writing the writeback
>>  buffer(if necessary).
>>
>> These changes allow us to allocate way less memory in the intermediate
>> buffer to compute these operations. Because now we don't need to
>> have the entire intermediate image lines at once, just one line is
>> enough.
>>
>> | Memory consumption (output dimensions) |
>> |:--:|
>> |   Current  | This patch|
>> |:--:|:-:|
>> |   Width * Heigth   | 2 * Width |
>>
>> Beyond memory, we also have a minor performance benefit from all
>> these changes. Results running the IGT tests `*kms_cursor_crc*`:
>>
>> | Frametime  |
>> |:--:|
>> |  Implementation |  Current  |  This commit |
>> |:---:|:-:|::|
>> | frametime range |  8~22 ms  |5~18 ms   |
>> | Average |  10.0 ms  |7.3 ms|
>>
>> Reported-by: kernel test robot 
>> Signed-off-by: Igor Torrente 
>> ---
>> V2: Improves the performance drastically, by perfoming the operations
>>  per-line and not per-pixel(Pekka Paalanen).
>>  Minor improvements(Pekka Paalanen).
>>
>> V3: Changes the code to blend the planes all at once. This improves
>>  performance, memory consumption, and removes much of the weirdness
>>  of the V2(Pekka Paalanen and me).
>>  Minor improvements(Pekka Paalanen and me).
>>
>> V4: Rebase the code and adapt it to the new NUM_OVERLAY_PLANES constant.
>> ---
>>   drivers/gpu/drm/vkms/Makefile|   1 +
>>   drivers/gpu/drm/vkms/vkms_composer.c | 335 +--
>>   drivers/gpu/drm/vkms/vkms_formats.c  | 138 +++
>>   drivers/gpu/drm/vkms/vkms_formats.h  |  31 +++
>>   4 files changed, 333 insertions(+), 172 deletions(-)
>>   create mode 100644 drivers/gpu/drm/vkms/vkms_formats.c
>>   create mode 100644 drivers/gpu/drm/vkms/vkms_formats.h
>
> Hi Igor,
>
> I'm really happy to see this, thanks!
>
> I still have some security/robustness and other comments below.
>
> I've deleted all the minus lines from the patch to make the new code
> more clear.
>
>>
>> diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
>> index 72f779cbfedd..1b28a6a32948 100644
>> --- a/drivers/gpu/drm/vkms/Makefile
>> +++ b/drivers/gpu/drm/vkms/Makefile
>> @@ -3,6 +3,7 @@ vkms-y := \
>>  vkms_drv.o \
>>  vkms_plane.o \
>>  vkms_output.o \
>> +vkms_formats.o \
>>  vkms_crtc.o \
>>  vkms_composer.o \
>>  vkms_writeback.o
>> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
>> b/drivers/gpu/drm/vkms/vkms_composer.c
>> index 95029d2ebcac..9f70fcf84fb9 100644
>> --- a/drivers/gpu/drm/vkms/vkms_composer.c
>> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
>> @@ -9,202 +9,210 @@
>>   #include 
>>
>>   #include "vkms_drv.h"
>> +#include "vkms_formats.h"
>>
>> +static u16 pre_mul_blend_channel(u16 src, u16 dst, u16 alpha)
>>   {
>> +u32 new_color;
>>
>> +new_color = (src * 0x + dst * (0x - alpha));
>>
>> +return DIV_ROUND_UP(new_color, 0x);
>
> Why round-up rather than the usual mathematical rounding?

AFAIK, this is the only round that's present in the kernel. And if I
understood correctly it is the round toward positive infinity that we are
all used to use.

>
>>   }
>>
>>   /**
>> + * pre_mul_alpha_blend - alpha blending equation
>> + * @src_frame_info: source framebuffer's metadata
>> + * @stage_buffer: The line with the pixels from src_plane
>> + * @output_buffer: A line buffer that receives all the blends output
>>*
>> + * Using the information from the `frame_info`, this blends only the
>> + * necessary pixels from the `stage_buffer` to the `output_buffer`
>> + * using premultiplied blend formula.
>>*
>> + * The current DRM assumption is that pixel color values have been already
>> + * pre-multiplied with the alpha channel values. See more
>> + * 

[PATCH v2 1/8] drm/i915/guc: Do not conflate lrc_desc with GuC id for registration

2022-02-24 Thread John . C . Harrison
From: John Harrison 

The LRC descriptor pool is going away. So, stop using it as a check for
context registration, use the GuC id instead (being the thing that
actually gets registered with the GuC).

Also, rename the set/clear/query helper functions for context id
mappings to better reflect their purpose and to differentiate from
other registration related helper functions.

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 69 ++-
 1 file changed, 38 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index b3a429a92c0d..7fb889e14995 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -514,31 +514,20 @@ static inline bool guc_submission_initialized(struct 
intel_guc *guc)
return !!guc->lrc_desc_pool_vaddr;
 }
 
-static inline void reset_lrc_desc(struct intel_guc *guc, u32 id)
+static inline void _reset_lrc_desc(struct intel_guc *guc, u32 id)
 {
-   if (likely(guc_submission_initialized(guc))) {
-   struct guc_lrc_desc *desc = __get_lrc_desc(guc, id);
-   unsigned long flags;
-
-   memset(desc, 0, sizeof(*desc));
+   struct guc_lrc_desc *desc = __get_lrc_desc(guc, id);
 
-   /*
-* xarray API doesn't have xa_erase_irqsave wrapper, so calling
-* the lower level functions directly.
-*/
-   xa_lock_irqsave(>context_lookup, flags);
-   __xa_erase(>context_lookup, id);
-   xa_unlock_irqrestore(>context_lookup, flags);
-   }
+   memset(desc, 0, sizeof(*desc));
 }
 
-static inline bool lrc_desc_registered(struct intel_guc *guc, u32 id)
+static inline bool ctx_id_mapped(struct intel_guc *guc, u32 id)
 {
return __get_context(guc, id);
 }
 
-static inline void set_lrc_desc_registered(struct intel_guc *guc, u32 id,
-  struct intel_context *ce)
+static inline void set_ctx_id_mapping(struct intel_guc *guc, u32 id,
+ struct intel_context *ce)
 {
unsigned long flags;
 
@@ -551,6 +540,24 @@ static inline void set_lrc_desc_registered(struct 
intel_guc *guc, u32 id,
xa_unlock_irqrestore(>context_lookup, flags);
 }
 
+static inline void clr_ctx_id_mapping(struct intel_guc *guc, u32 id)
+{
+   unsigned long flags;
+
+   if (unlikely(!guc_submission_initialized(guc)))
+   return;
+
+   _reset_lrc_desc(guc, id);
+
+   /*
+* xarray API doesn't have xa_erase_irqsave wrapper, so calling
+* the lower level functions directly.
+*/
+   xa_lock_irqsave(>context_lookup, flags);
+   __xa_erase(>context_lookup, id);
+   xa_unlock_irqrestore(>context_lookup, flags);
+}
+
 static void decr_outstanding_submission_g2h(struct intel_guc *guc)
 {
if (atomic_dec_and_test(>outstanding_submission_g2h))
@@ -795,7 +802,7 @@ static int __guc_wq_item_append(struct i915_request *rq)
GEM_BUG_ON(!atomic_read(>guc_id.ref));
GEM_BUG_ON(context_guc_id_invalid(ce));
GEM_BUG_ON(context_wait_for_deregister_to_register(ce));
-   GEM_BUG_ON(!lrc_desc_registered(ce_to_guc(ce), ce->guc_id.id));
+   GEM_BUG_ON(!ctx_id_mapped(ce_to_guc(ce), ce->guc_id.id));
 
/* Insert NOOP if this work queue item will wrap the tail pointer. */
if (wqi_size > wq_space_until_wrap(ce)) {
@@ -923,7 +930,7 @@ static int guc_dequeue_one_context(struct intel_guc *guc)
if (submit) {
struct intel_context *ce = request_to_scheduling_context(last);
 
-   if (unlikely(!lrc_desc_registered(guc, ce->guc_id.id) &&
+   if (unlikely(!ctx_id_mapped(guc, ce->guc_id.id) &&
 !intel_context_is_banned(ce))) {
ret = guc_lrc_desc_pin(ce, false);
if (unlikely(ret == -EPIPE)) {
@@ -1897,7 +1904,7 @@ static bool need_tasklet(struct intel_guc *guc, struct 
i915_request *rq)
 
return submission_disabled(guc) || guc->stalled_request ||
!i915_sched_engine_is_empty(sched_engine) ||
-   !lrc_desc_registered(guc, ce->guc_id.id);
+   !ctx_id_mapped(guc, ce->guc_id.id);
 }
 
 static void guc_submit_request(struct i915_request *rq)
@@ -1954,7 +1961,7 @@ static void __release_guc_id(struct intel_guc *guc, 
struct intel_context *ce)
else
ida_simple_remove(>submission_state.guc_ids,
  ce->guc_id.id);
-   reset_lrc_desc(guc, ce->guc_id.id);
+   clr_ctx_id_mapping(guc, ce->guc_id.id);
set_context_guc_id_invalid(ce);
}
if (!list_empty(>guc_id.link))
@@ -2250,10 +2257,10 @@ static int 

[PATCH v2 5/8] drm/i915/guc: Move lrc desc setup to where it is needed

2022-02-24 Thread John . C . Harrison
From: John Harrison 

The LRC descriptor was being initialised early on in the context
registration sequence. It could then be determined that the actual
registration needs to be delayed and the descriptor would be wiped
out. This is inefficient, so move the setup to later in the process
after the point of no return.

v2: Move some split changes into the split patch (and do them
correctly).

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index e41e309b9e7e..d9e1cd3e1db2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2153,6 +2153,8 @@ static int __guc_action_register_context(struct intel_guc 
*guc,
 0, loop);
 }
 
+static void prepare_context_registration_info(struct intel_context *ce);
+
 static int register_context(struct intel_context *ce, bool loop)
 {
struct intel_guc *guc = ce_to_guc(ce);
@@ -2163,6 +2165,8 @@ static int register_context(struct intel_context *ce, 
bool loop)
GEM_BUG_ON(intel_context_is_child(ce));
trace_intel_context_register(ce);
 
+   prepare_context_registration_info(ce);
+
if (intel_context_is_parent(ce))
ret = __guc_action_register_multi_lrc(guc, ce, ce->guc_id.id,
  offset, loop);
@@ -2317,8 +2321,6 @@ static int try_context_registration(struct intel_context 
*ce, bool loop)
clr_ctx_id_mapping(guc, desc_idx);
set_ctx_id_mapping(guc, desc_idx, ce);
 
-   prepare_context_registration_info(ce);
-
/*
 * The context_lookup xarray is used to determine if the hardware
 * context is currently registered. There are two cases in which it
-- 
2.25.1



[PATCH v2 8/8] drm/i915/guc: Fix potential invalid pointer dereferences when decoding G2Hs

2022-02-24 Thread John . C . Harrison
From: John Harrison 

Some G2H handlers were reading the context id field from the payload
before checking the payload met the minimum length required.

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 53114097a5b9..820f6e870505 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -3891,12 +3891,13 @@ int intel_guc_deregister_done_process_msg(struct 
intel_guc *guc,
  u32 len)
 {
struct intel_context *ce;
-   u32 ctx_id = msg[0];
+   u32 ctx_id;
 
if (unlikely(len < 1)) {
drm_err(_to_gt(guc)->i915->drm, "Invalid length %u\n", len);
return -EPROTO;
}
+   ctx_id = msg[0];
 
ce = g2h_context_lookup(guc, ctx_id);
if (unlikely(!ce))
@@ -3942,12 +3943,13 @@ int intel_guc_sched_done_process_msg(struct intel_guc 
*guc,
 {
struct intel_context *ce;
unsigned long flags;
-   u32 ctx_id = msg[0];
+   u32 ctx_id;
 
if (unlikely(len < 2)) {
drm_err(_to_gt(guc)->i915->drm, "Invalid length %u\n", len);
return -EPROTO;
}
+   ctx_id = msg[0];
 
ce = g2h_context_lookup(guc, ctx_id);
if (unlikely(!ce))
-- 
2.25.1



[PATCH v2 2/8] drm/i915/guc: Add an explicit 'submission_initialized' flag

2022-02-24 Thread John . C . Harrison
From: John Harrison 

The LRC descriptor pool is going away. So, stop using it as a check
for whether submission has been initialised or not.

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h| 2 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 8 +---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 9d779de16613..568eb6352ef0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -137,6 +137,8 @@ struct intel_guc {
bool submission_supported;
/** @submission_selected: tracks whether the user enabled GuC 
submission */
bool submission_selected;
+   /** @submission_initialized: tracks whether GuC submission has been 
initialised */
+   bool submission_initialized;
/**
 * @rc_supported: tracks whether we support GuC rc on the current 
platform
 */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 7fb889e14995..11bf56b5a266 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -511,7 +511,7 @@ static void guc_lrc_desc_pool_destroy(struct intel_guc *guc)
 
 static inline bool guc_submission_initialized(struct intel_guc *guc)
 {
-   return !!guc->lrc_desc_pool_vaddr;
+   return guc->submission_initialized;
 }
 
 static inline void _reset_lrc_desc(struct intel_guc *guc, u32 id)
@@ -1813,7 +1813,7 @@ int intel_guc_submission_init(struct intel_guc *guc)
struct intel_gt *gt = guc_to_gt(guc);
int ret;
 
-   if (guc->lrc_desc_pool)
+   if (guc->submission_initialized)
return 0;
 
ret = guc_lrc_desc_pool_create(guc);
@@ -1845,19 +1845,21 @@ int intel_guc_submission_init(struct intel_guc *guc)
INIT_DELAYED_WORK(>timestamp.work, guc_timestamp_ping);
guc->timestamp.ping_delay = (POLL_TIME_CLKS / gt->clock_frequency + 1) 
* HZ;
guc->timestamp.shift = gpm_timestamp_shift(gt);
+   guc->submission_initialized = true;
 
return 0;
 }
 
 void intel_guc_submission_fini(struct intel_guc *guc)
 {
-   if (!guc->lrc_desc_pool)
+   if (!guc->submission_initialized)
return;
 
guc_flush_destroyed_contexts(guc);
guc_lrc_desc_pool_destroy(guc);
i915_sched_engine_put(guc->sched_engine);
bitmap_free(guc->submission_state.guc_ids_bitmap);
+   guc->submission_initialized = false;
 }
 
 static inline void queue_request(struct i915_sched_engine *sched_engine,
-- 
2.25.1



[PATCH v2 3/8] drm/i915/guc: Better name for context id limit

2022-02-24 Thread John . C . Harrison
From: John Harrison 

The LRC descriptor pool is going away. So, stop using it as the limit
for how many context ids are available. Instead, size the pool
according to the number of contexts allowed. Note that this is just a
naming change, the actual limit is identical in value.

While at it, also update a kzalloc(sizeof()*count) to be a
kcalloc(count,size).

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/intel_context.c  |  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h  |  4 ++--
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c| 16 
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c|  2 +-
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 5d0ec7c49b6a..d87145b8fca0 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -400,7 +400,7 @@ intel_context_init(struct intel_context *ce, struct 
intel_engine_cs *engine)
INIT_LIST_HEAD(>guc_state.fences);
INIT_LIST_HEAD(>guc_state.requests);
 
-   ce->guc_id.id = GUC_INVALID_LRC_ID;
+   ce->guc_id.id = GUC_INVALID_CONTEXT_ID;
INIT_LIST_HEAD(>guc_id.link);
 
INIT_LIST_HEAD(>destroyed_link);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
index 6a4612a852e2..11099f0320ce 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -32,8 +32,8 @@
 #define GUC_CLIENT_PRIORITY_NORMAL 3
 #define GUC_CLIENT_PRIORITY_NUM4
 
-#define GUC_MAX_LRC_DESCRIPTORS65535
-#defineGUC_INVALID_LRC_ID  GUC_MAX_LRC_DESCRIPTORS
+#define GUC_MAX_CONTEXT_ID 65535
+#defineGUC_INVALID_CONTEXT_ID  GUC_MAX_CONTEXT_ID
 
 #define GUC_RENDER_ENGINE  0
 #define GUC_VIDEO_ENGINE   1
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 11bf56b5a266..ad784e8068c7 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -354,12 +354,12 @@ request_to_scheduling_context(struct i915_request *rq)
 
 static inline bool context_guc_id_invalid(struct intel_context *ce)
 {
-   return ce->guc_id.id == GUC_INVALID_LRC_ID;
+   return ce->guc_id.id == GUC_INVALID_CONTEXT_ID;
 }
 
 static inline void set_context_guc_id_invalid(struct intel_context *ce)
 {
-   ce->guc_id.id = GUC_INVALID_LRC_ID;
+   ce->guc_id.id = GUC_INVALID_CONTEXT_ID;
 }
 
 static inline struct intel_guc *ce_to_guc(struct intel_context *ce)
@@ -474,7 +474,7 @@ static struct guc_lrc_desc *__get_lrc_desc(struct intel_guc 
*guc, u32 index)
 {
struct guc_lrc_desc *base = guc->lrc_desc_pool_vaddr;
 
-   GEM_BUG_ON(index >= GUC_MAX_LRC_DESCRIPTORS);
+   GEM_BUG_ON(index >= GUC_MAX_CONTEXT_ID);
 
return [index];
 }
@@ -483,7 +483,7 @@ static inline struct intel_context *__get_context(struct 
intel_guc *guc, u32 id)
 {
struct intel_context *ce = xa_load(>context_lookup, id);
 
-   GEM_BUG_ON(id >= GUC_MAX_LRC_DESCRIPTORS);
+   GEM_BUG_ON(id >= GUC_MAX_CONTEXT_ID);
 
return ce;
 }
@@ -494,7 +494,7 @@ static int guc_lrc_desc_pool_create(struct intel_guc *guc)
int ret;
 
size = PAGE_ALIGN(sizeof(struct guc_lrc_desc) *
- GUC_MAX_LRC_DESCRIPTORS);
+ GUC_MAX_CONTEXT_ID);
ret = intel_guc_allocate_and_map_vma(guc, size, >lrc_desc_pool,
 (void 
**)>lrc_desc_pool_vaddr);
if (ret)
@@ -2441,7 +2441,7 @@ static void __guc_context_sched_disable(struct intel_guc 
*guc,
GUC_CONTEXT_DISABLE
};
 
-   GEM_BUG_ON(guc_id == GUC_INVALID_LRC_ID);
+   GEM_BUG_ON(guc_id == GUC_INVALID_CONTEXT_ID);
 
GEM_BUG_ON(intel_context_is_child(ce));
trace_intel_context_sched_disable(ce);
@@ -3840,7 +3840,7 @@ static bool __guc_submission_selected(struct intel_guc 
*guc)
 
 void intel_guc_submission_init_early(struct intel_guc *guc)
 {
-   guc->submission_state.num_guc_ids = GUC_MAX_LRC_DESCRIPTORS;
+   guc->submission_state.num_guc_ids = GUC_MAX_CONTEXT_ID;
guc->submission_supported = __guc_submission_supported(guc);
guc->submission_selected = __guc_submission_selected(guc);
 }
@@ -3850,7 +3850,7 @@ g2h_context_lookup(struct intel_guc *guc, u32 desc_idx)
 {
struct intel_context *ce;
 
-   if (unlikely(desc_idx >= GUC_MAX_LRC_DESCRIPTORS)) {
+   if (unlikely(desc_idx >= GUC_MAX_CONTEXT_ID)) {
drm_err(_to_gt(guc)->i915->drm,
"Invalid desc_idx %u", desc_idx);
return NULL;
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c 

[PATCH v2 7/8] drm/i915/guc: Drop obsolete H2G definitions

2022-02-24 Thread John . C . Harrison
From: John Harrison 

The CTB registration process changed significantly a while back using
a single KLV based H2G. So drop the original and now obsolete H2G
definitions.

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h 
b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
index 7afdadc7656f..e77f955435ce 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
@@ -131,8 +131,6 @@ enum intel_guc_action {
INTEL_GUC_ACTION_AUTHENTICATE_HUC = 0x4000,
INTEL_GUC_ACTION_REGISTER_CONTEXT = 0x4502,
INTEL_GUC_ACTION_DEREGISTER_CONTEXT = 0x4503,
-   INTEL_GUC_ACTION_REGISTER_COMMAND_TRANSPORT_BUFFER = 0x4505,
-   INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER = 0x4506,
INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600,
INTEL_GUC_ACTION_REGISTER_CONTEXT_MULTI_LRC = 0x4601,
INTEL_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,
-- 
2.25.1



[PATCH v2 6/8] drm/i915/guc: Rename desc_idx to ctx_id

2022-02-24 Thread John . C . Harrison
From: John Harrison 

The LRC descriptor pool is going away. So, stop naming context ids as
descriptor pool indecies.

While at it, add a bunch of missing line feeds to some error messages.

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 52 +--
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index d9e1cd3e1db2..53114097a5b9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2245,7 +2245,7 @@ static void prepare_context_registration_info(struct 
intel_context *ce)
 {
struct intel_engine_cs *engine = ce->engine;
struct intel_guc *guc = >gt->uc.guc;
-   u32 desc_idx = ce->guc_id.id;
+   u32 ctx_id = ce->guc_id.id;
struct guc_lrc_desc *desc;
struct intel_context *child;
 
@@ -2258,7 +2258,7 @@ static void prepare_context_registration_info(struct 
intel_context *ce)
GEM_BUG_ON(i915_gem_object_is_lmem(guc->ct.vma->obj) !=
   i915_gem_object_is_lmem(ce->ring->vma->obj));
 
-   desc = __get_lrc_desc(guc, desc_idx);
+   desc = __get_lrc_desc(guc, ctx_id);
desc->engine_class = engine_class_to_guc_class(engine->class);
desc->engine_submit_mask = engine->logical_mask;
desc->hw_context_desc = ce->lrc.lrca;
@@ -2310,16 +2310,16 @@ static int try_context_registration(struct 
intel_context *ce, bool loop)
struct intel_runtime_pm *runtime_pm = engine->uncore->rpm;
struct intel_guc *guc = >gt->uc.guc;
intel_wakeref_t wakeref;
-   u32 desc_idx = ce->guc_id.id;
+   u32 ctx_id = ce->guc_id.id;
bool context_registered;
int ret = 0;
 
GEM_BUG_ON(!sched_state_is_init(ce));
 
-   context_registered = ctx_id_mapped(guc, desc_idx);
+   context_registered = ctx_id_mapped(guc, ctx_id);
 
-   clr_ctx_id_mapping(guc, desc_idx);
-   set_ctx_id_mapping(guc, desc_idx, ce);
+   clr_ctx_id_mapping(guc, ctx_id);
+   set_ctx_id_mapping(guc, ctx_id, ce);
 
/*
 * The context_lookup xarray is used to determine if the hardware
@@ -2345,7 +2345,7 @@ static int try_context_registration(struct intel_context 
*ce, bool loop)
}
spin_unlock_irqrestore(>guc_state.lock, flags);
if (unlikely(disabled)) {
-   clr_ctx_id_mapping(guc, desc_idx);
+   clr_ctx_id_mapping(guc, ctx_id);
return 0;   /* Will get registered later */
}
 
@@ -2361,9 +2361,9 @@ static int try_context_registration(struct intel_context 
*ce, bool loop)
with_intel_runtime_pm(runtime_pm, wakeref)
ret = register_context(ce, loop);
if (unlikely(ret == -EBUSY)) {
-   clr_ctx_id_mapping(guc, desc_idx);
+   clr_ctx_id_mapping(guc, ctx_id);
} else if (unlikely(ret == -ENODEV)) {
-   clr_ctx_id_mapping(guc, desc_idx);
+   clr_ctx_id_mapping(guc, ctx_id);
ret = 0;/* Will get registered later */
}
}
@@ -3860,26 +3860,26 @@ void intel_guc_submission_init_early(struct intel_guc 
*guc)
 }
 
 static inline struct intel_context *
-g2h_context_lookup(struct intel_guc *guc, u32 desc_idx)
+g2h_context_lookup(struct intel_guc *guc, u32 ctx_id)
 {
struct intel_context *ce;
 
-   if (unlikely(desc_idx >= GUC_MAX_CONTEXT_ID)) {
+   if (unlikely(ctx_id >= GUC_MAX_CONTEXT_ID)) {
drm_err(_to_gt(guc)->i915->drm,
-   "Invalid desc_idx %u", desc_idx);
+   "Invalid ctx_id %u\n", ctx_id);
return NULL;
}
 
-   ce = __get_context(guc, desc_idx);
+   ce = __get_context(guc, ctx_id);
if (unlikely(!ce)) {
drm_err(_to_gt(guc)->i915->drm,
-   "Context is NULL, desc_idx %u", desc_idx);
+   "Context is NULL, ctx_id %u\n", ctx_id);
return NULL;
}
 
if (unlikely(intel_context_is_child(ce))) {
drm_err(_to_gt(guc)->i915->drm,
-   "Context is child, desc_idx %u", desc_idx);
+   "Context is child, ctx_id %u\n", ctx_id);
return NULL;
}
 
@@ -3891,14 +3891,14 @@ int intel_guc_deregister_done_process_msg(struct 
intel_guc *guc,
  u32 len)
 {
struct intel_context *ce;
-   u32 desc_idx = msg[0];
+   u32 ctx_id = msg[0];
 
if (unlikely(len < 1)) {
-   drm_err(_to_gt(guc)->i915->drm, "Invalid length %u", len);
+   drm_err(_to_gt(guc)->i915->drm, "Invalid length %u\n", len);

[PATCH v2 4/8] drm/i915/guc: Split guc_lrc_desc_pin apart

2022-02-24 Thread John . C . Harrison
From: John Harrison 

The LRC descriptor pool is going away. Further, the function that was
populating it was also doing a bunch of logic about the context
registration sequence. So, split that code apart into separate state
setup and try to register functions. Note that some of those 'try to
register' code paths actually undo the state setup and leave it to be
redone again later (with potentially different values). This is
inefficient. The next patch will correct this.

Also, move a comment about ignoring return values to the place where
the return values are actually ignored.

v2: Move some more splitting from a later patch (and do it correctly).

Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 54 +++
 1 file changed, 33 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index ad784e8068c7..e41e309b9e7e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -634,7 +634,7 @@ int intel_guc_wait_for_idle(struct intel_guc *guc, long 
timeout)
  true, timeout);
 }
 
-static int guc_lrc_desc_pin(struct intel_context *ce, bool loop);
+static int try_context_registration(struct intel_context *ce, bool loop);
 
 static int __guc_add_request(struct intel_guc *guc, struct i915_request *rq)
 {
@@ -932,7 +932,7 @@ static int guc_dequeue_one_context(struct intel_guc *guc)
 
if (unlikely(!ctx_id_mapped(guc, ce->guc_id.id) &&
 !intel_context_is_banned(ce))) {
-   ret = guc_lrc_desc_pin(ce, false);
+   ret = try_context_registration(ce, false);
if (unlikely(ret == -EPIPE)) {
goto deadlk;
} else if (ret == -EBUSY) {
@@ -2237,20 +2237,15 @@ static void guc_context_policy_init(struct 
intel_engine_cs *engine,
desc->preemption_timeout = engine->props.preempt_timeout_ms * 1000;
 }
 
-static int guc_lrc_desc_pin(struct intel_context *ce, bool loop)
+static void prepare_context_registration_info(struct intel_context *ce)
 {
struct intel_engine_cs *engine = ce->engine;
-   struct intel_runtime_pm *runtime_pm = engine->uncore->rpm;
struct intel_guc *guc = >gt->uc.guc;
u32 desc_idx = ce->guc_id.id;
struct guc_lrc_desc *desc;
-   bool context_registered;
-   intel_wakeref_t wakeref;
struct intel_context *child;
-   int ret = 0;
 
GEM_BUG_ON(!engine->mask);
-   GEM_BUG_ON(!sched_state_is_init(ce));
 
/*
 * Ensure LRC + CT vmas are is same region as write barrier is done
@@ -2259,11 +2254,6 @@ static int guc_lrc_desc_pin(struct intel_context *ce, 
bool loop)
GEM_BUG_ON(i915_gem_object_is_lmem(guc->ct.vma->obj) !=
   i915_gem_object_is_lmem(ce->ring->vma->obj));
 
-   context_registered = ctx_id_mapped(guc, desc_idx);
-
-   clr_ctx_id_mapping(guc, desc_idx);
-   set_ctx_id_mapping(guc, desc_idx, ce);
-
desc = __get_lrc_desc(guc, desc_idx);
desc->engine_class = engine_class_to_guc_class(engine->class);
desc->engine_submit_mask = engine->logical_mask;
@@ -2308,6 +2298,26 @@ static int guc_lrc_desc_pin(struct intel_context *ce, 
bool loop)
 
clear_children_join_go_memory(ce);
}
+}
+
+static int try_context_registration(struct intel_context *ce, bool loop)
+{
+   struct intel_engine_cs *engine = ce->engine;
+   struct intel_runtime_pm *runtime_pm = engine->uncore->rpm;
+   struct intel_guc *guc = >gt->uc.guc;
+   intel_wakeref_t wakeref;
+   u32 desc_idx = ce->guc_id.id;
+   bool context_registered;
+   int ret = 0;
+
+   GEM_BUG_ON(!sched_state_is_init(ce));
+
+   context_registered = ctx_id_mapped(guc, desc_idx);
+
+   clr_ctx_id_mapping(guc, desc_idx);
+   set_ctx_id_mapping(guc, desc_idx, ce);
+
+   prepare_context_registration_info(ce);
 
/*
 * The context_lookup xarray is used to determine if the hardware
@@ -3145,7 +3155,7 @@ static int guc_request_alloc(struct i915_request *rq)
if (unlikely(ret < 0))
return ret;
if (context_needs_register(ce, !!ret)) {
-   ret = guc_lrc_desc_pin(ce, true);
+   ret = try_context_registration(ce, true);
if (unlikely(ret)) {/* unwind */
if (ret == -EPIPE) {
disable_submission(guc);
@@ -3633,9 +3643,17 @@ static void guc_set_default_submission(struct 
intel_engine_cs *engine)
 static inline void guc_kernel_context_pin(struct intel_guc *guc,
  struct intel_context *ce)
 {
+   /*
+* Note: we purposefully do not check the returns below because
+* the registration 

[PATCH v2 0/8] Prep work for next GuC release

2022-02-24 Thread John . C . Harrison
From: John Harrison 

The next GuC firmware release includes some significant backwards
breaking API changes. One such is that there is no longer an LRC
descriptor pool. A bunch of prep work for that change can be done in
advance - the descriptor pool was being used for things it shouldn't
really have been used for anyway.

v2: Extend commit message on 'better name' patch. Improve 'split
apart' patch to include some necessary re-arrangement that was in a
later patch and which introduced an unnecessary conditional in said
patch too. (review feedback from Daniele)

Signed-off-by: John Harrison 


John Harrison (8):
  drm/i915/guc: Do not conflate lrc_desc with GuC id for registration
  drm/i915/guc: Add an explicit 'submission_initialized' flag
  drm/i915/guc: Better name for context id limit
  drm/i915/guc: Split guc_lrc_desc_pin apart
  drm/i915/guc: Move lrc desc setup to where it is needed
  drm/i915/guc: Rename desc_idx to ctx_id
  drm/i915/guc: Drop obsolete H2G definitions
  drm/i915/guc: Fix potential invalid pointer dereferences when decoding
G2Hs

 drivers/gpu/drm/i915/gt/intel_context.c   |   2 +-
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |   2 -
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|   2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |   4 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 181 ++
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c |   2 +-
 6 files changed, 109 insertions(+), 84 deletions(-)

-- 
2.25.1



[Bug 201957] amdgpu: ring gfx timeout

2022-02-24 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=201957

--- Comment #66 from Randune (randyk...@gmail.com) ---
So I've been running for about 2.5 weeks now using the amdgpu.runpm=0 kernel
parameter and I've had no crashes or freezes so far. I'm cautiously optimistic
that for me at least this may have solved the problem.  So far I haven't
noticed any side effects (performance degradation etc.).

I understand that amdgpu.runpm=0 is related to power management but I don't
know the specifics. Possibly Alex Deucher can chime in and specify exactly what
this parameter does?

See my previous comments for some context:
comment 35
comment 62
comment 63

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

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

[git pull] drm fixes for 5.17-rc6

2022-02-24 Thread Dave Airlie
Hey,

Regular drm fixes pull, i915, amdgpu and tegra mostly, all pretty small.

I'm in quarantine at home for next 7 days, shouldn't interrupt things,
but might be erratic if anyone is looking for me.

Dave.

drm-fixes-2022-02-25:
drm fixes for 5.17-rc6

core:
- edid: Always set RGB444

tegra:
- tegra186 suspend/resume fixes
- syncpoint wait fix
- build warning fix
- eDP on older devices fix

amdgpu:
- Display FP fix
- PCO powergating fix
- RDNA2 OEM SKU stability fixes
- Display PSR fix
- PCI ASPM fix
- Display link encoder fix for TEST_COMMIT
- Raven2 suspend/resume fix
- Fix a regression in virtual display support
- GPUVM eviction fix

i915:
- Fix QGV handling on ADL-P+
- Fix bw atomic check when switching between SAGV vs. no SAGV
- Disconnect PHYs left connected by BIOS on disabled ports
- Fix SAVG to no SAGV transitions on TGL+
- Print PHY name properly on calibration error (DG2)

imx:
- dcss: Select GEM CMA helpers

radeon:
- Fix some variables's type

vc4:
- Fix codec cleanup
- Fix PM reference counting
The following changes since commit cfb92440ee71adcc2105b0890bb01ac3cddb8507:

  Linux 5.17-rc5 (2022-02-20 13:07:20 -0800)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2022-02-25

for you to fetch changes up to ecf8a99f4807c17fa310a83067a95964cedd9ac1:

  Merge tag 'drm-intel-fixes-2022-02-24' of
git://anongit.freedesktop.org/drm/drm-intel into drm-fixes (2022-02-25
05:51:04 +1000)


drm fixes for 5.17-rc6

core:
- edid: Always set RGB444

tegra:
- tegra186 suspend/resume fixes
- syncpoint wait fix
- build warning fix
- eDP on older devices fix

amdgpu:
- Display FP fix
- PCO powergating fix
- RDNA2 OEM SKU stability fixes
- Display PSR fix
- PCI ASPM fix
- Display link encoder fix for TEST_COMMIT
- Raven2 suspend/resume fix
- Fix a regression in virtual display support
- GPUVM eviction fix

i915:
- Fix QGV handling on ADL-P+
- Fix bw atomic check when switching between SAGV vs. no SAGV
- Disconnect PHYs left connected by BIOS on disabled ports
- Fix SAVG to no SAGV transitions on TGL+
- Print PHY name properly on calibration error (DG2)

imx:
- dcss: Select GEM CMA helpers

radeon:
- Fix some variables's type

vc4:
- Fix codec cleanup
- Fix PM reference counting


Bas Nieuwenhuizen (1):
  drm/amd/display: Protect update_bw_bounding_box FPU code.

Chen Gong (1):
  drm/amdgpu: do not enable asic reset for raven2

Christian König (1):
  drm/radeon: fix variable type

Dave Airlie (4):
  Merge tag 'drm-misc-fixes-2022-02-23' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
  Merge tag 'drm/tegra/for-5.17-rc6' of
https://gitlab.freedesktop.org/drm/tegra into drm-fixes
  Merge tag 'amd-drm-fixes-5.17-2022-02-23' of
https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
  Merge tag 'drm-intel-fixes-2022-02-24' of
git://anongit.freedesktop.org/drm/drm-intel into drm-fixes

Dmitry Osipenko (1):
  gpu: host1x: Fix hang on Tegra186+

Evan Quan (2):
  drm/amdgpu: disable MMHUB PG for Picasso
  drm/amd/pm: fix some OEM SKU specific stability issues

Guchun Chen (2):
  Revert "drm/amdgpu: add modifiers in amdgpu_vkms_plane_init()"
  drm/amdgpu: bypass tiling flag check in virtual display case (v2)

Imre Deak (1):
  drm/i915: Disconnect PHYs left connected by BIOS on disabled ports

Jon Hunter (1):
  drm/tegra: Fix cast to restricted __le32

Mario Limonciello (1):
  drm/amd: Check if ASPM is enabled from PCIe subsystem

Matt Roper (1):
  drm/i915/dg2: Print PHY name properly on calibration error

Maxime Ripard (3):
  drm/vc4: hdmi: Unregister codec device on unbind
  drm/vc4: crtc: Fix runtime_pm reference counting
  drm/edid: Always set RGB444

Michel Dänzer (1):
  drm/amd/display: For vblank_disable_immediate, check PSR is really used

Mikko Perttunen (1):
  gpu: host1x: Always return syncpoint value when waiting

Nicholas Kazlauskas (1):
  drm/amd/display: Fix stream->link_enc unassigned during stream removal

Qiang Yu (1):
  drm/amdgpu: check vm ready by amdgpu_vm->evicting flag

Rudi Heitbaum (1):
  drm/imx/dcss: i.MX8MQ DCSS select DRM_GEM_CMA_HELPER

Thierry Reding (1):
  drm/tegra: dpaux: Populate AUX bus

Ville Syrjälä (3):
  drm/i915: Widen the QGV point mask
  drm/i915: Correctly populate use_sagv_wm for all pipes
  drm/i915: Fix bw atomic check when switching between SAGV vs. no SAGV

 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c|  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c|  3 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c   |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c |  9 --
 drivers/gpu/drm/amd/amdgpu/soc15.c |  9 --
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 17 ++-
 

Re: [PATCH v6 02/12] clk: Introduce Kunit Tests for the framework

2022-02-24 Thread Stephen Boyd
Quoting Daniel Latypov (2022-02-23 14:50:59)
> On Wed, Feb 23, 2022 at 2:56 AM Maxime Ripard  wrote:
> >
> > Let's test various parts of the rate-related clock API with the kunit
> > testing framework.
> >
> > Cc: kunit-...@googlegroups.com
> > Suggested-by: Stephen Boyd 
> > Signed-off-by: Maxime Ripard 
> 
> Tested-by: Daniel Latypov 
> 
> Looks good to me on the KUnit side.
> Two small nits below.
> 
> FYI, I computed the incremental coverage for this series, i.e.:
> 1) applied the full series
> 2) computed the absolute coverage
> 
> $  ./tools/testing/kunit/kunit.py run  --kunitconfig=drivers/clk
> --make_options=CC=/usr/bin/gcc-6 --kconfig_add=CONFIG_DEBUG_KERNEL=y
> --kconfig_add=CONFIG_DEBUG_INFO=y --kconfig_add=CONFIG_GCOV=y
> $ lcov -t "clk_tests" -o coverage.info -c -d .kunit/ 
> --gcov-tool=/usr/bin/gcov-6

This is cool. Thanks! Is it possible to add some 'coverage' command to
kunit so we don't have to recall this invocation?

> 
> 3) intersected that with the total diff

This would also be cool to do automatically with a revision range.

> 
> Incremental coverage for 3/9 files in --diff_file
> Total incremental: 99.29% coverage (281/283 lines)
>   drivers/clk/clk.c: 84.62% coverage (11/13 lines)
>   drivers/clk/clk_test.c: 100.00% coverage (269/269 lines)
>   include/linux/clk.h: 100.00% coverage (1/1 lines)
> 
> Missing lines are drivers/clk/clk.c:2397-8, i.e. this part of the diff:
> +   if (ret) {
> +   /* rollback the changes */
> +   clk->min_rate = old_min; <- 2397
> +   clk->max_rate = old_max; <- 2398
> 
> These are from before and were just moved around.

We could trigger a failure in the provider when the rate is set, and
then we could call round_rate() again and make sure the boundaries from
before are maintained.


Re: [PATCH v6 05/12] clk: Use clamp instead of open-coding our own

2022-02-24 Thread Stephen Boyd
Quoting Maxime Ripard (2022-02-23 02:55:53)
> The code in clk_set_rate_range() will, if the current rate is outside of
> the new range, will force it to the minimum or maximum.

s/will//

> 
> Since it's running under the condition that the rate is either lower
> than the minimum, or higher than the maximum, this is equivalent to
> using clamp, while being less readable. Let's switch to using clamp
> instead.
> 
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/clk/clk.c | 6 +-
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 6c4e10209568..c15ee5070f52 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2388,11 +2388,7 @@ int clk_set_rate_range(struct clk *clk, unsigned long 
> min, unsigned long max)
>  *   this corner case when determining the rate
>  */
>  
> -   if (rate < min)
> -   rate = min;
> -   else
> -   rate = max;
> -
> +   rate = clamp(clk->core->req_rate, min, max);
> ret = clk_core_set_rate_nolock(clk->core, rate);
> if (ret) {


[PATCH v5 0/3] Update VMware maintainer entries

2022-02-24 Thread Srivatsa S. Bhat
This series updates a few maintainer entries for VMware-maintained
subsystems and cleans up references to VMware's private mailing lists
to make it clear that they are effectively email-aliases to reach out
to reviewers.

Changes from v4->v5:
- Add Alexey as reviewer for paravirt ops.

Changes from v3->v4:
- Remove Cc: sta...@vger.kernel.org from patches 1 and 2.

Changes from v1->v3:
- Add Zack as the named maintainer for vmmouse driver
- Use R: to denote email-aliases for VMware reviewers

Regards,
Srivatsa
VMware Photon OS

---

Srivatsa S. Bhat (VMware) (3):
  MAINTAINERS: Update maintainers for paravirt ops and VMware hypervisor 
interface
  MAINTAINERS: Add Zack as maintainer of vmmouse driver
  MAINTAINERS: Mark VMware mailing list entries as email aliases


 MAINTAINERS | 31 ++-
 1 file changed, 18 insertions(+), 13 deletions(-)



[PATCH v5 3/3] MAINTAINERS: Mark VMware mailing list entries as email aliases

2022-02-24 Thread Srivatsa S. Bhat
From: Srivatsa S. Bhat (VMware) 

VMware mailing lists in the MAINTAINERS file are private lists meant
for VMware-internal review/notification for patches to the respective
subsystems. Anyone can post to these addresses, but there is no public
read access like open mailing lists, which makes them more like email
aliases instead (to reach out to reviewers).

So update all the VMware mailing list references in the MAINTAINERS
file to mark them as such, using "R: email-al...@vmware.com".

Signed-off-by: Srivatsa S. Bhat (VMware) 
Acked-by: Juergen Gross 
Acked-by: Joe Perches 
Acked-by: Zack Rusin 
Cc: Nadav Amit 
Cc: Vivek Thampi 
Cc: Vishal Bhakta 
Cc: Ronak Doshi 
Cc: pv-driv...@vmware.com
Cc: linux-graphics-maintai...@vmware.com
Cc: dri-devel@lists.freedesktop.org
Cc: linux-r...@vger.kernel.org
Cc: linux-s...@vger.kernel.org
Cc: net...@vger.kernel.org
Cc: linux-in...@vger.kernel.org
---

 MAINTAINERS |   22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 72771881f159..4041edba891d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6307,8 +6307,8 @@ T:git git://anongit.freedesktop.org/drm/drm-misc
 F: drivers/gpu/drm/vboxvideo/
 
 DRM DRIVER FOR VMWARE VIRTUAL GPU
-M: "VMware Graphics" 
 M: Zack Rusin 
+R: VMware Graphics Reviewers 
 L: dri-devel@lists.freedesktop.org
 S: Supported
 T: git git://anongit.freedesktop.org/drm/drm-misc
@@ -14611,7 +14611,7 @@ PARAVIRT_OPS INTERFACE
 M: Juergen Gross 
 M: Srivatsa S. Bhat (VMware) 
 R: Alexey Makhalov 
-M: "VMware, Inc." 
+R: VMware PV-Drivers Reviewers 
 L: virtualizat...@lists.linux-foundation.org
 L: x...@kernel.org
 S: Supported
@@ -20642,7 +20642,7 @@ F:  tools/testing/vsock/
 
 VMWARE BALLOON DRIVER
 M: Nadav Amit 
-M: "VMware, Inc." 
+R: VMware PV-Drivers Reviewers 
 L: linux-ker...@vger.kernel.org
 S: Maintained
 F: drivers/misc/vmw_balloon.c
@@ -20650,7 +20650,7 @@ F:  drivers/misc/vmw_balloon.c
 VMWARE HYPERVISOR INTERFACE
 M: Srivatsa S. Bhat (VMware) 
 M: Alexey Makhalov 
-M: "VMware, Inc." 
+R: VMware PV-Drivers Reviewers 
 L: virtualizat...@lists.linux-foundation.org
 L: x...@kernel.org
 S: Supported
@@ -20661,14 +20661,14 @@ F:arch/x86/kernel/cpu/vmware.c
 VMWARE PVRDMA DRIVER
 M: Bryan Tan 
 M: Vishnu Dasa 
-M: VMware PV-Drivers 
+R: VMware PV-Drivers Reviewers 
 L: linux-r...@vger.kernel.org
 S: Maintained
 F: drivers/infiniband/hw/vmw_pvrdma/
 
 VMware PVSCSI driver
 M: Vishal Bhakta 
-M: VMware PV-Drivers 
+R: VMware PV-Drivers Reviewers 
 L: linux-s...@vger.kernel.org
 S: Maintained
 F: drivers/scsi/vmw_pvscsi.c
@@ -20676,7 +20676,7 @@ F:  drivers/scsi/vmw_pvscsi.h
 
 VMWARE VIRTUAL PTP CLOCK DRIVER
 M: Vivek Thampi 
-M: "VMware, Inc." 
+R: VMware PV-Drivers Reviewers 
 L: net...@vger.kernel.org
 S: Supported
 F: drivers/ptp/ptp_vmw.c
@@ -20684,15 +20684,15 @@ F:drivers/ptp/ptp_vmw.c
 VMWARE VMCI DRIVER
 M: Jorgen Hansen 
 M: Vishnu Dasa 
+R: VMware PV-Drivers Reviewers 
 L: linux-ker...@vger.kernel.org
-L: pv-driv...@vmware.com (private)
 S: Maintained
 F: drivers/misc/vmw_vmci/
 
 VMWARE VMMOUSE SUBDRIVER
 M: Zack Rusin 
-M: "VMware Graphics" 
-M: "VMware, Inc." 
+R: VMware Graphics Reviewers 
+R: VMware PV-Drivers Reviewers 
 L: linux-in...@vger.kernel.org
 S: Maintained
 F: drivers/input/mouse/vmmouse.c
@@ -20700,7 +20700,7 @@ F:  drivers/input/mouse/vmmouse.h
 
 VMWARE VMXNET3 ETHERNET DRIVER
 M: Ronak Doshi 
-M: pv-driv...@vmware.com
+R: VMware PV-Drivers Reviewers 
 L: net...@vger.kernel.org
 S: Maintained
 F: drivers/net/vmxnet3/




[PATCH v9 10/11] PCI/VGA: Use unsigned format string to print lock counts

2022-02-24 Thread Bjorn Helgaas
From: Bjorn Helgaas 

In struct vga_device, io_lock_cnt and mem_lock_cnt are unsigned, but we
previously printed them with "%d", the signed decimal format.  Print them
with the unsigned format "%u" instead.

Signed-off-by: Bjorn Helgaas 
---
 drivers/pci/vgaarb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 7b1bfdea9d10..d6e77c6a9a1a 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -1156,7 +1156,7 @@ static ssize_t vga_arb_read(struct file *file, char 
__user *buf,
 
/* Fill the buffer with infos */
len = snprintf(lbuf, 1024,
-  "count:%d,PCI:%s,decodes=%s,owns=%s,locks=%s(%d:%d)\n",
+  "count:%d,PCI:%s,decodes=%s,owns=%s,locks=%s(%u:%u)\n",
   vga_decode_count, pci_name(pdev),
   vga_iostate_to_str(vgadev->decodes),
   vga_iostate_to_str(vgadev->owns),
-- 
2.25.1



[PATCH v9 11/11] PCI/VGA: Replace full MIT license text with SPDX identifier

2022-02-24 Thread Bjorn Helgaas
From: Bjorn Helgaas 

Per Documentation/process/license-rules.rst, the SPDX MIT identifier is
equivalent to including the entire MIT license text from
LICENSES/preferred/MIT.

Replace the MIT license text with the equivalent SPDX identifier.

Signed-off-by: Bjorn Helgaas 
---
 drivers/pci/vgaarb.c | 23 +--
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index d6e77c6a9a1a..f80b6ec88dc3 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -1,32 +1,11 @@
+// SPDX-License-Identifier: MIT
 /*
  * vgaarb.c: Implements the VGA arbitration. For details refer to
  * Documentation/gpu/vgaarbiter.rst
  *
- *
  * (C) Copyright 2005 Benjamin Herrenschmidt 
  * (C) Copyright 2007 Paulo R. Zanoni 
  * (C) Copyright 2007, 2009 Tiago Vignatti 
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS
- * IN THE SOFTWARE.
- *
  */
 
 #define pr_fmt(fmt) "vgaarb: " fmt
-- 
2.25.1



[PATCH v9 02/11] PCI/VGA: Move vga_arb_integrated_gpu() earlier in file

2022-02-24 Thread Bjorn Helgaas
From: Huacai Chen 

Move vga_arb_integrated_gpu() earlier in file to prepare for future patch.
No functional change intended.

[bhelgaas: pull #ifdefs inside function]
Link: https://lore.kernel.org/r/20211015061512.2941859-3-chenhua...@loongson.cn
Signed-off-by: Huacai Chen 
---
 drivers/pci/vgaarb.c | 25 +++--
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 8320385a487b..6c57ffb0 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -565,6 +565,17 @@ void vga_put(struct pci_dev *pdev, unsigned int rsrc)
 }
 EXPORT_SYMBOL(vga_put);
 
+static bool vga_arb_integrated_gpu(struct device *dev)
+{
+#if defined(CONFIG_ACPI)
+   struct acpi_device *adev = ACPI_COMPANION(dev);
+
+   return adev && !strcmp(acpi_device_hid(adev), ACPI_VIDEO_HID);
+#else
+   return false;
+#endif
+}
+
 /*
  * Rules for using a bridge to control a VGA descendant decoding: if a bridge
  * has only one VGA descendant then it can be used to control the VGA routing
@@ -1430,20 +1441,6 @@ static struct miscdevice vga_arb_device = {
MISC_DYNAMIC_MINOR, "vga_arbiter", _arb_device_fops
 };
 
-#if defined(CONFIG_ACPI)
-static bool vga_arb_integrated_gpu(struct device *dev)
-{
-   struct acpi_device *adev = ACPI_COMPANION(dev);
-
-   return adev && !strcmp(acpi_device_hid(adev), ACPI_VIDEO_HID);
-}
-#else
-static bool vga_arb_integrated_gpu(struct device *dev)
-{
-   return false;
-}
-#endif
-
 static void __init vga_arb_select_default_device(void)
 {
struct pci_dev *pdev, *found = NULL;
-- 
2.25.1



[PATCH v9 09/11] PCI/VGA: Log bridge control messages when adding devices

2022-02-24 Thread Bjorn Helgaas
From: Huacai Chen 

Previously vga_arb_device_init() iterated through all VGA devices and
indicated whether legacy VGA routing to each could be controlled by an
upstream bridge.

But we determine that information in vga_arbiter_add_pci_device(), which we
call for every device, so we can log it there without iterating through the
VGA devices again.

Note that we call vga_arbiter_check_bridge_sharing() before adding the
device to vga_list, so we have to handle the very first device separately.

Signed-off-by: Huacai Chen 
---
 drivers/pci/vgaarb.c | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 582f0054b71a..7b1bfdea9d10 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -719,8 +719,10 @@ static void vga_arbiter_check_bridge_sharing(struct 
vga_device *vgadev)
 
vgadev->bridge_has_one_vga = true;
 
-   if (list_empty(_list))
+   if (list_empty(_list)) {
+   vgaarb_info(>pdev->dev, "bridge control possible\n");
return;
+   }
 
/* okay iterate the new devices bridge hierarachy */
new_bus = vgadev->pdev->bus;
@@ -759,6 +761,11 @@ static void vga_arbiter_check_bridge_sharing(struct 
vga_device *vgadev)
}
new_bus = new_bus->parent;
}
+
+   if (vgadev->bridge_has_one_vga)
+   vgaarb_info(>pdev->dev, "bridge control possible\n");
+   else
+   vgaarb_info(>pdev->dev, "no bridge control possible\n");
 }
 
 /*
@@ -1557,7 +1564,6 @@ static int __init vga_arb_device_init(void)
 {
int rc;
struct pci_dev *pdev;
-   struct vga_device *vgadev;
 
rc = misc_register(_arb_device);
if (rc < 0)
@@ -1573,15 +1579,6 @@ static int __init vga_arb_device_init(void)
   PCI_ANY_ID, pdev)) != NULL)
vga_arbiter_add_pci_device(pdev);
 
-   list_for_each_entry(vgadev, _list, list) {
-   struct device *dev = >pdev->dev;
-
-   if (vgadev->bridge_has_one_vga)
-   vgaarb_info(dev, "bridge control possible\n");
-   else
-   vgaarb_info(dev, "no bridge control possible\n");
-   }
-
pr_info("loaded\n");
return rc;
 }
-- 
2.25.1



[PATCH v9 08/11] PCI/VGA: Remove empty vga_arb_device_card_gone()

2022-02-24 Thread Bjorn Helgaas
From: Bjorn Helgaas 

vga_arb_device_card_gone() has always been empty.  Remove it.

Signed-off-by: Bjorn Helgaas 
---
 drivers/pci/vgaarb.c | 16 +---
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index e8d5efd85ba6..582f0054b71a 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -123,8 +123,6 @@ static int vga_str_to_iostate(char *buf, int str_size, int 
*io_state)
 /* this is only used a cookie - it should not be dereferenced */
 static struct pci_dev *vga_default;
 
-static void vga_arb_device_card_gone(struct pci_dev *pdev);
-
 /* Find somebody in our list */
 static struct vga_device *vgadev_find(struct pci_dev *pdev)
 {
@@ -878,10 +876,6 @@ static bool vga_arbiter_del_pci_device(struct pci_dev 
*pdev)
/* Remove entry from list */
list_del(>list);
vga_count--;
-   /* Notify userland driver that the device is gone so it discards
-* it's copies of the pci_dev pointer
-*/
-   vga_arb_device_card_gone(pdev);
 
/* Wake up all possible waiters */
wake_up_all(_wait_queue);
@@ -1131,9 +1125,7 @@ static ssize_t vga_arb_read(struct file *file, char 
__user *buf,
if (lbuf == NULL)
return -ENOMEM;
 
-   /* Shields against vga_arb_device_card_gone (pci_dev going
-* away), and allows access to vga list
-*/
+   /* Protects vga_list */
spin_lock_irqsave(_lock, flags);
 
/* If we are targeting the default, use it */
@@ -1150,8 +1142,6 @@ static ssize_t vga_arb_read(struct file *file, char 
__user *buf,
/* Wow, it's not in the list, that shouldn't happen,
 * let's fix us up and return invalid card
 */
-   if (pdev == priv->target)
-   vga_arb_device_card_gone(pdev);
spin_unlock_irqrestore(_lock, flags);
len = sprintf(lbuf, "invalid");
goto done;
@@ -1495,10 +1485,6 @@ static int vga_arb_release(struct inode *inode, struct 
file *file)
return 0;
 }
 
-static void vga_arb_device_card_gone(struct pci_dev *pdev)
-{
-}
-
 /*
  * callback any registered clients to let them know we have a
  * change in VGA cards
-- 
2.25.1



[PATCH v9 07/11] PCI/VGA: Move disabled VGA device detection to ADD_DEVICE path

2022-02-24 Thread Bjorn Helgaas
From: Huacai Chen 

a37c0f48950b ("vgaarb: Select a default VGA device even if there's no
legacy VGA") extended the vga_arb_device_init() subsys_initcall so that if
there are no other eligible devices, it could select a disabled VGA device
as the default.

Move this detection from vga_arb_select_default_device() to
vga_arbiter_add_pci_device() so every device, even those hot-added or
enumerated after vga_arb_device_init() is eligible for selection as the
default VGA device.

[bhelgaas: commit log, restructure]
Link: https://lore.kernel.org/r/20211015061512.2941859-5-chenhua...@loongson.cn
Signed-off-by: Huacai Chen 
Cc: Daniel Axtens 
Cc: Zhou Wang 
---
 drivers/pci/vgaarb.c | 27 +--
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index e36ccbfdbd89..e8d5efd85ba6 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -656,7 +656,8 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
 * We use the first one we find, so if we've already found one,
 * vgadev is no better.
 */
-   if (boot_vga)
+   if (boot_vga &&
+   (boot_vga->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)
return false;
 
if ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)
@@ -693,6 +694,13 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
return true;
}
 
+   /*
+* vgadev has neither IO nor MEM enabled.  If we haven't found any
+* other VGA devices, it is the best candidate so far.
+*/
+   if (!boot_vga)
+   return true;
+
return false;
 }
 
@@ -1559,21 +1567,6 @@ static struct miscdevice vga_arb_device = {
MISC_DYNAMIC_MINOR, "vga_arbiter", _arb_device_fops
 };
 
-static void __init vga_arb_select_default_device(void)
-{
-   struct vga_device *vgadev;
-
-   if (!vga_default_device()) {
-   vgadev = list_first_entry_or_null(_list,
- struct vga_device, list);
-   if (vgadev) {
-   struct device *dev = >pdev->dev;
-   vgaarb_info(dev, "setting as boot device (VGA legacy 
resources not available)\n");
-   vga_set_default_device(vgadev->pdev);
-   }
-   }
-}
-
 static int __init vga_arb_device_init(void)
 {
int rc;
@@ -1603,8 +1596,6 @@ static int __init vga_arb_device_init(void)
vgaarb_info(dev, "no bridge control possible\n");
}
 
-   vga_arb_select_default_device();
-
pr_info("loaded\n");
return rc;
 }
-- 
2.25.1



[PATCH v9 04/11] PCI/VGA: Factor out default VGA device selection

2022-02-24 Thread Bjorn Helgaas
From: Huacai Chen 

Default VGA device selection fails when PCI devices are enumerated after
the vga_arb_device_init() subsys_initcall.

vga_arbiter_add_pci_device() selects the first fully enabled device to
which legacy VGA resources are routed as the default VGA device.  This is
an ADD_DEVICE notifier, so it runs after every PCI device is enumerated.

vga_arb_select_default_device() may select framebuffer devices, partially
enabled GPUs, or non-legacy devices that don't have legacy VGA resources
routed to them as the default VGA device.  But this only happens once, from
the vga_arb_device_init() subsys_initcall, so it doesn't consider devices
enumerated after that:

  acpi_init
acpi_scan_init
  acpi_pci_root_init # PCI device enumeration (ACPI systems)

  vga_arb_device_init
for_each_pci_device
  vga_arbiter_add_pci_device  # ADD_DEVICE notifier
if (VGA-owner)
  vga_set_default_device  <-- set default VGA
vga_arb_select_default_device # only called ONCE
  for_each_vga_device
if (framebuffer)
  vga_set_default_device  <-- set default VGA to framebuffer
  if (!vga_default_device())
if (non-legacy, integrated GPU, etc)
  vga_set_default_device  <-- set default VGA
  if (!vga_default_device())
vga_set_default_device<-- set default VGA

  pcibios_init
pcibios_scanbus  # PCI device enumeration (non-ACPI systems)
  ...
vga_arbiter_add_pci_device# ADD_DEVICE notification
  if (VGA-owner)
vga_set_default_device<-- set default VGA

Note that on non-ACPI systems, vga_arb_select_default_device() runs before
pcibios_init(), so it sees no VGA devices and can never set a framebuffer
device, a non-legacy integrated GPU, etc., as the default device.

Factor out the default VGA device selection to vga_is_boot_device(), called
from vga_arbiter_add_pci_device().

Then we can migrate the default device selection from
vga_arb_select_default_device() to the vga_arbiter_add_pci_device() path.

[bhelgaas: commit log, split to separate patch]
Link: https://lore.kernel.org/r/20211015061512.2941859-4-chenhua...@loongson.cn
Signed-off-by: Huacai Chen 
---
 drivers/pci/vgaarb.c | 45 ++--
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 3f8fead49197..58e0a12e623b 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -628,6 +628,41 @@ static bool vga_arb_integrated_gpu(struct device *dev)
 #endif
 }
 
+/*
+ * Return true if vgadev is a better default VGA device than the best one
+ * we've seen so far.
+ */
+static bool vga_is_boot_device(struct vga_device *vgadev)
+{
+   struct vga_device *boot_vga = vgadev_find(vga_default_device());
+
+   /*
+* We select the default VGA device in this order:
+*   Firmware framebuffer (see vga_arb_select_default_device())
+*   Legacy VGA device (owns VGA_RSRC_LEGACY_MASK)
+*   Non-legacy integrated device (see vga_arb_select_default_device())
+*   Non-legacy discrete device (see vga_arb_select_default_device())
+*   Other device (see vga_arb_select_default_device())
+*/
+
+   /*
+* A legacy VGA device has MEM and IO enabled and any bridges
+* leading to it have PCI_BRIDGE_CTL_VGA enabled so the legacy
+* resources ([mem 0xa-0xb], [io 0x3b0-0x3bb], etc) are
+* routed to it.
+*
+* We use the first one we find, so if we've already found one,
+* vgadev is no better.
+*/
+   if (boot_vga)
+   return false;
+
+   if ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)
+   return true;
+
+   return false;
+}
+
 /*
  * Rules for using a bridge to control a VGA descendant decoding: if a bridge
  * has only one VGA descendant then it can be used to control the VGA routing
@@ -755,12 +790,10 @@ static bool vga_arbiter_add_pci_device(struct pci_dev 
*pdev)
bus = bus->parent;
}
 
-   /* Deal with VGA default device. Use first enabled one
-* by default if arch doesn't have it's own hook
-*/
-   if (vga_default == NULL &&
-   ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) {
-   vgaarb_info(>dev, "setting as boot VGA device\n");
+   if (vga_is_boot_device(vgadev)) {
+   vgaarb_info(>dev, "setting as boot VGA device%s\n",
+   vga_default_device() ?
+   " (overriding previous)" : "");
vga_set_default_device(pdev);
}
 
-- 
2.25.1



[PATCH v9 05/11] PCI/VGA: Move firmware default device detection to ADD_DEVICE path

2022-02-24 Thread Bjorn Helgaas
From: Huacai Chen 

Previously we selected the firmware default device, i.e., one that owns the
boot framebuffer, as the default device in vga_arb_select_default_device().
This was only done in the vga_arb_device_init() subsys_initcall, so devices
enumerated later, e.g., by pcibios_init(), were not eligible.

Fix this by moving the firmware default device selection from
vga_arb_select_default_device() to vga_arbiter_add_pci_device(), which is
called after every PCI device is enumerated, either by the
vga_arb_device_init() subsys_initcall or as an ADD_DEVICE notifier.

Note that if vga_arb_select_default_device() previously found a device
owning the boot framebuffer, it unconditionally set it to be the default
VGA device, and no subsequent device could replace it.

[bhelgaas: commit log, restructure slightly]
Link: https://lore.kernel.org/r/20211015061512.2941859-7-chenhua...@loongson.cn
Signed-off-by: Huacai Chen 
Cc: Bruno Prémont 
---
 drivers/pci/vgaarb.c | 37 +
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 58e0a12e623b..c3323ab4f98e 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -72,6 +72,7 @@ struct vga_device {
unsigned int io_norm_cnt;   /* normal IO count */
unsigned int mem_norm_cnt;  /* normal MEM count */
bool bridge_has_one_vga;
+   bool is_firmware_default;   /* device selected by firmware */
unsigned int (*set_decode)(struct pci_dev *pdev, bool decode);
 };
 
@@ -565,10 +566,9 @@ void vga_put(struct pci_dev *pdev, unsigned int rsrc)
 }
 EXPORT_SYMBOL(vga_put);
 
-static void __init vga_select_framebuffer_device(struct pci_dev *pdev)
+static bool vga_is_firmware_default(struct pci_dev *pdev)
 {
 #if defined(CONFIG_X86) || defined(CONFIG_IA64)
-   struct device *dev = >dev;
u64 base = screen_info.lfb_base;
u64 size = screen_info.lfb_size;
u64 limit;
@@ -583,15 +583,6 @@ static void __init vga_select_framebuffer_device(struct 
pci_dev *pdev)
 
limit = base + size;
 
-   /*
-* Override vga_arbiter_add_pci_device()'s I/O based detection
-* as it may take the wrong device (e.g. on Apple system under
-* EFI).
-*
-* Select the device owning the boot framebuffer if there is
-* one.
-*/
-
/* Does firmware framebuffer belong to us? */
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
flags = pci_resource_flags(pdev, i);
@@ -608,13 +599,10 @@ static void __init vga_select_framebuffer_device(struct 
pci_dev *pdev)
if (base < start || limit >= end)
continue;
 
-   if (!vga_default_device())
-   vgaarb_info(dev, "setting as boot device\n");
-   else if (pdev != vga_default_device())
-   vgaarb_info(dev, "overriding boot device\n");
-   vga_set_default_device(pdev);
+   return true;
}
 #endif
+   return false;
 }
 
 static bool vga_arb_integrated_gpu(struct device *dev)
@@ -635,6 +623,7 @@ static bool vga_arb_integrated_gpu(struct device *dev)
 static bool vga_is_boot_device(struct vga_device *vgadev)
 {
struct vga_device *boot_vga = vgadev_find(vga_default_device());
+   struct pci_dev *pdev = vgadev->pdev;
 
/*
 * We select the default VGA device in this order:
@@ -645,6 +634,18 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
 *   Other device (see vga_arb_select_default_device())
 */
 
+   /*
+* We always prefer a firmware default device, so if we've already
+* found one, there's no need to consider vgadev.
+*/
+   if (boot_vga && boot_vga->is_firmware_default)
+   return false;
+
+   if (vga_is_firmware_default(pdev)) {
+   vgadev->is_firmware_default = true;
+   return true;
+   }
+
/*
 * A legacy VGA device has MEM and IO enabled and any bridges
 * leading to it have PCI_BRIDGE_CTL_VGA enabled so the legacy
@@ -1531,10 +1532,6 @@ static void __init vga_arb_select_default_device(void)
struct pci_dev *pdev, *found = NULL;
struct vga_device *vgadev;
 
-   list_for_each_entry(vgadev, _list, list) {
-   vga_select_framebuffer_device(vgadev->pdev);
-   }
-
if (!vga_default_device()) {
list_for_each_entry_reverse(vgadev, _list, list) {
struct device *dev = >pdev->dev;
-- 
2.25.1



[PATCH v9 06/11] PCI/VGA: Move non-legacy VGA detection to ADD_DEVICE path

2022-02-24 Thread Bjorn Helgaas
From: Huacai Chen 

a37c0f48950b ("vgaarb: Select a default VGA device even if there's no
legacy VGA") extended the vga_arb_device_init() subsys_initcall so it could
select a non-legacy VGA device as the default.

That failed to consider that PCI devices may be enumerated after
vga_arb_device_init(), e.g., hot-added devices or non-ACPI systems that do
PCI enumeration in pcibios_init().  Devices found then could never be
selected as the default.

One system where this is a problem is the MIPS-based Loongson where an
ASpeed AST2500 VGA device is behind a bridge that doesn't implement the VGA
Enable bit, so legacy resources are not routed to the VGA device. [1]

Fix this by moving the non-legacy VGA device selection from
vga_arb_select_default_device() to vga_arbiter_add_pci_device(), which is
called after every PCI device is enumerated, either by the
vga_arb_device_init() subsys_initcall or as an ADD_DEVICE notifier.

[1] https://lore.kernel.org/r/20210514080025.1828197-6-chenhua...@loongson.cn

[bhelgaas: commit log, restructure]
Link: https://lore.kernel.org/r/20211015061512.2941859-5-chenhua...@loongson.cn
Link: https://lore.kernel.org/r/20211015061512.2941859-7-chenhua...@loongson.cn
Signed-off-by: Huacai Chen 
Cc: Daniel Axtens 
Cc: Zhou Wang 
---
 drivers/pci/vgaarb.c | 54 ++--
 1 file changed, 32 insertions(+), 22 deletions(-)

diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index c3323ab4f98e..e36ccbfdbd89 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -624,6 +624,7 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
 {
struct vga_device *boot_vga = vgadev_find(vga_default_device());
struct pci_dev *pdev = vgadev->pdev;
+   u16 cmd, boot_cmd;
 
/*
 * We select the default VGA device in this order:
@@ -661,6 +662,37 @@ static bool vga_is_boot_device(struct vga_device *vgadev)
if ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)
return true;
 
+   /*
+* If we haven't found a legacy VGA device, accept a non-legacy
+* device.  It may have either IO or MEM enabled, and bridges may
+* not have PCI_BRIDGE_CTL_VGA enabled, so it may not be able to
+* use legacy VGA resources.  Prefer an integrated GPU over others.
+*/
+   pci_read_config_word(pdev, PCI_COMMAND, );
+   if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+
+   /*
+* An integrated GPU overrides a previous non-legacy
+* device.  We expect only a single integrated GPU, but if
+* there are more, we use the *last* because that was the
+* previous behavior.
+*/
+   if (vga_arb_integrated_gpu(>dev))
+   return true;
+
+   /*
+* We prefer the first non-legacy discrete device we find.
+* If we already found one, vgadev is no better.
+*/
+   if (boot_vga) {
+   pci_read_config_word(boot_vga->pdev, PCI_COMMAND,
+_cmd);
+   if (boot_cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
+   return false;
+   }
+   return true;
+   }
+
return false;
 }
 
@@ -1529,30 +1561,8 @@ static struct miscdevice vga_arb_device = {
 
 static void __init vga_arb_select_default_device(void)
 {
-   struct pci_dev *pdev, *found = NULL;
struct vga_device *vgadev;
 
-   if (!vga_default_device()) {
-   list_for_each_entry_reverse(vgadev, _list, list) {
-   struct device *dev = >pdev->dev;
-   u16 cmd;
-
-   pdev = vgadev->pdev;
-   pci_read_config_word(pdev, PCI_COMMAND, );
-   if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
-   found = pdev;
-   if (vga_arb_integrated_gpu(dev))
-   break;
-   }
-   }
-   }
-
-   if (found) {
-   vgaarb_info(>dev, "setting as boot device (VGA legacy 
resources not available)\n");
-   vga_set_default_device(found);
-   return;
-   }
-
if (!vga_default_device()) {
vgadev = list_first_entry_or_null(_list,
  struct vga_device, list);
-- 
2.25.1



[PATCH v9 03/11] PCI/VGA: Factor out vga_select_framebuffer_device()

2022-02-24 Thread Bjorn Helgaas
From: Bjorn Helgaas 

On x86 and ia64, if a VGA device BARs include a framebuffer reported by
platform firmware, we select the device as the default VGA device.  Factor
this code to a separate function.  No functional change intended.

Signed-off-by: Bjorn Helgaas 
Cc: Bruno Prémont 
---
 drivers/pci/vgaarb.c | 99 
 1 file changed, 53 insertions(+), 46 deletions(-)

diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 6c57ffb0..3f8fead49197 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -565,6 +565,58 @@ void vga_put(struct pci_dev *pdev, unsigned int rsrc)
 }
 EXPORT_SYMBOL(vga_put);
 
+static void __init vga_select_framebuffer_device(struct pci_dev *pdev)
+{
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
+   struct device *dev = >dev;
+   u64 base = screen_info.lfb_base;
+   u64 size = screen_info.lfb_size;
+   u64 limit;
+   resource_size_t start, end;
+   unsigned long flags;
+   int i;
+
+   /* Select the device owning the boot framebuffer if there is one */
+
+   if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
+   base |= (u64)screen_info.ext_lfb_base << 32;
+
+   limit = base + size;
+
+   /*
+* Override vga_arbiter_add_pci_device()'s I/O based detection
+* as it may take the wrong device (e.g. on Apple system under
+* EFI).
+*
+* Select the device owning the boot framebuffer if there is
+* one.
+*/
+
+   /* Does firmware framebuffer belong to us? */
+   for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+   flags = pci_resource_flags(pdev, i);
+
+   if ((flags & IORESOURCE_MEM) == 0)
+   continue;
+
+   start = pci_resource_start(pdev, i);
+   end  = pci_resource_end(pdev, i);
+
+   if (!start || !end)
+   continue;
+
+   if (base < start || limit >= end)
+   continue;
+
+   if (!vga_default_device())
+   vgaarb_info(dev, "setting as boot device\n");
+   else if (pdev != vga_default_device())
+   vgaarb_info(dev, "overriding boot device\n");
+   vga_set_default_device(pdev);
+   }
+#endif
+}
+
 static bool vga_arb_integrated_gpu(struct device *dev)
 {
 #if defined(CONFIG_ACPI)
@@ -1446,54 +1498,9 @@ static void __init vga_arb_select_default_device(void)
struct pci_dev *pdev, *found = NULL;
struct vga_device *vgadev;
 
-#if defined(CONFIG_X86) || defined(CONFIG_IA64)
-   u64 base = screen_info.lfb_base;
-   u64 size = screen_info.lfb_size;
-   u64 limit;
-   resource_size_t start, end;
-   unsigned long flags;
-   int i;
-
-   if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
-   base |= (u64)screen_info.ext_lfb_base << 32;
-
-   limit = base + size;
-
list_for_each_entry(vgadev, _list, list) {
-   struct device *dev = >pdev->dev;
-   /*
-* Override vga_arbiter_add_pci_device()'s I/O based detection
-* as it may take the wrong device (e.g. on Apple system under
-* EFI).
-*
-* Select the device owning the boot framebuffer if there is
-* one.
-*/
-
-   /* Does firmware framebuffer belong to us? */
-   for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-   flags = pci_resource_flags(vgadev->pdev, i);
-
-   if ((flags & IORESOURCE_MEM) == 0)
-   continue;
-
-   start = pci_resource_start(vgadev->pdev, i);
-   end  = pci_resource_end(vgadev->pdev, i);
-
-   if (!start || !end)
-   continue;
-
-   if (base < start || limit >= end)
-   continue;
-
-   if (!vga_default_device())
-   vgaarb_info(dev, "setting as boot device\n");
-   else if (vgadev->pdev != vga_default_device())
-   vgaarb_info(dev, "overriding boot device\n");
-   vga_set_default_device(vgadev->pdev);
-   }
+   vga_select_framebuffer_device(vgadev->pdev);
}
-#endif
 
if (!vga_default_device()) {
list_for_each_entry_reverse(vgadev, _list, list) {
-- 
2.25.1



[PATCH v9 01/11] PCI/VGA: Move vgaarb to drivers/pci

2022-02-24 Thread Bjorn Helgaas
From: Bjorn Helgaas 

The VGA arbiter is really PCI-specific and doesn't depend on any GPU
things.  Move it to the PCI subsystem.

Note that misc_init() must be called before vga_arb_device_init().  These
are both subsys_initcalls, so this ordering depends on the link order,
which is determined by drivers/Makefile:

  obj-y += pci/
  obj-y += char/<-- misc_init()
  obj-y += gpu/ <-- vga_arb_device_init() (before this commit)

The drivers/pci/ subsys_initcalls are called *before* misc_init(), so
convert vga_arb_device_init() to subsys_initcall_sync(), which is called
after *all* subsys_initcalls.

Signed-off-by: Bjorn Helgaas 
---
 drivers/gpu/vga/Kconfig   | 19 ---
 drivers/gpu/vga/Makefile  |  1 -
 drivers/pci/Kconfig   | 19 +++
 drivers/pci/Makefile  |  1 +
 drivers/{gpu/vga => pci}/vgaarb.c |  2 +-
 5 files changed, 21 insertions(+), 21 deletions(-)
 rename drivers/{gpu/vga => pci}/vgaarb.c (99%)

diff --git a/drivers/gpu/vga/Kconfig b/drivers/gpu/vga/Kconfig
index 1ad4c4ef0b5e..eb8b14ab22c3 100644
--- a/drivers/gpu/vga/Kconfig
+++ b/drivers/gpu/vga/Kconfig
@@ -1,23 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-config VGA_ARB
-   bool "VGA Arbitration" if EXPERT
-   default y
-   depends on (PCI && !S390)
-   help
- Some "legacy" VGA devices implemented on PCI typically have the same
- hard-decoded addresses as they did on ISA. When multiple PCI devices
- are accessed at same time they need some kind of coordination. Please
- see Documentation/gpu/vgaarbiter.rst for more details. Select this to
- enable VGA arbiter.
-
-config VGA_ARB_MAX_GPUS
-   int "Maximum number of GPUs"
-   default 16
-   depends on VGA_ARB
-   help
- Reserves space in the kernel to maintain resource locking for
- multiple GPUS.  The overhead for each GPU is very small.
-
 config VGA_SWITCHEROO
bool "Laptop Hybrid Graphics - GPU switching support"
depends on X86
diff --git a/drivers/gpu/vga/Makefile b/drivers/gpu/vga/Makefile
index e92064442d60..9800620deda3 100644
--- a/drivers/gpu/vga/Makefile
+++ b/drivers/gpu/vga/Makefile
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_VGA_ARB)  += vgaarb.o
 obj-$(CONFIG_VGA_SWITCHEROO) += vga_switcheroo.o
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index d98fafdd0f99..133c73207782 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -252,6 +252,25 @@ config PCIE_BUS_PEER2PEER
 
 endchoice
 
+config VGA_ARB
+   bool "VGA Arbitration" if EXPERT
+   default y
+   depends on (PCI && !S390)
+   help
+ Some "legacy" VGA devices implemented on PCI typically have the same
+ hard-decoded addresses as they did on ISA. When multiple PCI devices
+ are accessed at same time they need some kind of coordination. Please
+ see Documentation/gpu/vgaarbiter.rst for more details. Select this to
+ enable VGA arbiter.
+
+config VGA_ARB_MAX_GPUS
+   int "Maximum number of GPUs"
+   default 16
+   depends on VGA_ARB
+   help
+ Reserves space in the kernel to maintain resource locking for
+ multiple GPUS.  The overhead for each GPU is very small.
+
 source "drivers/pci/hotplug/Kconfig"
 source "drivers/pci/controller/Kconfig"
 source "drivers/pci/endpoint/Kconfig"
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 37be95adf169..0da6b1ebc694 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_PCI_PF_STUB) += pci-pf-stub.o
 obj-$(CONFIG_PCI_ECAM) += ecam.o
 obj-$(CONFIG_PCI_P2PDMA)   += p2pdma.o
 obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o
+obj-$(CONFIG_VGA_ARB)  += vgaarb.o
 
 # Endpoint library must be initialized before its users
 obj-$(CONFIG_PCI_ENDPOINT) += endpoint/
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/pci/vgaarb.c
similarity index 99%
rename from drivers/gpu/vga/vgaarb.c
rename to drivers/pci/vgaarb.c
index 569930552957..8320385a487b 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -1564,4 +1564,4 @@ static int __init vga_arb_device_init(void)
pr_info("loaded\n");
return rc;
 }
-subsys_initcall(vga_arb_device_init);
+subsys_initcall_sync(vga_arb_device_init);
-- 
2.25.1



[PATCH v9 00/11] vgaarb: Rework default VGA device selection

2022-02-24 Thread Bjorn Helgaas
From: Bjorn Helgaas 

Current default VGA device selection fails in some cases because part of it
is done in the vga_arb_device_init() subsys_initcall, and some arches
enumerate PCI devices in pcibios_init(), which runs *after* that.

The big change from the v8 posting is that this moves vgaarb.c from
drivers/gpu/vga to drivers/pci because it really has nothing to do with
GPUs or DRM.

For example:

  - On BMC system, the AST2500 bridge [1a03:1150] does not implement
PCI_BRIDGE_CTL_VGA.  This is perfectly legal but means the legacy VGA
resources won't reach downstream devices unless they're included in the
usual bridge windows.

  - vga_arb_select_default_device() will set a device below such a bridge
as the default VGA device as long as it has PCI_COMMAND_IO and
PCI_COMMAND_MEMORY enabled.

  - vga_arbiter_add_pci_device() is called for every VGA device, either at
boot-time or at hot-add time, and it will also set the device as the
default VGA device, but ONLY if all bridges leading to it implement
PCI_BRIDGE_CTL_VGA.

  - This difference between vga_arb_select_default_device() and
vga_arbiter_add_pci_device() means that a device below an AST2500 or
similar bridge can only be set as the default if it is enumerated
before vga_arb_device_init().

  - On ACPI-based systems, PCI devices are enumerated by acpi_init(), which
runs before vga_arb_device_init().

  - On non-ACPI systems, like on MIPS system, they are enumerated by
pcibios_init(), which typically runs *after* vga_arb_device_init().

This series consolidates all the default VGA device selection in
vga_arbiter_add_pci_device(), which is always called after enumerating a
PCI device.

Almost all the work here is Huacai's.  I restructured it a little bit and
added a few trivial patches on top.

Bjorn

Version history:
V0 original implementation as final quirk to set default device.
https://lore.kernel.org/r/20210514080025.1828197-6-chenhua...@loongson.cn

V1 rework vgaarb to do all default device selection in
vga_arbiter_add_pci_device().
https://lore.kernel.org/r/20210705100503.1120643-1-chenhua...@loongson.cn

V2 move arbiter to PCI subsystem, fix nits.
https://lore.kernel.org/r/20210722212920.347118-1-helg...@kernel.org

V3 rewrite the commit log of the last patch (which is also summarized
by Bjorn).
https://lore.kernel.org/r/20210820100832.663931-1-chenhua...@loongson.cn

V4 split the last patch to two steps.
https://lore.kernel.org/r/20210827083129.2781420-1-chenhua...@loongson.cn

V5 split Patch-9 again and sort the patches.
https://lore.kernel.org/r/20210911093056.1555274-1-chenhua...@loongson.cn

V6 split Patch-5 again and sort the patches again.
https://lore.kernel.org/r/20210916082941.3421838-1-chenhua...@loongson.cn

V7 stop moving vgaarb to drivers/pci because of ordering issues with
misc_init().
https://lore.kernel.org/r/20211015061512.2941859-1-chenhua...@loongson.cn
https://lore.kernel.org/r/caahv-h7fhajm-ha42z1dlre4pvc9frfyeu27khwcywkkmft...@mail.gmail.com

V8 expand commit logs, rework boot VGA device selection
https://lore.kernel.org/r/20220106000658.243509-1-helg...@kernel.org

V9 (this posting) move to drivers/pci, resolve initcall ordering, rename
vga_is_framebuffer_device() to vga_is_firmware_default()

Bjorn Helgaas (5):
  PCI/VGA: Move vgaarb to drivers/pci
  PCI/VGA: Factor out vga_select_framebuffer_device()
  PCI/VGA: Remove empty vga_arb_device_card_gone()
  PCI/VGA: Use unsigned format string to print lock counts
  PCI/VGA: Replace full MIT license text with SPDX identifier

Huacai Chen (6):
  PCI/VGA: Move vga_arb_integrated_gpu() earlier in file
  PCI/VGA: Factor out default VGA device selection
  PCI/VGA: Move firmware default device detection to ADD_DEVICE path
  PCI/VGA: Move non-legacy VGA detection to ADD_DEVICE path
  PCI/VGA: Move disabled VGA device detection to ADD_DEVICE path
  PCI/VGA: Log bridge control messages when adding devices

 drivers/gpu/vga/Kconfig   |  19 --
 drivers/gpu/vga/Makefile  |   1 -
 drivers/pci/Kconfig   |  19 ++
 drivers/pci/Makefile  |   1 +
 drivers/{gpu/vga => pci}/vgaarb.c | 313 +++---
 5 files changed, 175 insertions(+), 178 deletions(-)
 rename drivers/{gpu/vga => pci}/vgaarb.c (90%)

-- 
2.25.1



Re: [PATCH v4 03/10] clk: Use clamp instead of open-coding our own

2022-02-24 Thread Stephen Boyd
Quoting Maxime Ripard (2022-02-21 08:30:01)
> On Fri, Feb 18, 2022 at 02:34:20PM -0800, Stephen Boyd wrote:
> > Quoting Maxime Ripard (2022-01-25 06:15:42)
> > > The code in clk_set_rate_range() will, if the current rate is outside of
> > > the new range, will force it to the minimum or maximum. This is
> > > equivalent to using clamp, while being less readable. Let's switch to
> > > using clamp instead.
> > > 
> > > Signed-off-by: Maxime Ripard 
> > > ---
> > >  drivers/clk/clk.c | 6 +-
> > >  1 file changed, 1 insertion(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > > index 7bb5ae0fb688..150d1bc0985b 100644
> > > --- a/drivers/clk/clk.c
> > > +++ b/drivers/clk/clk.c
> > > @@ -2365,11 +2365,7 @@ int clk_set_rate_range(struct clk *clk, unsigned 
> > > long min, unsigned long max)
> > >  *   this corner case when determining the rate
> > >  */
> > >  
> > > -   if (rate < min)
> > > -   rate = min;
> > > -   else
> > > -   rate = max;
> > > -
> > > +   rate = clamp(clk->core->req_rate, min, max);
> > 
> > This isn't equivalent. The else arm is taken if rate >= min and rate is
> > set to max, whereas clamp() will leave the rate unchanged if rate >= min
> > && rate < max.
> 
> This can't happen, since we're in an if block that is (rate < min ||
> rate > max), so at this point if rate is not less than min, it is
> greater than rate. Thus, it's equivalent to clamp.
> 
> Still, the commit message could be better, I'll rephrase it.

Perfect! Should probably add a comment above the clamp as well just in
case someone decides to move it out of that if block.


[PATCH][next] drm/amdgpu: Fix missing assignment to variable r

2022-02-24 Thread Colin Ian King
Currently the call to function amdgpu_benchmark_move should be
assigning the return value to variable r as this is checked in
the next statement, however, this assignment is missing. Fix
this by adding in the missing assignment.

Addresses clang scan warning:
drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c:168:7: warning:
variable 'r' is uninitialized when used here [-Wuninitialized]

Fixes: 9645c9c9fb15 ("drm/amdgpu: plumb error handling though 
amdgpu_benchmark()")
Signed-off-by: Colin Ian King 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
index 3136a9ad2d54..bb293a5c6fd5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
@@ -163,7 +163,7 @@ int amdgpu_benchmark(struct amdgpu_device *adev, int 
test_number)
 "benchmark test: %d (simple test, VRAM to VRAM)\n",
 test_number);
/* simple test, VRAM to VRAM */
-   amdgpu_benchmark_move(adev, 1024*1024, AMDGPU_GEM_DOMAIN_VRAM,
+   r = amdgpu_benchmark_move(adev, 1024*1024, 
AMDGPU_GEM_DOMAIN_VRAM,
  AMDGPU_GEM_DOMAIN_VRAM);
if (r)
goto done;
-- 
2.34.1



Re: [PATCH V3 02/12] dt-bindings: display: bridge: tc358867: Document DSI data-lanes property

2022-02-24 Thread Rob Herring
On Thu, 24 Feb 2022 20:58:07 +0100, Marek Vasut wrote:
> It is necessary to specify the number of connected/used DSI data lanes when
> using the DSI input port of this bridge. Document the 'data-lanes' property
> of the DSI input port.
> 
> Signed-off-by: Marek Vasut 
> Cc: Jonas Karlman 
> Cc: Laurent Pinchart 
> Cc: Maxime Ripard 
> Cc: Neil Armstrong 
> Cc: Rob Herring 
> Cc: Sam Ravnborg 
> Cc: devicet...@vger.kernel.org
> To: dri-devel@lists.freedesktop.org
> ---
> V3: - New patch
> ---
>  .../display/bridge/toshiba,tc358767.yaml   | 18 +-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 

Reviewed-by: Rob Herring 


Re: [PATCH V3 01/12] dt-bindings: display: bridge: tc358867: Document DPI output support

2022-02-24 Thread Rob Herring
On Thu, 24 Feb 2022 20:58:06 +0100, Marek Vasut wrote:
> The TC358767/TC358867/TC9595 are all capable of operating in multiple
> modes, DPI-to-(e)DP, DSI-to-(e)DP, DSI-to-DPI. Document support for the
> DPI output port, which can now be connected both as input and output.
> 
> Signed-off-by: Marek Vasut 
> Cc: Jonas Karlman 
> Cc: Laurent Pinchart 
> Cc: Maxime Ripard 
> Cc: Neil Armstrong 
> Cc: Rob Herring 
> Cc: Sam Ravnborg 
> Cc: devicet...@vger.kernel.org
> To: dri-devel@lists.freedesktop.org
> ---
> V2: - Rebase on next-20220217
> V3: - No change
> ---
>  .../devicetree/bindings/display/bridge/toshiba,tc358767.yaml  | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 

Acked-by: Rob Herring 


Re: [PATCH v4 02/10] clk: Always clamp the rounded rate

2022-02-24 Thread Stephen Boyd
Quoting Maxime Ripard (2022-02-21 08:43:23)
> Hi again,
> 
> On Mon, Feb 21, 2022 at 05:18:21PM +0100, Maxime Ripard wrote:
> > On Fri, Feb 18, 2022 at 03:15:06PM -0800, Stephen Boyd wrote:
> > > Quoting Maxime Ripard (2022-01-25 06:15:41)
> > > > +/*
> > > > + * Test that if our clock has some boundaries and we try to round a 
> > > > rate
> > > > + * lower than the minimum, the returned rate will be within range.
> > > > + */
> > > > +static void clk_range_test_set_range_round_rate_lower(struct kunit 
> > > > *test)
> > > > +{
> > > > +   struct clk_dummy_context *ctx = test->priv;
> > > > +   struct clk_hw *hw = >hw;
> > > > +   struct clk *clk = hw->clk;
> > > > +   long rate;
> > > > +
> > > > +   KUNIT_ASSERT_EQ(test,
> > > > +   clk_set_rate_range(clk,
> > > > +  DUMMY_CLOCK_RATE_1,
> > > > +  DUMMY_CLOCK_RATE_2),
> > > > +   0);
> > > > +
> > > > +   rate = clk_round_rate(clk, DUMMY_CLOCK_RATE_1 - 1000);
> > > > +   KUNIT_ASSERT_GT(test, rate, 0);
> > > > +   KUNIT_EXPECT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
> > > 
> > > The comment says within range but this test says exactly the minimum
> > > rate. Please change it to test that the rate is within rate 1 and rate
> > > 2. Also, we should call clk_get_rate() here to make sure the rate is
> > > within the boundaries and matches what clk_round_rate() returned.
> > 
> > Ok
> 
> Actually, that doesn't work. Calling clk_round_rate() won't affect the
> clock rate, so the rate returned by clk_get_rate() won't match what
> clk_round_rate() will return.

Huh? This is asking "what rate will I get if I call clk_set_rate() with
DUMMY_CLOCK_RATE_1 - 1000 after setting the range to be rate 1 and rate
2. It should round that up to some value (and we should enforce that it
is inclusive or exclusive). I think I missed that this is
clk_round_rate().

Either way, the clk provider implementation could say that if you call
clk_set_rate() with a frequency below the minimum that it lies somewhere
between the rate 1 and rate 2. The expectation should only check that it
is within the range and not exactly the minimum because we're not
testing the clk provider implementation of the rounding here, just that
the constraints are satisfied and the rate is within range. That's my
understanding of the comment above the function and the function name.


Re: [PATCH v4 02/10] clk: Always clamp the rounded rate

2022-02-24 Thread Stephen Boyd
Quoting Maxime Ripard (2022-02-21 08:18:21)
> Hi,
> 
> On Fri, Feb 18, 2022 at 03:15:06PM -0800, Stephen Boyd wrote:
> > Quoting Maxime Ripard (2022-01-25 06:15:41)
> > > The current core while setting the min and max rate properly in the
> > > clk_request structure will not make sure that the requested rate is
> > > within these boundaries, leaving it to each and every driver to make
> > > sure it is.
> > 
> > It would be good to describe why. Or decide that it was an oversight and
> > write that down here.
> > 
> > > Add a clamp call to make sure it's always done, and add a few unit tests
> > > to make sure we don't have any regression there.
> > 
> > I looked through the per-user constraint patch history on the list but I
> > couldn't really figure out why it was done this way. I guess we didn't
> > clamp the rate in the core because we wanted to give the clk providers
> > all the information, i.e. the rate that was requested and the boundaries
> > that the consumers have placed on the rate.
> 
> I'm not really sure we should really leave it to the users, something like:
> 
> clk_set_range_rate(clk, 1000, 2000);
> clk_set_rate(clk, 500);
> clk_get_rate(clk) # == 500
> 
> Is definitely weird, and would break the least surprise :)
> 
> We shouldn't leave that to drivers, especially since close to none of
> them handle this properly.

Ok.

> 
> > With the round_rate() clk_op the providers don't know the min/max
> > because the rate request structure isn't passed. I think my concern a
> > long time ago was that a consumer could call clk_round_rate() and get
> > one frequency and then call clk_set_rate() and get another frequency.
> 
> I'm not sure I follow you there.
> 
> The function affected is clk_core_determine_round_nolock(), which is
> called by clk_core_round_rate_nolock() and clk_calc_new_rates(). In
> turn, they will be part of clk(_hw_)_round_clock for the former, and
> clk_core_set_rate_nolock() (and thus clk_set_rate()) for the latter.
> 
> I don't see how you can get a discrepancy between clk_round_rate() and
> clk_set_rate().
> 
> And yeah, it's true that the round_rate op won't have the min and max
> passed to them, but i'd consider this an argument for doing this check
> here, since you don't have that option at all for those clocks.

When the range setting API was introduced the rounding logic and the
rate setting logic didn't use the same code paths. It looks like that
code got consolidated now though so we should be fine.


Re: [PATCH v4 01/10] clk: Introduce Kunit Tests for the framework

2022-02-24 Thread Stephen Boyd
Quoting Maxime Ripard (2022-02-21 07:12:59)
> Hi Stephen,
> 
> Thanks for your review
> 
> On Fri, Feb 18, 2022 at 06:20:46PM -0800, Stephen Boyd wrote:
> > It would also be good to add a test that tries to set the clk rate with
> > clk_set_rate() after a range has been set that is outside the acceptable
> > range and verify that it fails, and one that tries to set it within the
> > range and make sure it succeeds (and changes it to be exactly what was
> > set).
> 
> Do we expect it to fail though?
> 
> If we do:
> 
> clk_set_range_range(clk, 1000, 2000);
> clk_set_rate(3000);
> 
> The current behaviour is that the rate is going to be rounded to 2000,
> but it doesn't fail.
> 
> Or is it what you meant by fail? ie, that the return code is 0, but the
> rate isn't what we asked for?

Yeah sorry for not being clear. I meant that it would be constrained to
the range from before.

> 
> > We want to test the failure paths as well, to make sure we don't start
> > causing them to pass, unless it's expected.
> 
> Do you have any other failure condition you want to test? I already
> tried to come up with those I could think of, but I clearly missed some
> if you said that :)

Not really! :)


[PATCH] drm/msm: Add MSM_SUBMIT_FENCE_SN_IN

2022-02-24 Thread Rob Clark
From: Rob Clark 

Add a way for userspace to specify the sequence number fence used to
track completion of the submit.  As the seqno fence is simply an
incrementing counter which is local to the submitqueue, it is easy for
userspace to know the next value.

This is useful for native userspace drivers in a vm guest, as the guest
to host roundtrip can have high latency.  Assigning the fence seqno in
the guest userspace allows the guest to continue without waiting for
response from the host.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_drv.c|  3 +-
 drivers/gpu/drm/msm/msm_gem_submit.c | 42 
 include/uapi/drm/msm_drm.h   |  4 ++-
 3 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 30fd18ca88c4..16f37f3d9061 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -41,9 +41,10 @@
  * - 1.6.0 - Syncobj support
  * - 1.7.0 - Add MSM_PARAM_SUSPENDS to access suspend count
  * - 1.8.0 - Add MSM_BO_CACHED_COHERENT for supported GPUs (a6xx)
+ * - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN
  */
 #define MSM_VERSION_MAJOR  1
-#define MSM_VERSION_MINOR  8
+#define MSM_VERSION_MINOR  9
 #define MSM_VERSION_PATCHLEVEL 0
 
 static const struct drm_mode_config_funcs mode_config_funcs = {
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
b/drivers/gpu/drm/msm/msm_gem_submit.c
index 6cfa984dee6a..c6d60c8d286d 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -872,16 +872,46 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void 
*data,
 
submit->nr_cmds = i;
 
+   /*
+* If using userspace provided seqno fence, validate that the id
+* is available before arming sched job.  Since access to fence_idr
+* is serialized on the queue lock, the slot should be still avail
+* after the job is armed
+*/
+   if ((args->flags & MSM_SUBMIT_FENCE_SN_IN) &&
+   idr_find(>fence_idr, args->fence)) {
+   ret = -EINVAL;
+   goto out;
+   }
+
drm_sched_job_arm(>base);
 
submit->user_fence = dma_fence_get(>base.s_fence->finished);
 
-   /*
-* Allocate an id which can be used by WAIT_FENCE ioctl to map back
-* to the underlying fence.
-*/
-   submit->fence_id = idr_alloc_cyclic(>fence_idr,
-   submit->user_fence, 1, INT_MAX, GFP_KERNEL);
+   if (args->flags & MSM_SUBMIT_FENCE_SN_IN) {
+   /*
+* Userspace has assigned the seqno fence that it wants
+* us to use.  It is an error to pick a fence sequence
+* number that is not available.
+*/
+   submit->fence_id = args->fence;
+   ret = idr_alloc_u32(>fence_idr, submit->user_fence,
+   >fence_id, submit->fence_id,
+   GFP_KERNEL);
+   /*
+* We've already validated that the fence_id slot is valid,
+* so if idr_alloc_u32 failed, it is a kernel bug
+*/
+   WARN_ON(ret);
+   } else {
+   /*
+* Allocate an id which can be used by WAIT_FENCE ioctl to map
+* back to the underlying fence.
+*/
+   submit->fence_id = idr_alloc_cyclic(>fence_idr,
+   submit->user_fence, 1,
+   INT_MAX, GFP_KERNEL);
+   }
if (submit->fence_id < 0) {
ret = submit->fence_id = 0;
submit->fence_id = 0;
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 6b8fffc28a50..6cd45a7f6947 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -227,6 +227,7 @@ struct drm_msm_gem_submit_bo {
 #define MSM_SUBMIT_SUDO  0x1000 /* run submitted cmds from RB */
 #define MSM_SUBMIT_SYNCOBJ_IN0x0800 /* enable input syncobj */
 #define MSM_SUBMIT_SYNCOBJ_OUT   0x0400 /* enable output syncobj */
+#define MSM_SUBMIT_FENCE_SN_IN   0x0200 /* userspace passes in seqno fence 
*/
 #define MSM_SUBMIT_FLAGS( \
MSM_SUBMIT_NO_IMPLICIT   | \
MSM_SUBMIT_FENCE_FD_IN   | \
@@ -234,6 +235,7 @@ struct drm_msm_gem_submit_bo {
MSM_SUBMIT_SUDO  | \
MSM_SUBMIT_SYNCOBJ_IN| \
MSM_SUBMIT_SYNCOBJ_OUT   | \
+   MSM_SUBMIT_FENCE_SN_IN   | \
0)
 
 #define MSM_SUBMIT_SYNCOBJ_RESET 0x0001 /* Reset syncobj after wait. */
@@ -253,7 +255,7 @@ struct drm_msm_gem_submit_syncobj {
  */
 struct drm_msm_gem_submit {
__u32 flags;  /* MSM_PIPE_x | MSM_SUBMIT_x */
-   __u32 fence;  /* out */
+   __u32 fence;  /* out (or 

[PATCH v5 5/7] drm/nouveau: drop the use of `pci_is_thunderbolt_attached`

2022-02-24 Thread Mario Limonciello
Currently `pci_is_thunderbolt_attached` is used to indicate a device
is connected externally.

The PCI core now marks such devices as removable and downstream drivers
can use this instead.

Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/nouveau/nouveau_vga.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c 
b/drivers/gpu/drm/nouveau/nouveau_vga.c
index 60cd8c0463df..2c8008cb38e0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vga.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
@@ -97,7 +97,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
vga_client_register(pdev, nouveau_vga_set_decode);
 
/* don't register Thunderbolt eGPU with vga_switcheroo */
-   if (pci_is_thunderbolt_attached(pdev))
+   if (dev_is_removable(>dev))
return;
 
vga_switcheroo_register_client(pdev, _switcheroo_ops, runtime);
@@ -120,7 +120,7 @@ nouveau_vga_fini(struct nouveau_drm *drm)
 
vga_client_unregister(pdev);
 
-   if (pci_is_thunderbolt_attached(pdev))
+   if (dev_is_removable(>dev))
return;
 
vga_switcheroo_unregister_client(pdev);
-- 
2.34.1



[PATCH v5 4/7] drm/amd: drop the use of `pci_is_thunderbolt_attached`

2022-02-24 Thread Mario Limonciello
Currently `pci_is_thunderbolt_attached` is used to indicate a device
is connected externally.

The PCI core now marks such devices as removable and downstream drivers
can use this instead.

Reviewed-by: Macpaul Lin 
Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +-
 drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 1ebb91db2274..6dbf5753b5be 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -161,7 +161,7 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, 
unsigned long flags)
(amdgpu_is_atpx_hybrid() ||
 amdgpu_has_atpx_dgpu_power_cntl()) &&
((flags & AMD_IS_APU) == 0) &&
-   !pci_is_thunderbolt_attached(to_pci_dev(dev->dev)))
+   !dev_is_removable(>pdev->dev))
flags |= AMD_IS_PX;
 
parent = pci_upstream_bridge(adev->pdev);
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c 
b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
index ee7cab37dfd5..2c5d74d836f0 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
@@ -382,7 +382,7 @@ static void nbio_v2_3_enable_aspm(struct amdgpu_device 
*adev,
 
data |= NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT << 
PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT;
 
-   if (pci_is_thunderbolt_attached(adev->pdev))
+   if (dev_is_removable(>pdev->dev))
data |= NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT  << 
PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
else
data |= NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT << 
PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
-- 
2.34.1



[PATCH v5 7/7] PCI: drop `pci_is_thunderbolt_attached`

2022-02-24 Thread Mario Limonciello
Currently `pci_is_thunderbolt_attached` is used to indicate a device
is connected externally.

As all drivers now look at the removable attribute, drop this function.

Signed-off-by: Mario Limonciello 
---
 include/linux/pci.h | 22 --
 1 file changed, 22 deletions(-)

diff --git a/include/linux/pci.h b/include/linux/pci.h
index d9719eb14654..089e7e36a0d9 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -2434,28 +2434,6 @@ static inline bool pci_ari_enabled(struct pci_bus *bus)
return bus->self && bus->self->ari_enabled;
 }
 
-/**
- * pci_is_thunderbolt_attached - whether device is on a Thunderbolt daisy chain
- * @pdev: PCI device to check
- *
- * Walk upwards from @pdev and check for each encountered bridge if it's part
- * of a Thunderbolt controller.  Reaching the host bridge means @pdev is not
- * Thunderbolt-attached.  (But rather soldered to the mainboard usually.)
- */
-static inline bool pci_is_thunderbolt_attached(struct pci_dev *pdev)
-{
-   struct pci_dev *parent = pdev;
-
-   if (dev_is_removable(>dev))
-   return true;
-
-   while ((parent = pci_upstream_bridge(parent)))
-   if (dev_is_removable(>dev))
-   return true;
-
-   return false;
-}
-
 #if defined(CONFIG_PCIEPORTBUS) || defined(CONFIG_EEH)
 void pci_uevent_ers(struct pci_dev *pdev, enum  pci_ers_result err_type);
 #endif
-- 
2.34.1



[PATCH v5 6/7] drm/radeon: drop the use of `pci_is_thunderbolt_attached`

2022-02-24 Thread Mario Limonciello
Currently `pci_is_thunderbolt_attached` is used to indicate a device
is connected externally.

The PCI core now marks such devices as removable and downstream drivers
can use this instead.

Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/radeon/radeon_device.c | 4 ++--
 drivers/gpu/drm/radeon/radeon_kms.c| 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 4f0fbf667431..5117fce23b3f 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1439,7 +1439,7 @@ int radeon_device_init(struct radeon_device *rdev,
 
if (rdev->flags & RADEON_IS_PX)
runtime = true;
-   if (!pci_is_thunderbolt_attached(rdev->pdev))
+   if (!dev_is_removable(>pdev->dev))
vga_switcheroo_register_client(rdev->pdev,
   _switcheroo_ops, runtime);
if (runtime)
@@ -1527,7 +1527,7 @@ void radeon_device_fini(struct radeon_device *rdev)
/* evict vram memory */
radeon_bo_evict_vram(rdev);
radeon_fini(rdev);
-   if (!pci_is_thunderbolt_attached(rdev->pdev))
+   if (!dev_is_removable(>pdev->dev))
vga_switcheroo_unregister_client(rdev->pdev);
if (rdev->flags & RADEON_IS_PX)
vga_switcheroo_fini_domain_pm_ops(rdev->dev);
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c 
b/drivers/gpu/drm/radeon/radeon_kms.c
index 11ad210919c8..e01ee7a5cf5d 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -139,7 +139,7 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned 
long flags)
if ((radeon_runtime_pm != 0) &&
radeon_has_atpx() &&
((flags & RADEON_IS_IGP) == 0) &&
-   !pci_is_thunderbolt_attached(pdev))
+   !dev_is_removable(>dev))
flags |= RADEON_IS_PX;
 
/* radeon_device_init should report only fatal error
-- 
2.34.1



[PATCH v5 1/7] PCI: Move `is_thunderbolt` check for lack of command completed to a quirk

2022-02-24 Thread Mario Limonciello
The `is_thunderbolt` check is currently used to indicate the lack of
command completed support for a number of older Thunderbolt devices.

This however is heavy handed and should have been done via a quirk.  Move
the affected devices outlined in commit 493fb50e958c ("PCI: pciehp: Assume
NoCompl+ for Thunderbolt ports") into pci quirks.

Suggested-by: Lukas Wunner 
Signed-off-by: Mario Limonciello 
---
 drivers/pci/hotplug/pciehp_hpc.c |  6 +-
 drivers/pci/quirks.c | 17 +
 include/linux/pci.h  |  2 ++
 3 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 1c1ebf3dad43..e4c42b24aba8 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -996,11 +996,7 @@ struct controller *pcie_init(struct pcie_device *dev)
if (pdev->hotplug_user_indicators)
slot_cap &= ~(PCI_EXP_SLTCAP_AIP | PCI_EXP_SLTCAP_PIP);
 
-   /*
-* We assume no Thunderbolt controllers support Command Complete events,
-* but some controllers falsely claim they do.
-*/
-   if (pdev->is_thunderbolt)
+   if (pdev->no_cmd_complete)
slot_cap |= PCI_EXP_SLTCAP_NCCS;
 
ctrl->slot_cap = slot_cap;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 65f7f6b0576c..ceeca7d8dd90 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3675,6 +3675,23 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
quirk_thunderbolt_hotplug_msi);
 
+static void quirk_thunderbolt_command_completed(struct pci_dev *pdev)
+{
+   pdev->no_cmd_complete = 1;
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LIGHT_RIDGE,
+   quirk_thunderbolt_command_completed);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EAGLE_RIDGE,
+   quirk_thunderbolt_command_completed);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LIGHT_PEAK,
+   quirk_thunderbolt_command_completed);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C,
+   quirk_thunderbolt_command_completed);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C,
+   quirk_thunderbolt_command_completed);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
+   quirk_thunderbolt_command_completed);
+
 #ifdef CONFIG_ACPI
 /*
  * Apple: Shutdown Cactus Ridge Thunderbolt controller.
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 8253a5413d7c..1e5b769e42fc 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -443,6 +443,8 @@ struct pci_dev {
unsigned intis_hotplug_bridge:1;
unsigned intshpc_managed:1; /* SHPC owned by shpchp */
unsigned intis_thunderbolt:1;   /* Thunderbolt controller */
+   unsigned intno_cmd_complete:1;  /* Lies about command completed 
events */
+
/*
 * Devices marked being untrusted are the ones that can potentially
 * execute DMA attacks and similar. They are typically connected
-- 
2.34.1



[PATCH v5 3/7] PCI: Drop the `is_thunderbolt` attribute from PCI core

2022-02-24 Thread Mario Limonciello
The `is_thunderbolt` attribute originally had a well defined list of
quirks that it existed for, but it has been overloaded with more
meaning.

Instead use the driver core removable attribute to indicate the
detail a device is attached to a thunderbolt or USB4 chain.

Signed-off-by: Mario Limonciello 
---
 drivers/pci/probe.c   | 2 +-
 drivers/platform/x86/apple-gmux.c | 2 +-
 include/linux/pci.h   | 5 ++---
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 17a969942d37..1b752d425c47 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1584,7 +1584,7 @@ static void set_pcie_thunderbolt(struct pci_dev *dev)
/* Is the device part of a Thunderbolt controller? */
vsec = pci_find_vsec_capability(dev, PCI_VENDOR_ID_INTEL, 
PCI_VSEC_ID_INTEL_TBT);
if (vsec)
-   dev->is_thunderbolt = 1;
+   dev->external_facing = true;
 }
 
 static void set_pcie_untrusted(struct pci_dev *dev)
diff --git a/drivers/platform/x86/apple-gmux.c 
b/drivers/platform/x86/apple-gmux.c
index 57553f9b4d1d..da0c39b0 100644
--- a/drivers/platform/x86/apple-gmux.c
+++ b/drivers/platform/x86/apple-gmux.c
@@ -596,7 +596,7 @@ static int gmux_resume(struct device *dev)
 
 static int is_thunderbolt(struct device *dev, void *data)
 {
-   return to_pci_dev(dev)->is_thunderbolt;
+   return to_pci_dev(dev)->external_facing;
 }
 
 static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1e5b769e42fc..d9719eb14654 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -442,7 +442,6 @@ struct pci_dev {
unsigned intis_virtfn:1;
unsigned intis_hotplug_bridge:1;
unsigned intshpc_managed:1; /* SHPC owned by shpchp */
-   unsigned intis_thunderbolt:1;   /* Thunderbolt controller */
unsigned intno_cmd_complete:1;  /* Lies about command completed 
events */
 
/*
@@ -2447,11 +2446,11 @@ static inline bool pci_is_thunderbolt_attached(struct 
pci_dev *pdev)
 {
struct pci_dev *parent = pdev;
 
-   if (pdev->is_thunderbolt)
+   if (dev_is_removable(>dev))
return true;
 
while ((parent = pci_upstream_bridge(parent)))
-   if (parent->is_thunderbolt)
+   if (dev_is_removable(>dev))
return true;
 
return false;
-- 
2.34.1



[PATCH v5 2/7] PCI: Move check for old Apple Thunderbolt controllers into a quirk

2022-02-24 Thread Mario Limonciello
`pci_bridge_d3_possible` currently checks explicitly for a Thunderbolt
controller to indicate that D3 is possible.

This is used solely for older Apple systems, due to a variety of factors:
* Apple used SW connection manager from the beginning, other manufacturers
  used a FW connection manager (ICM)
* Apple supported D3 initially, other manfuacturers didn't introduced this
  until the `HotplugSupportInD3` _DSD was introduced in ~2015.

Apple has stopped creating new machines with Intel Thunderbolt controllers,
and all other manufacturers now support D3 via `HotPlugSupportInD3` so
this should be a fixed list.

Suggested-by: Mika Westerberg 
Signed-off-by: Mario Limonciello 
---
 drivers/pci/pci.c| 17 +++
 drivers/pci/quirks.c | 67 
 2 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 9ecce435fb3f..01557c950c9f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1064,7 +1064,18 @@ static inline bool platform_pci_bridge_d3(struct pci_dev 
*dev)
if (pci_use_mid_pm())
return false;
 
-   return acpi_pci_bridge_d3(dev);
+   if (acpi_pci_bridge_d3(dev))
+   return true;
+
+   /*
+* This is for Apple machines via a quirk
+* Non-Apple machines will use the ACPI property with the same name
+* from `acpi_pci_bridge_d3` to indciate support.
+*/
+   if (device_property_read_bool(>dev, "HotPlugSupportInD3"))
+   return true;
+
+   return false;
 }
 
 /**
@@ -2954,10 +2965,6 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge)
if (pci_bridge_d3_force)
return true;
 
-   /* Even the oldest 2010 Thunderbolt controller supports D3. */
-   if (bridge->is_thunderbolt)
-   return true;
-
/* Platform might know better if the bridge supports D3 */
if (platform_pci_bridge_d3(bridge))
return true;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index ceeca7d8dd90..f74f50ea0695 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3756,6 +3756,73 @@ DECLARE_PCI_FIXUP_SUSPEND_LATE(PCI_VENDOR_ID_INTEL,
   quirk_apple_poweroff_thunderbolt);
 #endif
 
+/*
+ * The first machines supporting Intel Thunderbolt were released by Apple, and
+ * supported a software based connection manager including D3 support, as far
+ * back as 2010. These machines don't have ACPI companions to declare D3
+ * support.
+ *
+ * Other manufacturers introduced Thunderbolt shortly after but notably did not
+ * support:
+ * - Software based connection manager
+ * - Runtime power management
+ * Power management was handled via the BIOS when nothing was plugged in.
+ * Runtime D3 was later introduced in ~2015 and Microsoft declared when the
+ * `HotPlugSupportInD3` _DSD was present that they would support D3.
+ *
+ * This list is expected to be complete and not grow in the future as Apple
+ * has stopped producing new x86 models with Intel Thunderbolt controllers.
+ */
+static void quirk_apple_d3_thunderbolt(struct pci_dev *dev)
+{
+   struct property_entry properties[] = {
+   PROPERTY_ENTRY_BOOL("HotPlugSupportInD3"),
+   {},
+   };
+
+   if (!x86_apple_machine)
+   return;
+
+   if (device_create_managed_software_node(>dev, properties, NULL))
+   pci_warn(dev, "could not add HotPlugSupportInD3 property");
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LIGHT_RIDGE,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EAGLE_RIDGE,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LIGHT_PEAK,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_NHI,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_BRIDGE,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_NHI,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_BRIDGE,
+   quirk_apple_d3_thunderbolt);

[PATCH v5 0/7] Overhaul `is_thunderbolt`

2022-02-24 Thread Mario Limonciello
Various drivers in the kernel use `is_thunderbolt` or
`pci_is_thunderbolt_attached` to designate behaving differently
from a device that is internally in the machine. This currently works
by an attribute in PCI core "is_thunderbolt" which makes those drivers
only apply differences when Intel Thunderbolt controllers are encountered.

In each of these drivers' cases the code should apply whether it's another
vendor's USB4 controller or an Intel USB4/TBT3 controller.

As such, overhaul the use of "is_thunderbolt" in the PCI core to instead rally
around the device core "external" attribute. This means dropping the extra PCI
core attribute and the extra function designation to indicate thunderbolt 
attached.

Changes from v4->v5:
- Drop USB4 related patches.  Thoes may come at a later time if they're proven 
to be needed.
  At least in the integrated case vendors should be setting the _DSD to 
indicate the port is
  externally facing.
  For the discrete case we may bring it back later.

Changes from v3->v4:
- Add tags from last review where applicable
- Update titles of different patches
- Add more comments and commit messages to various patches to address
  comments raised in review
- Re-order the patch series, moving more contentious patches later
- Drop patch marking NHI removable
- Drop patch changing gmux on it's own, roll into patch to drop
  `is_thunderbolt`
- Modify patch to mark integrated USB4 tunnel PCIe root ports as
  "external" instead of removable.
- Modify patch to mark discrete USB4 tunnel root ports as "external"
  instead of removable.
- Fix bit mask error in discrete USB4 tunnel patch
- Fix USB IF vendor designation location in pci_ids.h

Changes from v2->v3:
- Add various tags for patches that haven't changed from v2->v3
- Add new patches for Mika's suggestions:
  * Moving Apple Thunderbolt D3 declaration into quirks
  * Detect PCIe root port used for PCIe tunneling on integrated
controllers using `usb4-host-interface`
  * Detect PCIe root port used for PCIe tunneling on discrete
controllers using the USB4 DVSEC specification

Changes from v1->v2:
- Add Alex's tag to first patch
- Move lack of command completion into a quirk (Lukas)
- Drop `is_thunderbolt` attribute and `pci_is_thunderbolt_attached` and
  use device core removable attribute instead
- Adjust all consumers of old attribute to use removable

Note: this spans USB/DRM/platform-x86/PCI trees.
As a majority of the changes are in PCI, it should probably come through
that tree if possible.


Mario Limonciello (7):
  PCI: Move `is_thunderbolt` check for lack of command completed to a
quirk
  PCI: Move check for old Apple Thunderbolt controllers into a quirk
  PCI: Drop the `is_thunderbolt` attribute from PCI core
  drm/amd: drop the use of `pci_is_thunderbolt_attached`
  drm/nouveau: drop the use of `pci_is_thunderbolt_attached`
  drm/radeon: drop the use of `pci_is_thunderbolt_attached`
  PCI: drop `pci_is_thunderbolt_attached`

 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c |  2 +-
 drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c  |  2 +-
 drivers/gpu/drm/nouveau/nouveau_vga.c   |  4 +-
 drivers/gpu/drm/radeon/radeon_device.c  |  4 +-
 drivers/gpu/drm/radeon/radeon_kms.c |  2 +-
 drivers/pci/hotplug/pciehp_hpc.c|  6 +-
 drivers/pci/pci.c   | 17 +++--
 drivers/pci/probe.c |  2 +-
 drivers/pci/quirks.c| 84 +
 drivers/platform/x86/apple-gmux.c   |  2 +-
 include/linux/pci.h | 25 +---
 11 files changed, 108 insertions(+), 42 deletions(-)

-- 
2.34.1



Re: [Intel-gfx] [PATCH 5/8] drm/i915/guc: Move lrc desc setup to where it is needed

2022-02-24 Thread John Harrison

On 2/23/2022 18:03, Ceraolo Spurio, Daniele wrote:

On 2/23/2022 12:23 PM, John Harrison wrote:

On 2/22/2022 17:12, Ceraolo Spurio, Daniele wrote:

On 2/17/2022 3:52 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

The LRC descriptor was being initialised early on in the context
registration sequence. It could then be determined that the actual
registration needs to be delayed and the descriptor would be wiped
out. This is inefficient, so move the setup to later in the process
after the point of no return.

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 11 +--
  1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c

index 0ab2d1a24bf6..aa74ec74194a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2153,6 +2153,8 @@ static int 
__guc_action_register_context(struct intel_guc *guc,

   0, loop);
  }
  +static void prepare_context_registration_info(struct 
intel_context *ce);

+
  static int register_context(struct intel_context *ce, bool loop)
  {
  struct intel_guc *guc = ce_to_guc(ce);
@@ -2163,6 +2165,8 @@ static int register_context(struct 
intel_context *ce, bool loop)

  GEM_BUG_ON(intel_context_is_child(ce));
  trace_intel_context_register(ce);
  +    prepare_context_registration_info(ce);
+
  if (intel_context_is_parent(ce))
  ret = __guc_action_register_multi_lrc(guc, ce, 
ce->guc_id.id,

    offset, loop);
@@ -2246,7 +2250,6 @@ static void 
prepare_context_registration_info(struct intel_context *ce)

  struct intel_context *child;
    GEM_BUG_ON(!engine->mask);
-    GEM_BUG_ON(!sched_state_is_init(ce));
    /*
   * Ensure LRC + CT vmas are is same region as write barrier 
is done
@@ -2314,9 +2317,13 @@ static int try_context_registration(struct 
intel_context *ce, bool loop)

  bool context_registered;
  int ret = 0;
  +    GEM_BUG_ON(!sched_state_is_init(ce));
+
  context_registered = ctx_id_mapped(guc, desc_idx);
  -    prepare_context_registration_info(ce);
+    if (context_registered)
+    clr_ctx_id_mapping(guc, desc_idx);
+    set_ctx_id_mapping(guc, desc_idx, ce);


I think we can do the clr unconditionally. Also, should we drop the 
clr/set pair in prepare_context_registration_info? it shouldn't be 
needed, unless I'm missing a path where we don;t pass through here.


Daniele

I don't believe so.

The point is that the context id might have changed (it got stolen, 
re-used, etc. - all the state machine code below can cause aborts and 
retries and such like if something is pending and the register needs 
to be delayed). So we need to clear out the old mapping and add a new 
one to be safe. Also, I'm not sure if it is safe to do a xa_store to 
an already used entry as an update or if you are supposed to clear it 
first? But that's what the code did before and I'm trying to not 
change any actual behaviour here.


I was comparing with previous behavior. before this patch, we only do 
the setting of the ctx_id here (inside 
prepare_context_registration_info) and you're not changing any of the 
abort/retry behavior, so if it was enough before it should be enough now.
Hmm, I think I must have confused myself with the intermediate steps 
along the way. Yes, it looks like the clr/set in prepare is redundant by 
the end.




Regarding the xa ops, we did an unconditional clear before, so it 
should be ok to just do the same and have the clear and set back to 
back without checking if the context ID was already in use or not.
Actually, I was thinking you meant to drop the clr completely rather 
than just drop the condition. Yeah, that sounds fine.


Will post an update.

John.



Daniele



John.




    /*
   * The context_lookup xarray is used to determine if the 
hardware










Re: [RFC PATCH v2 3/5] drm/msm/dp: support finding next bridge even for DP interfaces

2022-02-24 Thread Abhinav Kumar




On 2/24/2022 12:49 PM, Dmitry Baryshkov wrote:

On Thu, 24 Feb 2022 at 23:13, Abhinav Kumar  wrote:




On 2/11/2022 2:40 PM, Dmitry Baryshkov wrote:

It is possible to supply display-connector (bridge) to the DP interface,
add support for parsing it too.

Signed-off-by: Dmitry Baryshkov 
---
   drivers/gpu/drm/msm/dp/dp_parser.c | 19 ---
   1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c 
b/drivers/gpu/drm/msm/dp/dp_parser.c
index 901d7967370f..1056b8d5755b 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -301,17 +301,22 @@ static int dp_parser_parse(struct dp_parser *parser, int 
connector_type)
   return rc;

   /*
-  * Currently we support external bridges only for eDP connectors.
+  * External bridges are mandatory for eDP interfaces: one has to
+  * provide at least an eDP panel (which gets wrapped into panel-bridge).
*
-  * No external bridges are expected for the DisplayPort connector,
-  * it is physically present in a form of a DP or USB-C connector.
+  * For DisplayPort interfaces external bridges are optional, so
+  * silently ignore an error if one is not present (-ENODEV).
*/
- if (connector_type == DRM_MODE_CONNECTOR_eDP) {
- rc = dp_parser_find_next_bridge(parser);
- if (rc) {
- DRM_ERROR("DP: failed to find next bridge\n");
+ rc = dp_parser_find_next_bridge(parser);
+ if (rc == -ENODEV) {
+ if (connector_type == DRM_MODE_CONNECTOR_eDP) {
+ DRM_ERROR("eDP: next bridge is not present\n");
   return rc;
   }
+ } else if (rc) {
+ if (rc != -EPROBE_DEFER)
+ DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
+ return rc;
   }


How is this silently ignoring?

static int dp_display_bind(struct device *dev, struct device *master,
 void *data)
{
  int rc = 0;
  struct dp_display_private *dp = dev_get_dp_display_private(dev);
  struct msm_drm_private *priv = dev_get_drvdata(master);
  struct drm_device *drm = priv->dev;

  dp->dp_display.drm_dev = drm;
  priv->dp[dp->id] = >dp_display;

  rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type);
  if (rc) {
  DRM_ERROR("device tree parsing failed\n");
  goto end;
  }

dp_display_bind will still fail if a bridge is not found.

If supplying a bridge is optional even this should succeed right?


It will succeed as dp_parser_parse() will not return -ENODEV if the
connector is not eDP.
To rephrase the comment:
For the dp_parser_find_next_bridge() result:
- for eDP the driver passes all errors to the calling function.
- for DP the driver ignores -ENODEV (no external bridge is supplied),
but passes all other errors (which can mean e.g. that the bridge is
not properly declared or that it did hasn't been probed yet).



Ah okay, I just noticed that dp_parser_parse() returns 0 by default and 
not rc.


So in this case it will still return 0.

Hence this change LGTM,

Reviewed-by: Abhinav Kumar 


  1   2   >