Re: [PATCH v2 0/8] drm/msm: DSC Electric Boogaloo for sm8[12]50

2023-01-08 Thread Marijn Suijten
On 2023-01-05 15:49:58, Daniel Vetter wrote:
> On Thu, Dec 22, 2022 at 12:19:35AM +0100, Marijn Suijten wrote:
> > [..]
> 
> Please note that Electric Boogaloo/Boogaloo Boys has been appropriated by
> US alt-right groups, and so is really not a great thing to put into the
> cover letter for your patch series. For the next round, please use a meme
> that isn't tarnished like this.

Apologies for that, I wasn't aware of this abuse as a non-US citizen and
hope this series is not offending anyone.

As far as I recall this series was set to be applied for 6.3 yet Dmitry
seems to have just posted some additional comments.  May have been
confusion on my end.

Hence we do now need another cheeky title, conveying that we're already
on the second round of fixes for DSC and it is still not working on
major SoCs/boards.

- Marijn



Re: [PATCH v5 1/4] dt-bindings: display/msm: convert MDP5 schema to YAML format

2023-01-08 Thread Marijn Suijten
On 2023-01-09 07:01:49, Dmitry Baryshkov wrote:
> Convert the mdp5.txt into the yaml format. Changes to the existing (txt) 
> schema:
>  - MSM8996 has additional "iommu" clock, define it separately
>  - Add new properties used on some of platforms:
>- interconnects, interconnect-names
>- iommus
>- power-domains
>- operating-points-v2, opp-table
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../devicetree/bindings/display/msm/mdp5.txt  | 132 -
>  .../bindings/display/msm/qcom,mdp5.yaml   | 138 ++
>  2 files changed, 138 insertions(+), 132 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/display/msm/mdp5.txt
>  create mode 100644 
> Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/msm/mdp5.txt 
> b/Documentation/devicetree/bindings/display/msm/mdp5.txt
> deleted file mode 100644
> index 65d03c58dee6..
> --- a/Documentation/devicetree/bindings/display/msm/mdp5.txt
> +++ /dev/null
> @@ -1,132 +0,0 @@
> -Qualcomm adreno/snapdragon MDP5 display controller
> -
> -Description:
> -
> -This is the bindings documentation for the MDP5 display
> -controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994 and MSM8996.
> -
> -MDP5:
> -Required properties:
> -- compatible:
> -  * "qcom,mdp5" - MDP5
> -- reg: Physical base address and length of the controller's registers.
> -- reg-names: The names of register regions. The following regions are 
> required:
> -  * "mdp_phys"
> -- interrupts: Interrupt line from MDP5 to MDSS interrupt controller.
> -- clocks: device clocks. See ../clocks/clock-bindings.txt for details.
> -- clock-names: the following clocks are required.
> --   * "bus"
> --   * "iface"
> --   * "core"
> --   * "vsync"
> -- ports: contains the list of output ports from MDP. These connect to 
> interfaces
> -  that are external to the MDP hardware, such as HDMI, DSI, EDP etc (LVDS is 
> a
> -  special case since it is a part of the MDP block itself).
> -
> -  Each output port contains an endpoint that describes how it is connected 
> to an
> -  external interface. These are described by the standard properties 
> documented
> -  here:
> - Documentation/devicetree/bindings/graph.txt
> - Documentation/devicetree/bindings/media/video-interfaces.txt
> -
> -  The availability of output ports can vary across SoC revisions:
> -
> -  For MSM8974 and APQ8084:
> -  Port 0 -> MDP_INTF0 (eDP)
> -  Port 1 -> MDP_INTF1 (DSI1)
> -  Port 2 -> MDP_INTF2 (DSI2)
> -  Port 3 -> MDP_INTF3 (HDMI)
> -
> -  For MSM8916:
> -  Port 0 -> MDP_INTF1 (DSI1)
> -
> -  For MSM8994 and MSM8996:
> -  Port 0 -> MDP_INTF1 (DSI1)
> -  Port 1 -> MDP_INTF2 (DSI2)
> -  Port 2 -> MDP_INTF3 (HDMI)
> -
> -Optional properties:
> -- clock-names: the following clocks are optional:
> -  * "lut"
> -  * "tbu"
> -  * "tbu_rt"
> -
> -Example:
> -
> -/ {
> - ...
> -
> - mdss: mdss@1a0 {
> - compatible = "qcom,mdss";
> - reg = <0x1a0 0x1000>,
> -   <0x1ac8000 0x3000>;
> - reg-names = "mdss_phys", "vbif_phys";
> -
> - power-domains = < MDSS_GDSC>;
> -
> - clocks = < GCC_MDSS_AHB_CLK>,
> -  < GCC_MDSS_AXI_CLK>,
> -  < GCC_MDSS_VSYNC_CLK>;
> - clock-names = "iface",
> -   "bus",
> -   "vsync"
> -
> - interrupts = <0 72 0>;
> -
> - interrupt-controller;
> - #interrupt-cells = <1>;
> -
> - #address-cells = <1>;
> - #size-cells = <1>;
> - ranges;
> -
> - mdp: mdp@1a01000 {
> - compatible = "qcom,mdp5";
> - reg = <0x1a01000 0x9>;
> - reg-names = "mdp_phys";
> -
> - interrupt-parent = <>;
> - interrupts = <0 0>;
> -
> - clocks = < GCC_MDSS_AHB_CLK>,
> -  < GCC_MDSS_AXI_CLK>,
> -  < GCC_MDSS_MDP_CLK>,
> -  < GCC_MDSS_VSYNC_CLK>;
> - clock-names = "iface",
> -   "bus",
> -   "core",
> -   "vsync";
> -
> - ports {
> - #address-cells = <1>;
> - #size-cells = <0>;
> -
> - port@0 {
> - reg = <0>;
> - mdp5_intf1_out: endpoint {
> - remote-endpoint = <_in>;
> - };
> - };
> - };
> - };
> -
> - dsi0: dsi@1a98000 {
> - ...
> - ports 

Re: [PATCH 09/15] staging: fbtft: fb_ssd1351.c: Introduce backlight_is_blank()

2023-01-08 Thread Stephen Kitt
Hi Sam,

On Sun, 8 Jan 2023 21:29:43 +0100, Sam Ravnborg  wrote:
> On Sun, Jan 08, 2023 at 08:28:17PM +0100, Stephen Kitt wrote:
> > On Sat, 07 Jan 2023 19:26:23 +0100, Sam Ravnborg via B4 Submission
> > Endpoint  wrote:
> >   
> > > From: Sam Ravnborg 
> > > 
> > > Avoiding direct access to backlight_properties.props.
> > > 
> > > Access to the deprecated props.fb_blank replaced by
> > > backlight_is_blank(). Access to props.power is dropped - it was only
> > > used for debug.
> > > 
> > > Signed-off-by: Sam Ravnborg 
> > > Cc: Stephen Kitt 
> > > Cc: Greg Kroah-Hartman 
> > > Cc: Daniel Thompson 
> > > Cc: Andy Shevchenko 
> > > Cc: linux-fb...@vger.kernel.org
> > > ---
> > >  drivers/staging/fbtft/fb_ssd1351.c | 9 +++--
> > >  1 file changed, 3 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/drivers/staging/fbtft/fb_ssd1351.c
> > > b/drivers/staging/fbtft/fb_ssd1351.c index b8d55aa8c5c7..995fbd2f3dc6
> > > 100644 --- a/drivers/staging/fbtft/fb_ssd1351.c
> > > +++ b/drivers/staging/fbtft/fb_ssd1351.c
> > > @@ -190,15 +190,12 @@ static struct fbtft_display display = {
> > >  static int update_onboard_backlight(struct backlight_device *bd)
> > >  {
> > >   struct fbtft_par *par = bl_get_data(bd);
> > > - bool on;
> > > + bool blank = backlight_is_blank(bd);
> > >  
> > > - fbtft_par_dbg(DEBUG_BACKLIGHT, par,
> > > -   "%s: power=%d, fb_blank=%d\n",
> > > -   __func__, bd->props.power, bd->props.fb_blank);
> > > + fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s: blank=%d\n", __func__,
> > > blank); 
> > > - on = !backlight_is_blank(bd);
> > >   /* Onboard backlight connected to GPIO0 on SSD1351, GPIO1
> > > unused */
> > > - write_reg(par, 0xB5, on ? 0x03 : 0x02);
> > > + write_reg(par, 0xB5, !blank ? 0x03 : 0x02);
> > >  
> > >   return 0;
> > >  }
> > > 
> > > -- 
> > > 2.34.1  
> > 
> > For debugging purposes here, would there be any point in logging
> > props.state? As in
> > 
> > fbtft_par_dbg(DEBUG_BACKLIGHT, par,
> > - "%s: power=%d, fb_blank=%d\n",
> > - __func__, bd->props.power, bd->props.fb_blank);
> > + "%s: power=%d, state=%u\n",
> > + __func__, bd->props.power, bd->props.state);  
> 
> Thanks for the suggestion - and the reviews!
> 
> I was tempted to just remove the debugging.
> If we require debugging, then this could be added in the backlight core,
> thus everyone would benefit from it.
> 
> The solution above avoid any direct use of backlight_properties
> which I consider a layer violation outside the backlight core.
> (We cannot avoid it today with the current interface - but we can
> minimize it).

Ah yes, ideally backlight_properties should be viewed as an opaque structure,
that makes sense.

Regards,

Stephen


pgpJ6VFZ1WlMv.pgp
Description: OpenPGP digital signature


[PATCH] dt-bindings: display/msm: gpu: add rbcpr clock

2023-01-08 Thread Dmitry Baryshkov
Describe the RBCPR clock used on msm8996 (A530), MSM8998 (A540) and
SDM630/660 (A508/A512).

Signed-off-by: Dmitry Baryshkov 
---
 Documentation/devicetree/bindings/display/msm/gpu.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml 
b/Documentation/devicetree/bindings/display/msm/gpu.yaml
index c5f49842dc7b..db8afc636576 100644
--- a/Documentation/devicetree/bindings/display/msm/gpu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml
@@ -149,6 +149,8 @@ allOf:
 description: GPU 3D engine clock
   - const: rbbmtimer
 description: GPU RBBM Timer for Adreno 5xx series
+  - const: rbcpr
+description: GPU RB Core Power Reduction clock
   minItems: 2
   maxItems: 7
 
-- 
2.39.0



[PATCH 4/6] ARM: dts: qcom-msm8974: rename mdss node to display-subsystem

2023-01-08 Thread Dmitry Baryshkov
Follow the schema change and rename mdss node to generic name
'display-subsystem'.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 0cd59088f9c7..bb69247d7ebd 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1525,7 +1525,7 @@ mmcc: clock-controller@fd8c {
reg = <0xfd8c 0x6000>;
};
 
-   mdss: mdss@fd90 {
+   mdss: display-subsystem@fd90 {
compatible = "qcom,mdss";
reg = <0xfd90 0x100>, <0xfd924000 0x1000>;
reg-names = "mdss_phys", "vbif_phys";
-- 
2.39.0



[PATCH 6/6] ARM: dts: qcom: rename mdp nodes to display-controller

2023-01-08 Thread Dmitry Baryshkov
Follow the schema change and rename mdp nodes to generic name
'display-controller'.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm/boot/dts/qcom-apq8064.dtsi | 2 +-
 arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi 
b/arch/arm/boot/dts/qcom-apq8064.dtsi
index 363e75078a0a..5fdd78477666 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -1492,7 +1492,7 @@ hdmi_phy: phy@4a00400 {
status = "disabled";
};
 
-   mdp: mdp@510 {
+   mdp: display-controller@510 {
compatible = "qcom,mdp4";
reg = <0x0510 0xf>;
interrupts = ;
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index bb69247d7ebd..96b78bd85f35 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1548,7 +1548,7 @@ mdss: display-subsystem@fd90 {
#size-cells = <1>;
ranges;
 
-   mdp: mdp@fd90 {
+   mdp: display-controller@fd90 {
compatible = "qcom,msm8974-mdp5", "qcom,mdp5";
reg = <0xfd900100 0x22000>;
reg-names = "mdp_phys";
-- 
2.39.0



[PATCH 2/6] dt-bindings: display/msm: rename mdp nodes to display-controller

2023-01-08 Thread Dmitry Baryshkov
Follow the 'generic names' rule and rename mdp nodes to
display-controller.

Signed-off-by: Dmitry Baryshkov 
---
 .../devicetree/bindings/display/msm/dpu-common.yaml   | 8 
 .../devicetree/bindings/display/msm/qcom,mdp5.yaml| 3 +++
 .../devicetree/bindings/display/msm/qcom,mdss.yaml| 6 +++---
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/dpu-common.yaml 
b/Documentation/devicetree/bindings/display/msm/dpu-common.yaml
index 870158bb2aa0..3f953aa5e694 100644
--- a/Documentation/devicetree/bindings/display/msm/dpu-common.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dpu-common.yaml
@@ -13,7 +13,15 @@ maintainers:
 description: |
   Common properties for QCom DPU display controller.
 
+# Do not select this by default, otherwise it is also selected for all
+# display-controller@ nodes
+select:
+  false
+
 properties:
+  $nodename:
+pattern: '^display-controller@[0-9a-f]+$'
+
   interrupts:
 maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
index 681d6ac48d33..cbe4d3597f26 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
@@ -33,6 +33,9 @@ properties:
   - qcom,sdm660-mdp5
   - const: qcom,mdp5
 
+  $nodename:
+pattern: '^display-controller@[0-9a-f]+$'
+
   reg:
 maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
index 47fde9b6779f..1a2f639f8a9a 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
@@ -105,7 +105,7 @@ required:
   - ranges
 
 patternProperties:
-  "^mdp@[1-9a-f][0-9a-f]*$":
+  "^display-controller@[1-9a-f][0-9a-f]*$":
 type: object
 properties:
   compatible:
@@ -180,8 +180,8 @@ examples:
 #size-cells = <1>;
 ranges;
 
-mdp@1a01000 {
-compatible = "qcom,mdp5";
+display-controller@1a01000 {
+compatible = "qcom,msm8916-mdp5", "qcom,mdp5";
 reg = <0x01a01000 0x89000>;
 reg-names = "mdp_phys";
 
-- 
2.39.0



[PATCH 1/6] dt-bindings: display/msm: rename mdss nodes to display-sybsystem

2023-01-08 Thread Dmitry Baryshkov
Follow the 'generic names' rule and rename mdss nodes to
display-subsystem.

Signed-off-by: Dmitry Baryshkov 
---
 .../devicetree/bindings/display/msm/mdss-common.yaml  | 8 
 .../devicetree/bindings/display/msm/qcom,mdss.yaml| 5 -
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/msm/mdss-common.yaml 
b/Documentation/devicetree/bindings/display/msm/mdss-common.yaml
index 59f17ac898aa..ccd7d6417523 100644
--- a/Documentation/devicetree/bindings/display/msm/mdss-common.yaml
+++ b/Documentation/devicetree/bindings/display/msm/mdss-common.yaml
@@ -15,7 +15,15 @@ description:
   Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
   sub-blocks like DPU display controller, DSI and DP interfaces etc.
 
+# Do not select this by default, otherwise it is also selected for qcom,mdss
+# devices.
+select:
+  false
+
 properties:
+  $nodename:
+pattern: "^display-subsystem@[0-9a-f]+$"
+
   reg:
 maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
index c218c9172608..47fde9b6779f 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
@@ -15,6 +15,9 @@ description:
   encapsulates sub-blocks like MDP5, DSI, HDMI, eDP, etc.
 
 properties:
+  $nodename:
+pattern: "^display-subsystem@[0-9a-f]+$"
+
   compatible:
 enum:
   - qcom,mdss
@@ -153,7 +156,7 @@ examples:
   - |
 #include 
 #include 
-mdss@1a0 {
+display-subsystem@1a0 {
 compatible = "qcom,mdss";
 reg = <0x1a0 0x1000>,
   <0x1ac8000 0x3000>;
-- 
2.39.0



[PATCH 5/6] arm64: dts: qcom: rename mdp nodes to display-controller

2023-01-08 Thread Dmitry Baryshkov
Follow the schema change and rename mdp nodes to generic name
'display-controller'.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +-
 arch/arm64/boot/dts/qcom/msm8953.dtsi | 2 +-
 arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +-
 arch/arm64/boot/dts/qcom/sdm630.dtsi  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi 
b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 8f29d7e49423..591f5552c59d 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -988,7 +988,7 @@ mdss: display-subsystem@1a0 {
#size-cells = <1>;
ranges;
 
-   mdp: mdp@1a01000 {
+   mdp: display-controller@1a01000 {
compatible = "qcom,msm8916-mdp5", "qcom,mdp5";
reg = <0x01a01000 0x89000>;
reg-names = "mdp_phys";
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi 
b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index c07b707ff454..dbe506815310 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -755,7 +755,7 @@ mdss: display-subsystem@1a0 {
 
status = "disabled";
 
-   mdp: mdp@1a01000 {
+   mdp: display-controller@1a01000 {
compatible = "qcom,msm8953-mdp5", "qcom,mdp5";
reg = <0x1a01000 0x89000>;
reg-names = "mdp_phys";
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi 
b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index b30c35fffe68..409c3c34e8ee 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -930,7 +930,7 @@ mdss: display-subsystem@90 {
 
status = "disabled";
 
-   mdp: mdp@901000 {
+   mdp: display-controller@901000 {
compatible = "qcom,msm8996-mdp5", "qcom,mdp5";
reg = <0x00901000 0x9>;
reg-names = "mdp_phys";
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi 
b/arch/arm64/boot/dts/qcom/sdm630.dtsi
index 0bceda788341..9409ca3f3485 100644
--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -1497,7 +1497,7 @@ mdss: display-subsystem@c90 {
ranges;
status = "disabled";
 
-   mdp: mdp@c901000 {
+   mdp: display-controller@c901000 {
compatible = "qcom,sdm630-mdp5", "qcom,mdp5";
reg = <0x0c901000 0x89000>;
reg-names = "mdp_phys";
-- 
2.39.0



[PATCH 3/6] arm64: dts: qcom: rename mdss nodes to display-subsystem

2023-01-08 Thread Dmitry Baryshkov
Follow the schema change and rename mdss nodes to generic name
'display-subsystem'.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +-
 arch/arm64/boot/dts/qcom/msm8953.dtsi | 2 +-
 arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +-
 arch/arm64/boot/dts/qcom/sc7180.dtsi  | 2 +-
 arch/arm64/boot/dts/qcom/sdm630.dtsi  | 2 +-
 arch/arm64/boot/dts/qcom/sdm845.dtsi  | 2 +-
 arch/arm64/boot/dts/qcom/sm8250.dtsi  | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi 
b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 0a23fb6efae8..8f29d7e49423 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -963,7 +963,7 @@ tcsr: syscon@1937000 {
reg = <0x01937000 0x3>;
};
 
-   mdss: mdss@1a0 {
+   mdss: display-subsystem@1a0 {
status = "disabled";
compatible = "qcom,mdss";
reg = <0x01a0 0x1000>,
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi 
b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index 32349174c4bd..c07b707ff454 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -726,7 +726,7 @@ tcsr_phy_clk_scheme_sel: syscon@193f044 {
reg = <0x193f044 0x4>;
};
 
-   mdss: mdss@1a0 {
+   mdss: display-subsystem@1a0 {
compatible = "qcom,mdss";
 
reg = <0x1a0 0x1000>,
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi 
b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index b5cd1bcad5eb..b30c35fffe68 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -904,7 +904,7 @@ mmcc: clock-controller@8c {
   <82500>;
};
 
-   mdss: mdss@90 {
+   mdss: display-subsystem@90 {
compatible = "qcom,mdss";
 
reg = <0x0090 0x1000>,
diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi 
b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index f71cf21a8dd8..d951ea42ee45 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -2921,7 +2921,7 @@ camcc: clock-controller@ad0 {
#power-domain-cells = <1>;
};
 
-   mdss: mdss@ae0 {
+   mdss: display-subsystem@ae0 {
compatible = "qcom,sc7180-mdss";
reg = <0 0x0ae0 0 0x1000>;
reg-names = "mdss";
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi 
b/arch/arm64/boot/dts/qcom/sdm630.dtsi
index 65addd4c672e..0bceda788341 100644
--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -1470,7 +1470,7 @@ opp-26250 {
};
};
 
-   mdss: mdss@c90 {
+   mdss: display-subsystem@c90 {
compatible = "qcom,mdss";
reg = <0x0c90 0x1000>,
  <0x0c9b 0x1040>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 1d0198935136..fa62479206ce 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -4473,7 +4473,7 @@ opp-35800 {
};
};
 
-   mdss: mdss@ae0 {
+   mdss: display-subsystem@ae0 {
compatible = "qcom,sdm845-mdss";
reg = <0 0x0ae0 0 0x1000>;
reg-names = "mdss";
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi 
b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index dab5579946f3..75cd600c5ca3 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -3955,7 +3955,7 @@ camcc: clock-controller@ad0 {
#power-domain-cells = <1>;
};
 
-   mdss: mdss@ae0 {
+   mdss: display-subsystem@ae0 {
compatible = "qcom,sm8250-mdss";
reg = <0 0x0ae0 0 0x1000>;
reg-names = "mdss";
-- 
2.39.0



[PATCH 0/6] dt-bindings: display/msm: rename mdss and mdp nodes

2023-01-08 Thread Dmitry Baryshkov
Finish the process of renaming display-related nodes on Qualcomm
systems. Fix it in the schema that MDSS (Mobile Display SubSystem)
devices are named `display-subsystem' and both MDP (Mobile Display
Processor) and DPU (Display Processor Unit) nodes are named
`display-controller'.

Dmitry Baryshkov (6):
  dt-bindings: display/msm: rename mdss nodes to display-sybsystem
  dt-bindings: display/msm: rename mdp nodes to display-controller
  arm64: dts: qcom: rename mdss nodes to display-subsystem
  ARM: dts: qcom-msm8974: rename mdss node to display-subsystem
  arm64: dts: qcom: rename mdp nodes to display-controller
  ARM: dts: qcom: rename mdp nodes to display-controller

 .../devicetree/bindings/display/msm/dpu-common.yaml   |  8 
 .../devicetree/bindings/display/msm/mdss-common.yaml  |  8 
 .../devicetree/bindings/display/msm/qcom,mdp5.yaml|  3 +++
 .../devicetree/bindings/display/msm/qcom,mdss.yaml| 11 +++
 arch/arm/boot/dts/qcom-apq8064.dtsi   |  2 +-
 arch/arm/boot/dts/qcom-msm8974.dtsi   |  4 ++--
 arch/arm64/boot/dts/qcom/msm8916.dtsi |  4 ++--
 arch/arm64/boot/dts/qcom/msm8953.dtsi |  4 ++--
 arch/arm64/boot/dts/qcom/msm8996.dtsi |  4 ++--
 arch/arm64/boot/dts/qcom/sc7180.dtsi  |  2 +-
 arch/arm64/boot/dts/qcom/sdm630.dtsi  |  4 ++--
 arch/arm64/boot/dts/qcom/sdm845.dtsi  |  2 +-
 arch/arm64/boot/dts/qcom/sm8250.dtsi  |  2 +-
 13 files changed, 40 insertions(+), 18 deletions(-)

-- 
2.39.0



[PATCH v5 3/4] ARM: dts: qcom-msm8974: add SoC specific compat string to mdp5 node

2023-01-08 Thread Dmitry Baryshkov
Add SoC-specific compat string to the MDP5 device node to ease
distinguishing between various platforms.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 8d216a3c0851..0cd59088f9c7 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1549,7 +1549,7 @@ mdss: mdss@fd90 {
ranges;
 
mdp: mdp@fd90 {
-   compatible = "qcom,mdp5";
+   compatible = "qcom,msm8974-mdp5", "qcom,mdp5";
reg = <0xfd900100 0x22000>;
reg-names = "mdp_phys";
 
-- 
2.39.0



[PATCH v5 2/4] dt-bindings: display/msm: add SoC-specific compats to qcom, mdp5.yaml

2023-01-08 Thread Dmitry Baryshkov
Add platform-specific compatible entries to the qcom,mdp5.yaml to allow
distinguishing between various platforms. For msm8998 list
qcom,msm8998-dpu rather than -mdp5 to allow this binding to be handled
by either of the drivers.

Signed-off-by: Dmitry Baryshkov 
---
 .../bindings/display/msm/qcom,mdp5.yaml | 17 -
 .../bindings/display/msm/qcom,mdss.yaml |  6 +-
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
index cbcbe8b47e9b..681d6ac48d33 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
@@ -16,7 +16,22 @@ maintainers:
 
 properties:
   compatible:
-const: qcom,mdp5
+oneOf:
+  - const: qcom,mdp5
+deprecated: true
+  - items:
+  - enum:
+  - qcom,apq8084-mdp5
+  - qcom,msm8916-mdp5
+  - qcom,msm8917-mdp5
+  - qcom,msm8953-mdp5
+  - qcom,msm8974-mdp5
+  - qcom,msm8976-mdp5
+  - qcom,msm8994-mdp5
+  - qcom,msm8996-mdp5
+  - qcom,sdm630-mdp5
+  - qcom,sdm660-mdp5
+  - const: qcom,mdp5
 
   reg:
 maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
index 7479cd96fdec..7a81a10c0a9b 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
@@ -88,7 +88,11 @@ patternProperties:
 type: object
 properties:
   compatible:
-const: qcom,mdp5
+oneOf:
+  - const: qcom,mdp5
+  - items:
+  - {}
+  - const: qcom,mdp5
 
   "^dsi@[1-9a-f][0-9a-f]*$":
 type: object
-- 
2.39.0



[PATCH v5 4/4] arm64: dts: qcom: add SoC specific compat strings to mdp5 nodes

2023-01-08 Thread Dmitry Baryshkov
Add SoC-specific compat string to the MDP5 device nodes to ease
distinguishing between various platforms.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +-
 arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +-
 arch/arm64/boot/dts/qcom/sdm630.dtsi  | 2 +-
 arch/arm64/boot/dts/qcom/sdm660.dtsi  | 2 ++
 4 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi 
b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 2ca8e977fc2a..0a23fb6efae8 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -989,7 +989,7 @@ mdss: mdss@1a0 {
ranges;
 
mdp: mdp@1a01000 {
-   compatible = "qcom,mdp5";
+   compatible = "qcom,msm8916-mdp5", "qcom,mdp5";
reg = <0x01a01000 0x89000>;
reg-names = "mdp_phys";
 
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi 
b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index d31464204f69..b5cd1bcad5eb 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -931,7 +931,7 @@ mdss: mdss@90 {
status = "disabled";
 
mdp: mdp@901000 {
-   compatible = "qcom,mdp5";
+   compatible = "qcom,msm8996-mdp5", "qcom,mdp5";
reg = <0x00901000 0x9>;
reg-names = "mdp_phys";
 
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi 
b/arch/arm64/boot/dts/qcom/sdm630.dtsi
index 13e6a4fbba27..65addd4c672e 100644
--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -1498,7 +1498,7 @@ mdss: mdss@c90 {
status = "disabled";
 
mdp: mdp@c901000 {
-   compatible = "qcom,mdp5";
+   compatible = "qcom,sdm630-mdp5", "qcom,mdp5";
reg = <0x0c901000 0x89000>;
reg-names = "mdp_phys";
 
diff --git a/arch/arm64/boot/dts/qcom/sdm660.dtsi 
b/arch/arm64/boot/dts/qcom/sdm660.dtsi
index d52123cb5cd3..cdaa0d7a66f3 100644
--- a/arch/arm64/boot/dts/qcom/sdm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm660.dtsi
@@ -142,6 +142,8 @@  {
 };
 
  {
+   compatible = "qcom,sdm660-mdp5", "qcom,mdp5";
+
ports {
port@1 {
reg = <1>;
-- 
2.39.0



[PATCH v5 0/4] dt-bindings: display/msm: convert MDP5 schema to YAML format

2023-01-08 Thread Dmitry Baryshkov
This patch concludes the conversion of display/msm schema from txt files
to YAML format.

The per-SoC compat (new addition) is required to ease migrating platform
support between mdp5 and dpu drivers.

Changes since v4:
- Adjust qcom,mdss.yaml to follow the addition of per-SoC compatibles

Changes since v3:
- Drop MSM8998 completely, it conflicts with qcom,msm8998-dpu.yaml

Changes since v2:
- Fix MSM8998 compatible list: "qcom,msm8998-dpu", "msm,mdp5" to allow
  handling this device by either of the drivers.

Changes since v1:
- Renamed mdp@ to display-controller@ in the example (Krzysztof)
- Extended ports description to mention possible ports (Krzysztof)
- Fixed ports@ regexp to limit to just four ports (Krzysztof)
- Included patches adding per-SoC compat strings to the schema and to
  dtsi files.


Dmitry Baryshkov (4):
  dt-bindings: display/msm: convert MDP5 schema to YAML format
  dt-bindings: display/msm: add SoC-specific compats to qcom,mdp5.yaml
  ARM: dts: qcom-msm8974: add SoC specific compat string to mdp5 node
  arm64: dts: qcom: add SoC specific compat strings to mdp5 nodes

 .../devicetree/bindings/display/msm/mdp5.txt  | 132 ---
 .../bindings/display/msm/qcom,mdp5.yaml   | 153 ++
 .../bindings/display/msm/qcom,mdss.yaml   |   6 +-
 arch/arm/boot/dts/qcom-msm8974.dtsi   |   2 +-
 arch/arm64/boot/dts/qcom/msm8916.dtsi |   2 +-
 arch/arm64/boot/dts/qcom/msm8996.dtsi |   2 +-
 arch/arm64/boot/dts/qcom/sdm630.dtsi  |   2 +-
 arch/arm64/boot/dts/qcom/sdm660.dtsi  |   2 +
 8 files changed, 164 insertions(+), 137 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/msm/mdp5.txt
 create mode 100644 Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml

-- 
2.39.0



[PATCH v5 1/4] dt-bindings: display/msm: convert MDP5 schema to YAML format

2023-01-08 Thread Dmitry Baryshkov
Convert the mdp5.txt into the yaml format. Changes to the existing (txt) schema:
 - MSM8996 has additional "iommu" clock, define it separately
 - Add new properties used on some of platforms:
   - interconnects, interconnect-names
   - iommus
   - power-domains
   - operating-points-v2, opp-table

Signed-off-by: Dmitry Baryshkov 
---
 .../devicetree/bindings/display/msm/mdp5.txt  | 132 -
 .../bindings/display/msm/qcom,mdp5.yaml   | 138 ++
 2 files changed, 138 insertions(+), 132 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/msm/mdp5.txt
 create mode 100644 Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml

diff --git a/Documentation/devicetree/bindings/display/msm/mdp5.txt 
b/Documentation/devicetree/bindings/display/msm/mdp5.txt
deleted file mode 100644
index 65d03c58dee6..
--- a/Documentation/devicetree/bindings/display/msm/mdp5.txt
+++ /dev/null
@@ -1,132 +0,0 @@
-Qualcomm adreno/snapdragon MDP5 display controller
-
-Description:
-
-This is the bindings documentation for the MDP5 display
-controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994 and MSM8996.
-
-MDP5:
-Required properties:
-- compatible:
-  * "qcom,mdp5" - MDP5
-- reg: Physical base address and length of the controller's registers.
-- reg-names: The names of register regions. The following regions are required:
-  * "mdp_phys"
-- interrupts: Interrupt line from MDP5 to MDSS interrupt controller.
-- clocks: device clocks. See ../clocks/clock-bindings.txt for details.
-- clock-names: the following clocks are required.
--   * "bus"
--   * "iface"
--   * "core"
--   * "vsync"
-- ports: contains the list of output ports from MDP. These connect to 
interfaces
-  that are external to the MDP hardware, such as HDMI, DSI, EDP etc (LVDS is a
-  special case since it is a part of the MDP block itself).
-
-  Each output port contains an endpoint that describes how it is connected to 
an
-  external interface. These are described by the standard properties documented
-  here:
-   Documentation/devicetree/bindings/graph.txt
-   Documentation/devicetree/bindings/media/video-interfaces.txt
-
-  The availability of output ports can vary across SoC revisions:
-
-  For MSM8974 and APQ8084:
-Port 0 -> MDP_INTF0 (eDP)
-Port 1 -> MDP_INTF1 (DSI1)
-Port 2 -> MDP_INTF2 (DSI2)
-Port 3 -> MDP_INTF3 (HDMI)
-
-  For MSM8916:
-Port 0 -> MDP_INTF1 (DSI1)
-
-  For MSM8994 and MSM8996:
-Port 0 -> MDP_INTF1 (DSI1)
-Port 1 -> MDP_INTF2 (DSI2)
-Port 2 -> MDP_INTF3 (HDMI)
-
-Optional properties:
-- clock-names: the following clocks are optional:
-  * "lut"
-  * "tbu"
-  * "tbu_rt"
-
-Example:
-
-/ {
-   ...
-
-   mdss: mdss@1a0 {
-   compatible = "qcom,mdss";
-   reg = <0x1a0 0x1000>,
- <0x1ac8000 0x3000>;
-   reg-names = "mdss_phys", "vbif_phys";
-
-   power-domains = < MDSS_GDSC>;
-
-   clocks = < GCC_MDSS_AHB_CLK>,
-< GCC_MDSS_AXI_CLK>,
-< GCC_MDSS_VSYNC_CLK>;
-   clock-names = "iface",
- "bus",
- "vsync"
-
-   interrupts = <0 72 0>;
-
-   interrupt-controller;
-   #interrupt-cells = <1>;
-
-   #address-cells = <1>;
-   #size-cells = <1>;
-   ranges;
-
-   mdp: mdp@1a01000 {
-   compatible = "qcom,mdp5";
-   reg = <0x1a01000 0x9>;
-   reg-names = "mdp_phys";
-
-   interrupt-parent = <>;
-   interrupts = <0 0>;
-
-   clocks = < GCC_MDSS_AHB_CLK>,
-< GCC_MDSS_AXI_CLK>,
-< GCC_MDSS_MDP_CLK>,
-< GCC_MDSS_VSYNC_CLK>;
-   clock-names = "iface",
- "bus",
- "core",
- "vsync";
-
-   ports {
-   #address-cells = <1>;
-   #size-cells = <0>;
-
-   port@0 {
-   reg = <0>;
-   mdp5_intf1_out: endpoint {
-   remote-endpoint = <_in>;
-   };
-   };
-   };
-   };
-
-   dsi0: dsi@1a98000 {
-   ...
-   ports {
-   ...
-   port@0 {
-   reg = <0>;
-   dsi0_in: endpoint {
-  

[PATCH] dt-bindings: display/msm: qcom, sdm845-mdss: document the DP device

2023-01-08 Thread Dmitry Baryshkov
Document the DP controller added to the sdm845 display subsystem.

Signed-off-by: Dmitry Baryshkov 
---
 .../devicetree/bindings/display/msm/qcom,sdm845-mdss.yaml   | 6 ++
 1 file changed, 6 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,sdm845-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sdm845-mdss.yaml
index 300d8f1ac45c..8f60be6147d8 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,sdm845-mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sdm845-mdss.yaml
@@ -46,6 +46,12 @@ patternProperties:
   compatible:
 const: qcom,sdm845-dpu
 
+  "^displayport-controller@[0-9a-f]+$":
+type: object
+properties:
+  compatible:
+const: qcom,sdm845-dp
+
   "^dsi@[0-9a-f]+$":
 type: object
 properties:
-- 
2.39.0



[PATCH] dt-bindings: display/msm: qcom,mdss: fix HDMI PHY node names

2023-01-08 Thread Dmitry Baryshkov
On Qualcomm devices HDMI PHY node names were changed from hdmi-phy to
phy. Follow this change.

Signed-off-by: Dmitry Baryshkov 
---
 .../devicetree/bindings/display/msm/qcom,mdss.yaml  | 6 --
 1 file changed, 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
index ba0460268731..7479cd96fdec 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
@@ -107,12 +107,6 @@ patternProperties:
   - qcom,dsi-phy-20nm
   - qcom,dsi-phy-28nm-hpm
   - qcom,dsi-phy-28nm-lp
-
-  "^hdmi-phy@[1-9a-f][0-9a-f]*$":
-type: object
-properties:
-  compatible:
-enum:
   - qcom,hdmi-phy-8084
   - qcom,hdmi-phy-8660
   - qcom,hdmi-phy-8960
-- 
2.39.0



[PATCH RFC v7 05/23] dept: Tie to Lockdep and IRQ tracing

2023-01-08 Thread Byungchul Park
Yes. How to place Dept in here looks so ugly. But it's inevitable as
long as relying on Lockdep. The way should be enhanced gradually.

   1. Basically relies on Lockdep to track typical locks and IRQ things.

   2. Dept fails to recognize IRQ situation so it generates false alarms
  when raw_local_irq_*() APIs are used. So made it track those too.

   3. Lockdep doesn't track the outmost {hard,soft}irq entracnes but
  Dept makes use of it. So made it track those too.

Signed-off-by: Byungchul Park 
---
 include/linux/irqflags.h|  22 +++-
 include/linux/local_lock_internal.h |   1 +
 include/linux/lockdep.h | 108 +---
 include/linux/lockdep_types.h   |   3 +
 include/linux/mutex.h   |   1 +
 include/linux/percpu-rwsem.h|   2 +-
 include/linux/rtmutex.h |   1 +
 include/linux/rwlock_types.h|   1 +
 include/linux/rwsem.h   |   1 +
 include/linux/seqlock.h |   2 +-
 include/linux/spinlock_types_raw.h  |   3 +
 include/linux/srcu.h|   2 +-
 kernel/dependency/dept.c|   4 +-
 kernel/locking/lockdep.c|  23 
 14 files changed, 145 insertions(+), 29 deletions(-)

diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
index 5ec0fa7..3cca328 100644
--- a/include/linux/irqflags.h
+++ b/include/linux/irqflags.h
@@ -13,6 +13,7 @@
 #define _LINUX_TRACE_IRQFLAGS_H
 
 #include 
+#include 
 #include 
 #include 
 
@@ -60,8 +61,10 @@ struct irqtrace_events {
 # define lockdep_softirqs_enabled(p)   ((p)->softirqs_enabled)
 # define lockdep_hardirq_enter()   \
 do {   \
-   if (__this_cpu_inc_return(hardirq_context) == 1)\
+   if (__this_cpu_inc_return(hardirq_context) == 1) { \
current->hardirq_threaded = 0;  \
+   dept_hardirq_enter();   \
+   }   \
 } while (0)
 # define lockdep_hardirq_threaded()\
 do {   \
@@ -136,6 +139,8 @@ struct irqtrace_events {
 # define lockdep_softirq_enter()   \
 do {   \
current->softirq_context++; \
+   if (current->softirq_context == 1)  \
+   dept_softirq_enter();   \
 } while (0)
 # define lockdep_softirq_exit()\
 do {   \
@@ -170,17 +175,28 @@ struct irqtrace_events {
 /*
  * Wrap the arch provided IRQ routines to provide appropriate checks.
  */
-#define raw_local_irq_disable()arch_local_irq_disable()
-#define raw_local_irq_enable() arch_local_irq_enable()
+#define raw_local_irq_disable()\
+   do {\
+   arch_local_irq_disable();   \
+   dept_hardirqs_off(_THIS_IP_);   \
+   } while (0)
+#define raw_local_irq_enable() \
+   do {\
+   dept_hardirqs_on(_THIS_IP_);\
+   arch_local_irq_enable();\
+   } while (0)
 #define raw_local_irq_save(flags)  \
do {\
typecheck(unsigned long, flags);\
flags = arch_local_irq_save();  \
+   dept_hardirqs_off(_THIS_IP_);   \
} while (0)
 #define raw_local_irq_restore(flags)   \
do {\
typecheck(unsigned long, flags);\
raw_check_bogus_irq_restore();  \
+   if (!arch_irqs_disabled_flags(flags))   \
+   dept_hardirqs_on(_THIS_IP_);\
arch_local_irq_restore(flags);  \
} while (0)
 #define raw_local_save_flags(flags)\
diff --git a/include/linux/local_lock_internal.h 
b/include/linux/local_lock_internal.h
index 975e33b..39f6778 100644
--- a/include/linux/local_lock_internal.h
+++ b/include/linux/local_lock_internal.h
@@ -21,6 +21,7 @@
.name = #lockname,  \
.wait_type_inner = LD_WAIT_CONFIG,  \
.lock_type = LD_LOCK_PERCPU,\
+   .dmap = DEPT_MAP_INITIALIZER(lockname, NULL),\
},  \
.owner = NULL,
 
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 1f1099d..3c0b10e 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -12,6 +12,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 struct task_struct;
@@ -39,6 +40,8 @@ static inline void lockdep_copy_map(struct lockdep_map *to,
 */
  

[PATCH RFC v7 08/23] dept: Apply sdt_might_sleep_strong() to PG_{locked, writeback} wait

2023-01-08 Thread Byungchul Park
Makes Dept able to track dependencies by PG_{locked,writeback} waits.

Signed-off-by: Byungchul Park 
---
 mm/filemap.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/mm/filemap.c b/mm/filemap.c
index c4d4ace..b013a5b 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "internal.h"
@@ -1215,6 +1216,9 @@ static inline bool folio_trylock_flag(struct folio 
*folio, int bit_nr,
 /* How many times do we accept lock stealing from under a waiter? */
 int sysctl_page_lock_unfairness = 5;
 
+static struct dept_map __maybe_unused PG_locked_map = 
DEPT_MAP_INITIALIZER(PG_locked_map, NULL);
+static struct dept_map __maybe_unused PG_writeback_map = 
DEPT_MAP_INITIALIZER(PG_writeback_map, NULL);
+
 static inline int folio_wait_bit_common(struct folio *folio, int bit_nr,
int state, enum behavior behavior)
 {
@@ -1226,6 +1230,11 @@ static inline int folio_wait_bit_common(struct folio 
*folio, int bit_nr,
unsigned long pflags;
bool in_thrashing;
 
+   if (bit_nr == PG_locked)
+   sdt_might_sleep_strong(_locked_map);
+   else if (bit_nr == PG_writeback)
+   sdt_might_sleep_strong(_writeback_map);
+
if (bit_nr == PG_locked &&
!folio_test_uptodate(folio) && folio_test_workingset(folio)) {
delayacct_thrashing_start(_thrashing);
@@ -1327,6 +1336,8 @@ static inline int folio_wait_bit_common(struct folio 
*folio, int bit_nr,
 */
finish_wait(q, wait);
 
+   sdt_might_sleep_finish();
+
if (thrashing) {
delayacct_thrashing_end(_thrashing);
psi_memstall_leave();
-- 
1.9.1



[PATCH RFC v7 20/23] dept: Apply timeout consideration to waitqueue wait

2023-01-08 Thread Byungchul Park
Now that CONFIG_DEPT_AGGRESSIVE_TIMEOUT_WAIT was introduced, apply the
consideration to waitqueue wait, assuming an input 'ret' in
___wait_event() macro is used as a timeout value.

Signed-off-by: Byungchul Park 
---
 include/linux/wait.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/linux/wait.h b/include/linux/wait.h
index ede466c..87888ee 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -304,7 +304,10 @@ static inline void wake_up_pollfree(struct wait_queue_head 
*wq_head)
struct wait_queue_entry __wq_entry; 
\
long __ret = ret;   /* explicit shadow */   
\

\
-   sdt_might_sleep_weak(NULL); 
\
+   if (!__ret || __ret == MAX_SCHEDULE_TIMEOUT)
\
+   sdt_might_sleep_weak(NULL); 
\
+   else
\
+   sdt_might_sleep_weak_timeout(NULL); 
\
init_wait_entry(&__wq_entry, exclusive ? WQ_FLAG_EXCLUSIVE : 0);
\
for (;;) {  
\
long __int = prepare_to_wait_event(_head, &__wq_entry, 
state);\
-- 
1.9.1



[PATCH RFC v7 16/23] dept: Apply sdt_might_sleep_strong() to dma fence wait

2023-01-08 Thread Byungchul Park
Makes Dept able to track dma fence waits.

Signed-off-by: Byungchul Park 
---
 drivers/dma-buf/dma-fence.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 406b4e2..dd190cf 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define CREATE_TRACE_POINTS
 #include 
@@ -782,6 +783,7 @@ struct default_wait_cb {
cb.task = current;
list_add(, >cb_list);
 
+   sdt_might_sleep_strong(NULL);
while (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, >flags) && ret > 
0) {
if (intr)
__set_current_state(TASK_INTERRUPTIBLE);
@@ -795,6 +797,7 @@ struct default_wait_cb {
if (ret > 0 && intr && signal_pending(current))
ret = -ERESTARTSYS;
}
+   sdt_might_sleep_finish();
 
if (!list_empty())
list_del();
@@ -884,6 +887,7 @@ struct default_wait_cb {
}
}
 
+   sdt_might_sleep_strong(NULL);
while (ret > 0) {
if (intr)
set_current_state(TASK_INTERRUPTIBLE);
@@ -898,6 +902,7 @@ struct default_wait_cb {
if (ret > 0 && intr && signal_pending(current))
ret = -ERESTARTSYS;
}
+   sdt_might_sleep_finish();
 
__set_current_state(TASK_RUNNING);
 
-- 
1.9.1



[PATCH RFC v7 18/23] dept: Apply timeout consideration to wait_for_completion()/complete()

2023-01-08 Thread Byungchul Park
Now that CONFIG_DEPT_AGGRESSIVE_TIMEOUT_WAIT was introduced, apply the
consideration to wait_for_completion()/complete().

Signed-off-by: Byungchul Park 
---
 include/linux/completion.h | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/include/linux/completion.h b/include/linux/completion.h
index 0408f6d..57a715f 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 
 /*
  * struct completion - structure used to maintain state for a "completion"
@@ -153,7 +154,10 @@ extern long raw_wait_for_completion_killable_timeout(
 #define wait_for_completion_timeout(x, t)  \
 ({ \
unsigned long __ret;\
-   sdt_might_sleep_strong(NULL);   \
+   if ((t) == MAX_SCHEDULE_TIMEOUT)\
+   sdt_might_sleep_strong(NULL);   \
+   else\
+   sdt_might_sleep_strong_timeout(NULL);   \
__ret = raw_wait_for_completion_timeout(x, t);  \
sdt_might_sleep_finish();   \
__ret;  \
@@ -161,7 +165,10 @@ extern long raw_wait_for_completion_killable_timeout(
 #define wait_for_completion_io_timeout(x, t)   \
 ({ \
unsigned long __ret;\
-   sdt_might_sleep_strong(NULL);   \
+   if ((t) == MAX_SCHEDULE_TIMEOUT)\
+   sdt_might_sleep_strong(NULL);   \
+   else\
+   sdt_might_sleep_strong_timeout(NULL);   \
__ret = raw_wait_for_completion_io_timeout(x, t);   \
sdt_might_sleep_finish();   \
__ret;  \
@@ -169,7 +176,10 @@ extern long raw_wait_for_completion_killable_timeout(
 #define wait_for_completion_interruptible_timeout(x, t)\
 ({ \
long __ret; \
-   sdt_might_sleep_strong(NULL);   \
+   if ((t) == MAX_SCHEDULE_TIMEOUT)\
+   sdt_might_sleep_strong(NULL);   \
+   else\
+   sdt_might_sleep_strong_timeout(NULL);   \
__ret = raw_wait_for_completion_interruptible_timeout(x, t);\
sdt_might_sleep_finish();   \
__ret;  \
@@ -177,7 +187,10 @@ extern long raw_wait_for_completion_killable_timeout(
 #define wait_for_completion_killable_timeout(x, t) \
 ({ \
long __ret; \
-   sdt_might_sleep_strong(NULL);   \
+   if ((t) == MAX_SCHEDULE_TIMEOUT)\
+   sdt_might_sleep_strong(NULL);   \
+   else\
+   sdt_might_sleep_strong_timeout(NULL);   \
__ret = raw_wait_for_completion_killable_timeout(x, t); \
sdt_might_sleep_finish();   \
__ret;  \
-- 
1.9.1



[PATCH RFC v7 17/23] dept: Track timeout waits separately with a new Kconfig

2023-01-08 Thread Byungchul Park
Waits with valid timeouts don't actually cause deadlocks. However, Dept
has been reporting the cases as well because it's worth informing the
circular dependency for some cases where, for example, timeout is used
to avoid a deadlock but not meant to be expired.

However, yes, there are also a lot of, even more, cases where timeout
is used for its clear purpose and meant to be expired.

Let Dept report these as an information rather than shouting DEADLOCK.
Plus, introduced CONFIG_DEPT_AGGRESSIVE_TIMEOUT_WAIT Kconfig to make it
optional so that any reports involving waits with timeouts can be turned
on/off depending on the purpose.

Signed-off-by: Byungchul Park 
---
 include/linux/dept.h | 15 
 include/linux/dept_ldt.h |  6 ++---
 include/linux/dept_sdt.h | 35 +---
 kernel/dependency/dept.c | 60 
 lib/Kconfig.debug| 10 
 5 files changed, 107 insertions(+), 19 deletions(-)

diff --git a/include/linux/dept.h b/include/linux/dept.h
index 21ecefc..4387d5a 100644
--- a/include/linux/dept.h
+++ b/include/linux/dept.h
@@ -270,6 +270,11 @@ struct dept_wait {
 * whether this wait is for commit in scheduler
 */
boolsched_sleep;
+
+   /*
+* whether a timeout is set
+*/
+   booltimeout;
};
};
 };
@@ -458,6 +463,7 @@ struct dept_task {
boolstage_sched_map;
const char  *stage_w_fn;
unsigned long   stage_ip;
+   boolstage_timeout;
 
/*
 * the number of missing ecxts
@@ -496,6 +502,7 @@ struct dept_task {
.stage_sched_map = false,   \
.stage_w_fn = NULL, \
.stage_ip = 0UL,\
+   .stage_timeout = false, \
.missing_ecxt = 0,  \
.hardirqs_enabled = false,  \
.softirqs_enabled = false,  \
@@ -513,8 +520,8 @@ struct dept_task {
 extern void dept_map_reinit(struct dept_map *m, struct dept_key *k, int sub_u, 
const char *n);
 extern void dept_map_copy(struct dept_map *to, struct dept_map *from);
 
-extern void dept_wait(struct dept_map *m, unsigned long w_f, unsigned long ip, 
const char *w_fn, int sub_l);
-extern void dept_stage_wait(struct dept_map *m, struct dept_key *k, unsigned 
long ip, const char *w_fn, bool strong);
+extern void dept_wait(struct dept_map *m, unsigned long w_f, unsigned long ip, 
const char *w_fn, int sub_l, bool timeout);
+extern void dept_stage_wait(struct dept_map *m, struct dept_key *k, unsigned 
long ip, const char *w_fn, bool strong, bool timeout);
 extern void dept_request_event_wait_commit(void);
 extern void dept_clean_stage(void);
 extern void dept_stage_event(struct task_struct *t, unsigned long ip);
@@ -564,8 +571,8 @@ static inline void dept_ecxt_enter_nokeep(struct dept_map 
*m)
 #define dept_map_reinit(m, k, su, n)   do { (void)(n); 
(void)(k); } while (0)
 #define dept_map_copy(t, f)do { } while (0)
 
-#define dept_wait(m, w_f, ip, w_fn, sl)do { 
(void)(w_fn); } while (0)
-#define dept_stage_wait(m, k, ip, w_fn, s) do { (void)(k); 
(void)(w_fn); } while (0)
+#define dept_wait(m, w_f, ip, w_fn, sl, t) do { (void)(w_fn); } 
while (0)
+#define dept_stage_wait(m, k, ip, w_fn, s, t)  do { (void)(k); 
(void)(w_fn); } while (0)
 #define dept_request_event_wait_commit()   do { } while (0)
 #define dept_clean_stage() do { } while (0)
 #define dept_stage_event(t, ip)do { } while (0)
diff --git a/include/linux/dept_ldt.h b/include/linux/dept_ldt.h
index b8c00bc..9a88aa3 100644
--- a/include/linux/dept_ldt.h
+++ b/include/linux/dept_ldt.h
@@ -27,7 +27,7 @@
else if (t) \
dept_ecxt_enter(m, LDT_EVT_L, i, "trylock", "unlock", 
sl);\
else {  \
-   dept_wait(m, LDT_EVT_L, i, "lock", sl); \
+   dept_wait(m, LDT_EVT_L, i, "lock", sl, false);  \
dept_ecxt_enter(m, LDT_EVT_L, i, "lock", "unlock", sl);\
}   \
} while (0)
@@ -39,7 +39,7 @@
else if (t) \
dept_ecxt_enter(m, LDT_EVT_R, i, "read_trylock", 
"read_unlock", sl);\

[PATCH RFC v7 07/23] dept: Apply sdt_might_sleep_strong() to wait_for_completion()/complete()

2023-01-08 Thread Byungchul Park
Makes Dept able to track dependencies by
wait_for_completion()/complete().

In order to obtain the meaningful caller points, replace all the
wait_for_completion*() declarations with macros in the header.

Signed-off-by: Byungchul Park 
---
 include/linux/completion.h | 89 +-
 kernel/sched/completion.c  | 60 +++
 2 files changed, 110 insertions(+), 39 deletions(-)

diff --git a/include/linux/completion.h b/include/linux/completion.h
index 62b32b1..0408f6d 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -10,6 +10,7 @@
  */
 
 #include 
+#include 
 
 /*
  * struct completion - structure used to maintain state for a "completion"
@@ -99,19 +100,89 @@ static inline void reinit_completion(struct completion *x)
x->done = 0;
 }
 
-extern void wait_for_completion(struct completion *);
-extern void wait_for_completion_io(struct completion *);
-extern int wait_for_completion_interruptible(struct completion *x);
-extern int wait_for_completion_killable(struct completion *x);
-extern int wait_for_completion_state(struct completion *x, unsigned int state);
-extern unsigned long wait_for_completion_timeout(struct completion *x,
+extern void raw_wait_for_completion(struct completion *);
+extern void raw_wait_for_completion_io(struct completion *);
+extern int raw_wait_for_completion_interruptible(struct completion *x);
+extern int raw_wait_for_completion_killable(struct completion *x);
+extern int raw_wait_for_completion_state(struct completion *x, unsigned int 
state);
+extern unsigned long raw_wait_for_completion_timeout(struct completion *x,
   unsigned long timeout);
-extern unsigned long wait_for_completion_io_timeout(struct completion *x,
+extern unsigned long raw_wait_for_completion_io_timeout(struct completion *x,
unsigned long timeout);
-extern long wait_for_completion_interruptible_timeout(
+extern long raw_wait_for_completion_interruptible_timeout(
struct completion *x, unsigned long timeout);
-extern long wait_for_completion_killable_timeout(
+extern long raw_wait_for_completion_killable_timeout(
struct completion *x, unsigned long timeout);
+
+#define wait_for_completion(x) \
+({ \
+   sdt_might_sleep_strong(NULL);   \
+   raw_wait_for_completion(x); \
+   sdt_might_sleep_finish();   \
+})
+#define wait_for_completion_io(x)  \
+({ \
+   sdt_might_sleep_strong(NULL);   \
+   raw_wait_for_completion_io(x);  \
+   sdt_might_sleep_finish();   \
+})
+#define wait_for_completion_interruptible(x)   \
+({ \
+   int __ret;  \
+   sdt_might_sleep_strong(NULL);   \
+   __ret = raw_wait_for_completion_interruptible(x);   \
+   sdt_might_sleep_finish();   \
+   __ret;  \
+})
+#define wait_for_completion_killable(x)\
+({ \
+   int __ret;  \
+   sdt_might_sleep_strong(NULL);   \
+   __ret = raw_wait_for_completion_killable(x);\
+   sdt_might_sleep_finish();   \
+   __ret;  \
+})
+#define wait_for_completion_state(x, s)\
+({ \
+   int __ret;  \
+   sdt_might_sleep_strong(NULL);   \
+   __ret = raw_wait_for_completion_state(x, s);\
+   sdt_might_sleep_finish();   \
+   __ret;  \
+})
+#define wait_for_completion_timeout(x, t)  \
+({ \
+   unsigned long __ret;\
+   sdt_might_sleep_strong(NULL);   \
+   __ret = raw_wait_for_completion_timeout(x, t);  \
+   sdt_might_sleep_finish();   \
+   __ret;  \
+})
+#define wait_for_completion_io_timeout(x, t)   \
+({ \
+   unsigned 

[PATCH RFC v7 13/23] dept: Distinguish each work from another

2023-01-08 Thread Byungchul Park
Workqueue already provides concurrency control. By that, any wait in a
work doesn't prevents events in other works with the control enabled.
Thus, each work would better be considered a different context.

So let Dept assign a different context id to each work.

Signed-off-by: Byungchul Park 
---
 include/linux/dept.h |  2 ++
 kernel/dependency/dept.c | 10 ++
 kernel/workqueue.c   |  3 +++
 3 files changed, 15 insertions(+)

diff --git a/include/linux/dept.h b/include/linux/dept.h
index 777c837..625c645 100644
--- a/include/linux/dept.h
+++ b/include/linux/dept.h
@@ -515,6 +515,7 @@ struct dept_task {
 extern void dept_sched_enter(void);
 extern void dept_sched_exit(void);
 extern void dept_kernel_enter(void);
+extern void dept_work_enter(void);
 
 static inline void dept_ecxt_enter_nokeep(struct dept_map *m)
 {
@@ -565,6 +566,7 @@ static inline void dept_ecxt_enter_nokeep(struct dept_map 
*m)
 #define dept_sched_enter() do { } while (0)
 #define dept_sched_exit()  do { } while (0)
 #define dept_kernel_enter()do { } while (0)
+#define dept_work_enter()  do { } while (0)
 #define dept_ecxt_enter_nokeep(m)  do { } while (0)
 #define dept_key_init(k)   do { (void)(k); } while 
(0)
 #define dept_key_destroy(k)do { (void)(k); } while 
(0)
diff --git a/kernel/dependency/dept.c b/kernel/dependency/dept.c
index e98617b..2f215c2 100644
--- a/kernel/dependency/dept.c
+++ b/kernel/dependency/dept.c
@@ -1954,6 +1954,16 @@ void dept_hardirqs_off(unsigned long ip)
 }
 EXPORT_SYMBOL_GPL(dept_hardirqs_off);
 
+/*
+ * Assign a different context id to each work.
+ */
+void dept_work_enter(void)
+{
+   struct dept_task *dt = dept_task();
+
+   dt->cxt_id[DEPT_CXT_PROCESS] += 1UL << DEPT_CXTS_NR;
+}
+
 void dept_kernel_enter(void)
 {
struct dept_task *dt = dept_task();
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 07895de..69c4f46 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -51,6 +51,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "workqueue_internal.h"
 
@@ -2199,6 +2200,8 @@ static void process_one_work(struct worker *worker, 
struct work_struct *work)
 
lockdep_copy_map(_map, >lockdep_map);
 #endif
+   dept_work_enter();
+
/* ensure we're on the correct CPU */
WARN_ON_ONCE(!(pool->flags & POOL_DISASSOCIATED) &&
 raw_smp_processor_id() != pool->cpu);
-- 
1.9.1



[PATCH RFC v7 11/23] dept: Apply sdt_might_sleep_weak() to hashed-waitqueue wait

2023-01-08 Thread Byungchul Park
Makes Dept able to track dependencies by hashed-waitqueue waits, but
weakly.

Signed-off-by: Byungchul Park 
---
 include/linux/wait_bit.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/wait_bit.h b/include/linux/wait_bit.h
index 7725b75..bad30ba 100644
--- a/include/linux/wait_bit.h
+++ b/include/linux/wait_bit.h
@@ -6,6 +6,7 @@
  * Linux wait-bit related types and methods:
  */
 #include 
+#include 
 
 struct wait_bit_key {
void*flags;
@@ -246,6 +247,7 @@ struct wait_bit_queue_entry {
struct wait_bit_queue_entry __wbq_entry;\
long __ret = ret; /* explicit shadow */ \
\
+   sdt_might_sleep_weak(NULL); \
init_wait_var_entry(&__wbq_entry, var,  \
exclusive ? WQ_FLAG_EXCLUSIVE : 0); \
for (;;) {  \
@@ -263,6 +265,7 @@ struct wait_bit_queue_entry {
cmd;\
}   \
finish_wait(__wq_head, &__wbq_entry.wq_entry);  \
+   sdt_might_sleep_finish();   \
 __out: __ret;  \
 })
 
-- 
1.9.1



[PATCH RFC v7 09/23] dept: Apply sdt_might_sleep_weak() to swait

2023-01-08 Thread Byungchul Park
Makes Dept able to track dependencies by swaits, but weakly.

Signed-off-by: Byungchul Park 
---
 include/linux/swait.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/swait.h b/include/linux/swait.h
index 6a8c22b..1304209 100644
--- a/include/linux/swait.h
+++ b/include/linux/swait.h
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -161,6 +162,7 @@ static inline bool swq_has_sleeper(struct swait_queue_head 
*wq)
struct swait_queue __wait;  \
long __ret = ret;   \
\
+   sdt_might_sleep_weak(NULL); \
INIT_LIST_HEAD(&__wait.task_list);  \
for (;;) {  \
long __int = prepare_to_swait_event(, &__wait, state);\
@@ -176,6 +178,7 @@ static inline bool swq_has_sleeper(struct swait_queue_head 
*wq)
cmd;\
}   \
finish_swait(, &__wait); \
+   sdt_might_sleep_finish();   \
 __out: __ret;  \
 })
 
-- 
1.9.1



[PATCH RFC v7 04/23] dept: Add lock dependency tracker APIs

2023-01-08 Thread Byungchul Park
Wrapped the base APIs for easier annotation on typical lock.

Signed-off-by: Byungchul Park 
---
 include/linux/dept_ldt.h | 77 
 1 file changed, 77 insertions(+)
 create mode 100644 include/linux/dept_ldt.h

diff --git a/include/linux/dept_ldt.h b/include/linux/dept_ldt.h
new file mode 100644
index ..b8c00bc
--- /dev/null
+++ b/include/linux/dept_ldt.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Lock Dependency Tracker
+ *
+ * Started by Byungchul Park :
+ *
+ *  Copyright (c) 2020 LG Electronics, Inc., Byungchul Park
+ */
+
+#ifndef __LINUX_DEPT_LDT_H
+#define __LINUX_DEPT_LDT_H
+
+#include 
+
+#ifdef CONFIG_DEPT
+#define LDT_EVT_L  1UL
+#define LDT_EVT_R  2UL
+#define LDT_EVT_W  4UL
+#define LDT_EVT_RW (LDT_EVT_R | LDT_EVT_W)
+#define LDT_EVT_ALL(LDT_EVT_L | LDT_EVT_RW)
+
+#define ldt_init(m, k, su, n)  dept_map_init(m, k, su, n)
+#define ldt_lock(m, sl, t, n, i)   \
+   do {\
+   if (n)  \
+   dept_ecxt_enter_nokeep(m);  \
+   else if (t) \
+   dept_ecxt_enter(m, LDT_EVT_L, i, "trylock", "unlock", 
sl);\
+   else {  \
+   dept_wait(m, LDT_EVT_L, i, "lock", sl); \
+   dept_ecxt_enter(m, LDT_EVT_L, i, "lock", "unlock", sl);\
+   }   \
+   } while (0)
+
+#define ldt_rlock(m, sl, t, n, i)  \
+   do {\
+   if (n)  \
+   dept_ecxt_enter_nokeep(m);  \
+   else if (t) \
+   dept_ecxt_enter(m, LDT_EVT_R, i, "read_trylock", 
"read_unlock", sl);\
+   else {  \
+   dept_wait(m, LDT_EVT_W, i, "read_lock", sl);\
+   dept_ecxt_enter(m, LDT_EVT_R, i, "read_lock", 
"read_unlock", sl);\
+   }   \
+   } while (0)
+
+#define ldt_wlock(m, sl, t, n, i)  \
+   do {\
+   if (n)  \
+   dept_ecxt_enter_nokeep(m);  \
+   else if (t) \
+   dept_ecxt_enter(m, LDT_EVT_W, i, "write_trylock", 
"write_unlock", sl);\
+   else {  \
+   dept_wait(m, LDT_EVT_RW, i, "write_lock", sl);  \
+   dept_ecxt_enter(m, LDT_EVT_W, i, "write_lock", 
"write_unlock", sl);\
+   }   \
+   } while (0)
+
+#define ldt_unlock(m, i)   dept_ecxt_exit(m, LDT_EVT_ALL, i)
+
+#define ldt_downgrade(m, i)\
+   do {\
+   if (dept_ecxt_holding(m, LDT_EVT_W))\
+   dept_map_ecxt_modify(m, LDT_EVT_W, NULL, LDT_EVT_R, i, 
"downgrade", "read_unlock", -1);\
+   } while (0)
+
+#define ldt_set_class(m, n, k, sl, i)  dept_map_ecxt_modify(m, LDT_EVT_ALL, k, 
0UL, i, "lock_set_class", "(any)unlock", sl)
+#else /* !CONFIG_DEPT */
+#define ldt_init(m, k, su, n)  do { (void)(k); } while (0)
+#define ldt_lock(m, sl, t, n, i)   do { } while (0)
+#define ldt_rlock(m, sl, t, n, i)  do { } while (0)
+#define ldt_wlock(m, sl, t, n, i)  do { } while (0)
+#define ldt_unlock(m, i)   do { } while (0)
+#define ldt_downgrade(m, i)do { } while (0)
+#define ldt_set_class(m, n, k, sl, i)  do { } while (0)
+#endif
+#endif /* __LINUX_DEPT_LDT_H */
-- 
1.9.1



[PATCH RFC v7 21/23] dept: Apply timeout consideration to hashed-waitqueue wait

2023-01-08 Thread Byungchul Park
Now that CONFIG_DEPT_AGGRESSIVE_TIMEOUT_WAIT was introduced, apply the
consideration to hashed-waitqueue wait, assuming an input 'ret' in
___wait_var_event() macro is used as a timeout value.

Signed-off-by: Byungchul Park 
---
 include/linux/wait_bit.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/linux/wait_bit.h b/include/linux/wait_bit.h
index bad30ba..b504815 100644
--- a/include/linux/wait_bit.h
+++ b/include/linux/wait_bit.h
@@ -247,7 +247,10 @@ struct wait_bit_queue_entry {
struct wait_bit_queue_entry __wbq_entry;\
long __ret = ret; /* explicit shadow */ \
\
-   sdt_might_sleep_weak(NULL); \
+   if (!__ret || __ret == MAX_SCHEDULE_TIMEOUT)\
+   sdt_might_sleep_weak(NULL); \
+   else\
+   sdt_might_sleep_weak_timeout(NULL); \
init_wait_var_entry(&__wbq_entry, var,  \
exclusive ? WQ_FLAG_EXCLUSIVE : 0); \
for (;;) {  \
-- 
1.9.1



[PATCH RFC v7 03/23] dept: Add single event dependency tracker APIs

2023-01-08 Thread Byungchul Park
Wrapped the base APIs for easier annotation on wait and event. Start
with supporting waiters on each single event. More general support for
multiple events is a future work. Do more when the need arises.

How to annotate (the simplest way):

1. Initaialize a map for the interesting wait.

   /*
* Recommand to place along with the wait instance.
*/
   struct dept_map my_wait;

   /*
* Recommand to place in the initialization code.
*/
   sdt_map_init(_wait);

2. Place the following at the wait code.

   sdt_wait(_wait);

3. Place the following at the event code.

   sdt_event(_wait);

That's it!

Signed-off-by: Byungchul Park 
---
 include/linux/dept_sdt.h | 72 
 1 file changed, 72 insertions(+)
 create mode 100644 include/linux/dept_sdt.h

diff --git a/include/linux/dept_sdt.h b/include/linux/dept_sdt.h
new file mode 100644
index ..2644e77
--- /dev/null
+++ b/include/linux/dept_sdt.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Single-event Dependency Tracker
+ *
+ * Started by Byungchul Park :
+ *
+ *  Copyright (c) 2020 LG Electronics, Inc., Byungchul Park
+ */
+
+#ifndef __LINUX_DEPT_SDT_H
+#define __LINUX_DEPT_SDT_H
+
+#include 
+
+#ifdef CONFIG_DEPT
+#define sdt_map_init(m)
\
+   do {\
+   static struct dept_key __key;   \
+   dept_map_init(m, &__key, 0, #m);\
+   } while (0)
+
+#define sdt_map_init_key(m, k) dept_map_init(m, k, 0, #m)
+
+#define sdt_wait(m)\
+   do {\
+   dept_request_event(m);  \
+   dept_wait(m, 1UL, _THIS_IP_, __func__, 0);  \
+   } while (0)
+
+/*
+ * sdt_might_sleep() and its family will be committed in __schedule()
+ * when it actually gets to __schedule(). Both dept_request_event() and
+ * dept_wait() will be performed on the commit.
+ */
+
+/*
+ * Use the code location as the class key if an explicit map is not used.
+ */
+#define sdt_might_sleep_strong(m)  \
+   do {\
+   struct dept_map *__m = m;   \
+   static struct dept_key __key;   \
+   dept_stage_wait(__m, __m ? NULL : &__key, _THIS_IP_, __func__, 
true);\
+   } while (0)
+
+/*
+ * Use the code location as the class key if an explicit map is not used.
+ */
+#define sdt_might_sleep_weak(m)
\
+   do {\
+   struct dept_map *__m = m;   \
+   static struct dept_key __key;   \
+   dept_stage_wait(__m, __m ? NULL : &__key, _THIS_IP_, __func__, 
false);\
+   } while (0)
+
+#define sdt_might_sleep_finish()   dept_clean_stage()
+
+#define sdt_ecxt_enter(m)  dept_ecxt_enter(m, 1UL, _THIS_IP_, 
"start", "event", 0)
+#define sdt_event(m)   dept_event(m, 1UL, _THIS_IP_, __func__)
+#define sdt_ecxt_exit(m)   dept_ecxt_exit(m, 1UL, _THIS_IP_)
+#else /* !CONFIG_DEPT */
+#define sdt_map_init(m)do { } while (0)
+#define sdt_map_init_key(m, k) do { (void)(k); } while (0)
+#define sdt_wait(m)do { } while (0)
+#define sdt_might_sleep_strong(m)  do { } while (0)
+#define sdt_might_sleep_weak(m)do { } while (0)
+#define sdt_might_sleep_finish()   do { } while (0)
+#define sdt_ecxt_enter(m)  do { } while (0)
+#define sdt_event(m)   do { } while (0)
+#define sdt_ecxt_exit(m)   do { } while (0)
+#endif
+#endif /* __LINUX_DEPT_SDT_H */
-- 
1.9.1



[PATCH RFC v7 15/23] locking/lockdep, cpu/hotplus: Use a weaker annotation in AP thread

2023-01-08 Thread Byungchul Park
cb92173d1f0 ("locking/lockdep, cpu/hotplug: Annotate AP thread") was
introduced to make lockdep_assert_cpus_held() work in AP thread.

However, the annotation is too strong for that purpose. We don't have to
use more than try lock annotation for that.

Furthermore, now that Dept was introduced, false positive alarms was
reported by that. Replaced it with try lock annotation.

Signed-off-by: Byungchul Park 
---
 kernel/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 6c0a92c..6a9b9c3 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -356,7 +356,7 @@ int lockdep_is_cpus_held(void)
 
 static void lockdep_acquire_cpus_lock(void)
 {
-   rwsem_acquire(_hotplug_lock.dep_map, 0, 0, _THIS_IP_);
+   rwsem_acquire(_hotplug_lock.dep_map, 0, 1, _THIS_IP_);
 }
 
 static void lockdep_release_cpus_lock(void)
-- 
1.9.1



[PATCH RFC v7 14/23] dept: Add a mechanism to refill the internal memory pools on running out

2023-01-08 Thread Byungchul Park
Dept engine works in a constrained environment. For example, Dept cannot
make use of dynamic allocation e.g. kmalloc(). So Dept has been using
static pools to keep memory chunks Dept uses.

However, Dept would barely work once any of the pools gets run out. So
implemented a mechanism for the refill on the lack by any chance, using
irq work and workqueue that fits on the contrained environment.

Signed-off-by: Byungchul Park 
---
 include/linux/dept.h|  19 ++--
 kernel/dependency/dept.c| 104 ++--
 kernel/dependency/dept_object.h |  10 ++--
 kernel/dependency/dept_proc.c   |   8 ++--
 4 files changed, 112 insertions(+), 29 deletions(-)

diff --git a/include/linux/dept.h b/include/linux/dept.h
index 625c645..21ecefc 100644
--- a/include/linux/dept.h
+++ b/include/linux/dept.h
@@ -336,9 +336,19 @@ struct dept_pool {
size_t  obj_sz;
 
/*
-* the number of the static array
+* the remaining number of the object in spool
 */
-   atomic_tobj_nr;
+   int obj_nr;
+
+   /*
+* the number of the object in spool
+*/
+   int tot_nr;
+
+   /*
+* accumulated amount of memory used by the object in byte
+*/
+   atomic_tacc_sz;
 
/*
 * offset of ->pool_node
@@ -348,9 +358,10 @@ struct dept_pool {
/*
 * pointer to the pool
 */
-   void*spool;
+   void*spool; /* static pool */
+   void*rpool; /* reserved pool */
struct llist_head   boot_pool;
-   struct llist_head __percpu  *lpool;
+   struct llist_head __percpu  *lpool; /* local pool */
 };
 
 struct dept_ecxt_held {
diff --git a/kernel/dependency/dept.c b/kernel/dependency/dept.c
index 2f215c2..11d4f75 100644
--- a/kernel/dependency/dept.c
+++ b/kernel/dependency/dept.c
@@ -73,6 +73,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include "dept_internal.h"
 
 static int dept_stop;
@@ -121,10 +124,12 @@
WARN(1, "DEPT_STOP: " s);   \
})
 
-#define DEPT_INFO_ONCE(s...) pr_warn_once("DEPT_INFO_ONCE: " s)
+#define DEPT_INFO_ONCE(s...)   pr_warn_once("DEPT_INFO_ONCE: " s)
+#define DEPT_INFO(s...)pr_warn("DEPT_INFO: " s)
 
 static arch_spinlock_t dept_spin = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
 static arch_spinlock_t stage_spin = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
+static arch_spinlock_t dept_pool_spin = 
(arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
 
 /*
  * DEPT internal engine should be careful in using outside functions
@@ -263,6 +268,7 @@ static inline bool valid_key(struct dept_key *k)
 
 #define OBJECT(id, nr) \
 static struct dept_##id spool_##id[nr];
\
+static struct dept_##id rpool_##id[nr];
\
 static DEFINE_PER_CPU(struct llist_head, lpool_##id);
#include "dept_object.h"
 #undef  OBJECT
@@ -271,14 +277,70 @@ struct dept_pool dept_pool[OBJECT_NR] = {
 #define OBJECT(id, nr) {   \
.name = #id,\
.obj_sz = sizeof(struct dept_##id), \
-   .obj_nr = ATOMIC_INIT(nr),  \
+   .obj_nr = nr,   \
+   .tot_nr = nr,   \
+   .acc_sz = ATOMIC_INIT(sizeof(spool_##id) + sizeof(rpool_##id)), \
.node_off = offsetof(struct dept_##id, pool_node),  \
.spool = spool_##id,\
+   .rpool = rpool_##id,\
.lpool = _##id, },
#include "dept_object.h"
 #undef  OBJECT
 };
 
+static void dept_wq_work_fn(struct work_struct *work)
+{
+   int i;
+
+   for (i = 0; i < OBJECT_NR; i++) {
+   struct dept_pool *p = dept_pool + i;
+   int sz = p->tot_nr * p->obj_sz;
+   void *rpool;
+   bool need;
+
+   arch_spin_lock(_pool_spin);
+   need = !p->rpool;
+   arch_spin_unlock(_pool_spin);
+
+   if (!need)
+   continue;
+
+   rpool = vmalloc(sz);
+
+   if (!rpool) {
+   DEPT_STOP("Failed to extend internal resources.\n");
+   break;
+   }
+
+   arch_spin_lock(_pool_spin);
+   if (!p->rpool) {
+   p->rpool = rpool;
+   rpool = NULL;
+   

[PATCH RFC v7 19/23] dept: Apply timeout consideration to swait

2023-01-08 Thread Byungchul Park
Now that CONFIG_DEPT_AGGRESSIVE_TIMEOUT_WAIT was introduced, apply the
consideration to swait, assuming an input 'ret' in ___swait_event()
macro is used as a timeout value.

Signed-off-by: Byungchul Park 
---
 include/linux/swait.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/linux/swait.h b/include/linux/swait.h
index 1304209..339e5f2 100644
--- a/include/linux/swait.h
+++ b/include/linux/swait.h
@@ -162,7 +162,10 @@ static inline bool swq_has_sleeper(struct swait_queue_head 
*wq)
struct swait_queue __wait;  \
long __ret = ret;   \
\
-   sdt_might_sleep_weak(NULL); \
+   if (!__ret || __ret == MAX_SCHEDULE_TIMEOUT)\
+   sdt_might_sleep_weak(NULL); \
+   else\
+   sdt_might_sleep_weak_timeout(NULL); \
INIT_LIST_HEAD(&__wait.task_list);  \
for (;;) {  \
long __int = prepare_to_swait_event(, &__wait, state);\
-- 
1.9.1



[PATCH RFC v7 22/23] dept: Apply timeout consideration to dma fence wait

2023-01-08 Thread Byungchul Park
Now that CONFIG_DEPT_AGGRESSIVE_TIMEOUT_WAIT was introduced, apply the
consideration to dma fence wait.

Signed-off-by: Byungchul Park 
---
 drivers/dma-buf/dma-fence.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index dd190cf..ee9b350 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -783,7 +783,10 @@ struct default_wait_cb {
cb.task = current;
list_add(, >cb_list);
 
-   sdt_might_sleep_strong(NULL);
+   if (timeout == MAX_SCHEDULE_TIMEOUT)
+   sdt_might_sleep_strong(NULL);
+   else
+   sdt_might_sleep_strong_timeout(NULL);
while (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, >flags) && ret > 
0) {
if (intr)
__set_current_state(TASK_INTERRUPTIBLE);
@@ -887,7 +890,10 @@ struct default_wait_cb {
}
}
 
-   sdt_might_sleep_strong(NULL);
+   if (timeout == MAX_SCHEDULE_TIMEOUT)
+   sdt_might_sleep_strong(NULL);
+   else
+   sdt_might_sleep_strong_timeout(NULL);
while (ret > 0) {
if (intr)
set_current_state(TASK_INTERRUPTIBLE);
-- 
1.9.1



[PATCH RFC v7 23/23] dept: Record the latest one out of consecutive waits of the same class

2023-01-08 Thread Byungchul Park
The current code records all the waits for later use to track relation
between waits and events in each context. However, since the same class
is handled the same way, it'd be okay to record only one on behalf of
the others if they all have the same class.

Even though it's the ideal to search the whole history buffer for that,
since it'd cost too high, alternatively, let's keep the latest one at
least when the same class'ed waits consecutively appear.

Signed-off-by: Byungchul Park 
---
 kernel/dependency/dept.c | 21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/kernel/dependency/dept.c b/kernel/dependency/dept.c
index cd25995..9cd37b4 100644
--- a/kernel/dependency/dept.c
+++ b/kernel/dependency/dept.c
@@ -1521,9 +1521,28 @@ static inline struct dept_wait_hist *new_hist(void)
return wh;
 }
 
+static inline struct dept_wait_hist *last_hist(void)
+{
+   int pos_n = hist_pos_next();
+   struct dept_wait_hist *wh_n = hist(pos_n);
+
+   /*
+* This is the first try.
+*/
+   if (!pos_n && !wh_n->wait)
+   return NULL;
+
+   return hist(pos_n + DEPT_MAX_WAIT_HIST - 1);
+}
+
 static void add_hist(struct dept_wait *w, unsigned int wg, unsigned int 
ctxt_id)
 {
-   struct dept_wait_hist *wh = new_hist();
+   struct dept_wait_hist *wh;
+
+   wh = last_hist();
+
+   if (!wh || wh->wait->class != w->class || wh->ctxt_id != ctxt_id)
+   wh = new_hist();
 
if (likely(wh->wait))
put_wait(wh->wait);
-- 
1.9.1



[PATCH RFC v7 12/23] dept: Distinguish each syscall context from another

2023-01-08 Thread Byungchul Park
It enters kernel mode on each syscall and each syscall handling should
be considered independently from the point of view of Dept. Otherwise,
Dept may wrongly track dependencies across different syscalls.

That might be a real dependency from user mode. However, now that Dept
just started to work, conservatively let Dept not track dependencies
across different syscalls.

Signed-off-by: Byungchul Park 
---
 arch/arm64/kernel/syscall.c |  2 ++
 arch/x86/entry/common.c |  4 +++
 include/linux/dept.h| 39 +++---
 kernel/dependency/dept.c| 67 +++--
 4 files changed, 63 insertions(+), 49 deletions(-)

diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index a5de47e..e26d0ca 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -105,6 +106,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, 
int sc_nr,
 */
 
local_daif_restore(DAIF_PROCCTX);
+   dept_kernel_enter();
 
if (flags & _TIF_MTE_ASYNC_FAULT) {
/*
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index 6c28264..7cdd27a 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_XEN_PV
 #include 
@@ -72,6 +73,7 @@ static __always_inline bool do_syscall_x32(struct pt_regs 
*regs, int nr)
 
 __visible noinstr void do_syscall_64(struct pt_regs *regs, int nr)
 {
+   dept_kernel_enter();
add_random_kstack_offset();
nr = syscall_enter_from_user_mode(regs, nr);
 
@@ -120,6 +122,7 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs 
*regs)
 {
int nr = syscall_32_enter(regs);
 
+   dept_kernel_enter();
add_random_kstack_offset();
/*
 * Subtlety here: if ptrace pokes something larger than 2^31-1 into
@@ -140,6 +143,7 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs 
*regs)
int nr = syscall_32_enter(regs);
int res;
 
+   dept_kernel_enter();
add_random_kstack_offset();
/*
 * This cannot use syscall_enter_from_user_mode() as it has to
diff --git a/include/linux/dept.h b/include/linux/dept.h
index f2a3057..777c837 100644
--- a/include/linux/dept.h
+++ b/include/linux/dept.h
@@ -25,11 +25,16 @@
 #define DEPT_MAX_SUBCLASSES_USR(DEPT_MAX_SUBCLASSES / 
DEPT_MAX_SUBCLASSES_EVT)
 #define DEPT_MAX_SUBCLASSES_CACHE  2
 
-#define DEPT_SIRQ  0
-#define DEPT_HIRQ  1
-#define DEPT_IRQS_NR   2
-#define DEPT_SIRQF (1UL << DEPT_SIRQ)
-#define DEPT_HIRQF (1UL << DEPT_HIRQ)
+enum {
+   DEPT_CXT_SIRQ = 0,
+   DEPT_CXT_HIRQ,
+   DEPT_CXT_IRQS_NR,
+   DEPT_CXT_PROCESS = DEPT_CXT_IRQS_NR,
+   DEPT_CXTS_NR
+};
+
+#define DEPT_SIRQF (1UL << DEPT_CXT_SIRQ)
+#define DEPT_HIRQF (1UL << DEPT_CXT_HIRQ)
 
 struct dept_ecxt;
 struct dept_iecxt {
@@ -94,8 +99,8 @@ struct dept_class {
/*
 * for tracking IRQ dependencies
 */
-   struct dept_iecxt iecxt[DEPT_IRQS_NR];
-   struct dept_iwait iwait[DEPT_IRQS_NR];
+   struct dept_iecxt iecxt[DEPT_CXT_IRQS_NR];
+   struct dept_iwait iwait[DEPT_CXT_IRQS_NR];
 
/*
 * classified by a map embedded in task_struct,
@@ -207,8 +212,8 @@ struct dept_ecxt {
/*
 * where the IRQ-enabled happened
 */
-   unsigned long   enirq_ip[DEPT_IRQS_NR];
-   struct dept_stack *enirq_stack[DEPT_IRQS_NR];
+   unsigned long   enirq_ip[DEPT_CXT_IRQS_NR];
+   struct dept_stack *enirq_stack[DEPT_CXT_IRQS_NR];
 
/*
 * where the event context started
@@ -252,8 +257,8 @@ struct dept_wait {
/*
 * where the IRQ wait happened
 */
-   unsigned long   irq_ip[DEPT_IRQS_NR];
-   struct dept_stack *irq_stack[DEPT_IRQS_NR];
+   unsigned long   irq_ip[DEPT_CXT_IRQS_NR];
+   struct dept_stack *irq_stack[DEPT_CXT_IRQS_NR];
 
/*
 * where the wait happened
@@ -406,19 +411,19 @@ struct dept_task {
int wait_hist_pos;
 
/*
-* sequential id to identify each IRQ context
+* sequential id to identify each context
 */
-   unsigned intirq_id[DEPT_IRQS_NR];
+   unsigned int

[PATCH RFC v7 02/23] dept: Implement Dept(Dependency Tracker)

2023-01-08 Thread Byungchul Park
CURRENT STATUS
--
Lockdep tracks acquisition order of locks in order to detect deadlock,
and IRQ and IRQ enable/disable state as well to take accident
acquisitions into account.

Lockdep should be turned off once it detects and reports a deadlock
since the data structure and algorithm are not reusable after detection
because of the complex design.

PROBLEM
---
*Waits* and their *events* that never reach eventually cause deadlock.
However, Lockdep is only interested in lock acquisition order, forcing
to emulate lock acqusition even for just waits and events that have
nothing to do with real lock.

Even worse, no one likes Lockdep's false positive detection because that
prevents further one that might be more valuable. That's why all the
kernel developers are sensitive to Lockdep's false positive.

Besides those, by tracking acquisition order, it cannot correctly deal
with read lock and cross-event e.g. wait_for_completion()/complete() for
deadlock detection. Lockdep is no longer a good tool for that purpose.

SOLUTION

Again, *waits* and their *events* that never reach eventually cause
deadlock. The new solution, Dept(DEPendency Tracker), focuses on waits
and events themselves. Dept tracks waits and events and report it if
any event would be never reachable.

Dept does:
   . Works with read lock in the right way.
   . Works with any wait and event e.i. cross-event.
   . Continue to work even after reporting multiple times.
   . Provides simple and intuitive APIs.
   . Does exactly what dependency checker should do.

Q & A
-
Q. Is this the first try ever to address the problem?
A. No. Cross-release feature (b09be676e0ff2 locking/lockdep: Implement
   the 'crossrelease' feature) addressed it 2 years ago that was a
   Lockdep extension and merged but reverted shortly because:

   Cross-release started to report valuable hidden problems but started
   to give report false positive reports as well. For sure, no one
   likes Lockdep's false positive reports since it makes Lockdep stop,
   preventing reporting further real problems.

Q. Why not Dept was developed as an extension of Lockdep?
A. Lockdep definitely includes all the efforts great developers have
   made for a long time so as to be quite stable enough. But I had to
   design and implement newly because of the following:

   1) Lockdep was designed to track lock acquisition order. The APIs and
  implementation do not fit on wait-event model.
   2) Lockdep is turned off on detection including false positive. Which
  is terrible and prevents developing any extension for stronger
  detection.

Q. Do you intend to totally replace Lockdep?
A. No. Lockdep also checks if lock usage is correct. Of course, the
   dependency check routine should be replaced but the other functions
   should be still there.

Q. Do you mean the dependency check routine should be replaced right
   away?
A. No. I admit Lockdep is stable enough thanks to great efforts kernel
   developers have made. Lockdep and Dept, both should be in the kernel
   until Dept gets considered stable.

Q. Stronger detection capability would give more false positive report.
   Which was a big problem when cross-release was introduced. Is it ok
   with Dept?
A. It's ok. Dept allows multiple reporting thanks to simple and quite
   generalized design. Of course, false positive reports should be fixed
   anyway but it's no longer as a critical problem as it was.

Signed-off-by: Byungchul Park 
---
 include/linux/dept.h|  573 
 include/linux/hardirq.h |3 +
 include/linux/sched.h   |3 +
 init/init_task.c|2 +
 init/main.c |2 +
 kernel/Makefile |1 +
 kernel/dependency/Makefile  |3 +
 kernel/dependency/dept.c| 2980 +++
 kernel/dependency/dept_hash.h   |   10 +
 kernel/dependency/dept_object.h |   13 +
 kernel/exit.c   |1 +
 kernel/fork.c   |2 +
 kernel/module/main.c|2 +
 kernel/sched/core.c |9 +
 lib/Kconfig.debug   |   27 +
 lib/locking-selftest.c  |2 +
 16 files changed, 3633 insertions(+)
 create mode 100644 include/linux/dept.h
 create mode 100644 kernel/dependency/Makefile
 create mode 100644 kernel/dependency/dept.c
 create mode 100644 kernel/dependency/dept_hash.h
 create mode 100644 kernel/dependency/dept_object.h

diff --git a/include/linux/dept.h b/include/linux/dept.h
new file mode 100644
index ..f2a3057
--- /dev/null
+++ b/include/linux/dept.h
@@ -0,0 +1,573 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * DEPT(DEPendency Tracker) - runtime dependency tracker
+ *
+ * Started by Byungchul Park :
+ *
+ *  Copyright (c) 2020 LG Electronics, Inc., Byungchul Park
+ */
+
+#ifndef __LINUX_DEPT_H
+#define __LINUX_DEPT_H
+
+#ifdef CONFIG_DEPT
+
+#include 
+
+struct task_struct;
+
+#define DEPT_MAX_STACK_ENTRY 

[PATCH RFC v7 10/23] dept: Apply sdt_might_sleep_weak() to waitqueue wait

2023-01-08 Thread Byungchul Park
Makes Dept able to track dependencies by waitqueue waits, but weakly.

Signed-off-by: Byungchul Park 
---
 include/linux/wait.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/wait.h b/include/linux/wait.h
index a0307b5..ede466c 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -303,6 +304,7 @@ static inline void wake_up_pollfree(struct wait_queue_head 
*wq_head)
struct wait_queue_entry __wq_entry; 
\
long __ret = ret;   /* explicit shadow */   
\

\
+   sdt_might_sleep_weak(NULL); 
\
init_wait_entry(&__wq_entry, exclusive ? WQ_FLAG_EXCLUSIVE : 0);
\
for (;;) {  
\
long __int = prepare_to_wait_event(_head, &__wq_entry, 
state);\
@@ -318,6 +320,7 @@ static inline void wake_up_pollfree(struct wait_queue_head 
*wq_head)
cmd;
\
}   
\
finish_wait(_head, &__wq_entry); 
\
+   sdt_might_sleep_finish();   
\
 __out: __ret;  
\
 })
 
-- 
1.9.1



[PATCH RFC v7 06/23] dept: Add proc knobs to show stats and dependency graph

2023-01-08 Thread Byungchul Park
It'd be useful to show Dept internal stats and dependency graph on
runtime via proc for better information. Introduced the knobs.

Signed-off-by: Byungchul Park 
---
 kernel/dependency/Makefile|  1 +
 kernel/dependency/dept.c  | 24 --
 kernel/dependency/dept_internal.h | 26 +++
 kernel/dependency/dept_proc.c | 95 +++
 4 files changed, 131 insertions(+), 15 deletions(-)
 create mode 100644 kernel/dependency/dept_internal.h
 create mode 100644 kernel/dependency/dept_proc.c

diff --git a/kernel/dependency/Makefile b/kernel/dependency/Makefile
index b5cfb8a..92f1654 100644
--- a/kernel/dependency/Makefile
+++ b/kernel/dependency/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_DEPT) += dept.o
+obj-$(CONFIG_DEPT) += dept_proc.o
diff --git a/kernel/dependency/dept.c b/kernel/dependency/dept.c
index e950954..d164482 100644
--- a/kernel/dependency/dept.c
+++ b/kernel/dependency/dept.c
@@ -73,6 +73,7 @@
 #include 
 #include 
 #include 
+#include "dept_internal.h"
 
 static int dept_stop;
 static int dept_per_cpu_ready;
@@ -260,20 +261,13 @@ static inline bool valid_key(struct dept_key *k)
  *   have been freed will be placed.
  */
 
-enum object_t {
-#define OBJECT(id, nr) OBJECT_##id,
-   #include "dept_object.h"
-#undef  OBJECT
-   OBJECT_NR,
-};
-
 #define OBJECT(id, nr) \
 static struct dept_##id spool_##id[nr];
\
 static DEFINE_PER_CPU(struct llist_head, lpool_##id);
#include "dept_object.h"
 #undef  OBJECT
 
-static struct dept_pool pool[OBJECT_NR] = {
+struct dept_pool dept_pool[OBJECT_NR] = {
 #define OBJECT(id, nr) {   \
.name = #id,\
.obj_sz = sizeof(struct dept_##id), \
@@ -303,7 +297,7 @@ static void *from_pool(enum object_t t)
if (DEPT_WARN_ON(!irqs_disabled()))
return NULL;
 
-   p = [t];
+   p = _pool[t];
 
/*
 * Try local pool first.
@@ -338,7 +332,7 @@ static void *from_pool(enum object_t t)
 
 static void to_pool(void *o, enum object_t t)
 {
-   struct dept_pool *p = [t];
+   struct dept_pool *p = _pool[t];
struct llist_head *h;
 
preempt_disable();
@@ -2113,7 +2107,7 @@ void dept_map_copy(struct dept_map *to, struct dept_map 
*from)
clean_classes_cache(>map_key);
 }
 
-static LIST_HEAD(classes);
+LIST_HEAD(dept_classes);
 
 static inline bool within(const void *addr, void *start, unsigned long size)
 {
@@ -2145,7 +2139,7 @@ void dept_free_range(void *start, unsigned int sz)
while (unlikely(!dept_lock()))
cpu_relax();
 
-   list_for_each_entry_safe(c, n, , all_node) {
+   list_for_each_entry_safe(c, n, _classes, all_node) {
if (!within((void *)c->key, start, sz) &&
!within(c->name, start, sz))
continue;
@@ -2221,7 +2215,7 @@ static struct dept_class *check_new_class(struct dept_key 
*local,
c->sub_id = sub_id;
c->key = (unsigned long)(k->base + sub_id);
hash_add_class(c);
-   list_add(>all_node, );
+   list_add(>all_node, _classes);
 unlock:
dept_unlock();
 caching:
@@ -2932,8 +2926,8 @@ static void migrate_per_cpu_pool(void)
struct llist_head *from;
struct llist_head *to;
 
-   from = [i].boot_pool;
-   to = per_cpu_ptr(pool[i].lpool, boot_cpu);
+   from = _pool[i].boot_pool;
+   to = per_cpu_ptr(dept_pool[i].lpool, boot_cpu);
move_llist(to, from);
}
 }
diff --git a/kernel/dependency/dept_internal.h 
b/kernel/dependency/dept_internal.h
new file mode 100644
index ..007c1ee
--- /dev/null
+++ b/kernel/dependency/dept_internal.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Dept(DEPendency Tracker) - runtime dependency tracker internal header
+ *
+ * Started by Byungchul Park :
+ *
+ *  Copyright (c) 2020 LG Electronics, Inc., Byungchul Park
+ */
+
+#ifndef __DEPT_INTERNAL_H
+#define __DEPT_INTERNAL_H
+
+#ifdef CONFIG_DEPT
+
+enum object_t {
+#define OBJECT(id, nr) OBJECT_##id,
+   #include "dept_object.h"
+#undef  OBJECT
+   OBJECT_NR,
+};
+
+extern struct list_head dept_classes;
+extern struct dept_pool dept_pool[];
+
+#endif
+#endif /* __DEPT_INTERNAL_H */
diff --git a/kernel/dependency/dept_proc.c b/kernel/dependency/dept_proc.c
new file mode 100644
index ..7d61dfb
--- /dev/null
+++ b/kernel/dependency/dept_proc.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Procfs knobs for Dept(DEPendency Tracker)
+ *
+ * Started by Byungchul Park :
+ *
+ *  Copyright (C) 2021 LG Electronics, Inc. , Byungchul Park
+ */
+#include 
+#include 
+#include 
+#include "dept_internal.h"
+
+static void 

[PATCH RFC v7 00/23] DEPT(Dependency Tracker)

2023-01-08 Thread Byungchul Park
Just for those who want to try the latest version of DEPT.

---

Hi Linus and folks,

I've been developing a tool for detecting deadlock possibilities by
tracking wait/event rather than lock(?) acquisition order to try to
cover all synchonization machanisms. It's done on v6.2-rc2.

https://github.com/lgebyungchulpark/linux-dept/commits/dept2.0_on_v6.2-rc2

Benifit:

0. Works with all lock primitives.
1. Works with wait_for_completion()/complete().
2. Works with 'wait' on PG_locked.
3. Works with 'wait' on PG_writeback.
4. Works with swait/wakeup.
5. Works with waitqueue.
6. Multiple reports are allowed.
7. Deduplication control on multiple reports.
8. Withstand false positives thanks to 6.
9. Easy to tag any wait/event.

Future work:

0. To make it more stable.
1. To separates Dept from Lockdep.
2. To improves performance in terms of time and space.
3. To use Dept as a dependency engine for Lockdep.
4. To add any missing tags of wait/event in the kernel.
5. To deduplicate stack trace.

How to interpret reports:

1. E(event) in each context cannot be triggered because of the
   W(wait) that cannot be woken.
2. The stack trace helping find the problematic code is located
   in each conext's detail.

Thanks,
Byungchul

---

Changes from v6:

1. Tie to task scheduler code to track sleep and try_to_wake_up()
   assuming sleeps cause waits, try_to_wake_up()s would be the
   events that those are waiting for, of course with proper DEPT
   annotations, sdt_might_sleep_weak(), sdt_might_sleep_strong()
   and so on. For these cases, class is classified at sleep
   entrance rather than the synchronization initialization code.
   Which would extremely reduce false alarms.
2. Remove the DEPT associated instance in each page struct for
   tracking dependencies by PG_locked and PG_writeback thanks to
   the 1. work above.
3. Introduce CONFIG_DEPT_AGGRESIVE_TIMEOUT_WAIT to suppress
   reports that waits with timeout set are involved, for those
   who don't like verbose reporting.
4. Add a mechanism to refill the internal memory pools on
   running out so that DEPT could keep working as long as free
   memory is available in the system.
5. Re-enable tracking hashed-waitqueue wait. That's going to no
   longer generate false positives because class is classified
   at sleep entrance rather than the waitqueue initailization.
6. Refactor to make it easier to port onto each new version of
   the kernel.
7. Apply DEPT to dma fence.
8. Do trivial optimizaitions.

Changes from v5:

1. Use just pr_warn_once() rather than WARN_ONCE() on the lack
   of internal resources because WARN_*() printing stacktrace is
   too much for informing the lack. (feedback from Ted, Hyeonggon)
2. Fix trivial bugs like missing initializing a struct before
   using it.
3. Assign a different class per task when handling onstack
   variables for waitqueue or the like. Which makes Dept
   distinguish between onstack variables of different tasks so
   as to prevent false positives. (reported by Hyeonggon)
4. Make Dept aware of even raw_local_irq_*() to prevent false
   positives. (reported by Hyeonggon)
5. Don't consider dependencies between the events that might be
   triggered within __schedule() and the waits that requires
__schedule(), real ones. (reported by Hyeonggon)
6. Unstage the staged wait that has prepare_to_wait_event()'ed
   *and* yet to get to __schedule(), if we encounter __schedule()
   in-between for another sleep, which is possible if e.g. a
   mutex_lock() exists in 'condition' of ___wait_event().
7. Turn on CONFIG_PROVE_LOCKING when CONFIG_DEPT is on, to rely
   on the hardirq and softirq entrance tracing to make Dept more
   portable for now.

Changes from v4:

1. Fix some bugs that produce false alarms.
2. Distinguish each syscall context from another *for arm64*.
3. Make it not warn it but just print it in case Dept ring
   buffer gets exhausted. (feedback from Hyeonggon)
4. Explicitely describe "EXPERIMENTAL" and "Dept might produce
   false positive reports" in Kconfig. (feedback from Ted)

Changes from v3:

1. Dept shouldn't create dependencies between different depths
   of a class that were indicated by *_lock_nested(). Dept
   normally doesn't but it does once another lock class comes
   in. So fixed it. (feedback from Hyeonggon)
2. Dept considered a wait as a real wait once getting to
   __schedule() even if it has been set 

[PATCH RFC v7 01/23] llist: Move llist_{head, node} definition to types.h

2023-01-08 Thread Byungchul Park
llist_head and llist_node can be used by very primitives. For example,
Dept for tracking dependency uses llist things in its header. To avoid
header dependency, move those to types.h.

Signed-off-by: Byungchul Park 
---
 include/linux/llist.h | 8 
 include/linux/types.h | 8 
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/linux/llist.h b/include/linux/llist.h
index 85bda2d..99cc3c3 100644
--- a/include/linux/llist.h
+++ b/include/linux/llist.h
@@ -53,14 +53,6 @@
 #include 
 #include 
 
-struct llist_head {
-   struct llist_node *first;
-};
-
-struct llist_node {
-   struct llist_node *next;
-};
-
 #define LLIST_HEAD_INIT(name)  { NULL }
 #define LLIST_HEAD(name)   struct llist_head name = LLIST_HEAD_INIT(name)
 
diff --git a/include/linux/types.h b/include/linux/types.h
index ea8cf60a..b12a444 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -187,6 +187,14 @@ struct hlist_node {
struct hlist_node *next, **pprev;
 };
 
+struct llist_head {
+   struct llist_node *first;
+};
+
+struct llist_node {
+   struct llist_node *next;
+};
+
 struct ustat {
__kernel_daddr_tf_tfree;
 #ifdef CONFIG_ARCH_32BIT_USTAT_F_TINODE
-- 
1.9.1



[PATCH v2] drm/msm/dsi: Add missing check for alloc_ordered_workqueue

2023-01-08 Thread Jiasheng Jiang
Add check for the return value of alloc_ordered_workqueue as it may return
NULL pointer and cause NULL pointer dereference.
Moreover, change the "goto fail" into "return ret" and drop the "fail"
label since they are the same.

Signed-off-by: Jiasheng Jiang 
---
Changelog:

v1 -> v2:

1. Change the "goto fail" into "return ret" and drop the "fail" label.
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 89aadd3b3202..819f5be5fd77 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1884,7 +1884,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
msm_host = devm_kzalloc(>dev, sizeof(*msm_host), GFP_KERNEL);
if (!msm_host) {
ret = -ENOMEM;
-   goto fail;
+   return ret;
}
 
msm_host->pdev = pdev;
@@ -1893,14 +1893,14 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
ret = dsi_host_parse_dt(msm_host);
if (ret) {
pr_err("%s: failed to parse dt\n", __func__);
-   goto fail;
+   return ret;
}
 
msm_host->ctrl_base = msm_ioremap_size(pdev, "dsi_ctrl", 
_host->ctrl_size);
if (IS_ERR(msm_host->ctrl_base)) {
pr_err("%s: unable to map Dsi ctrl base\n", __func__);
ret = PTR_ERR(msm_host->ctrl_base);
-   goto fail;
+   return ret;
}
 
pm_runtime_enable(>dev);
@@ -1909,7 +1909,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
if (!msm_host->cfg_hnd) {
ret = -EINVAL;
pr_err("%s: get config failed\n", __func__);
-   goto fail;
+   return ret;
}
cfg = msm_host->cfg_hnd->cfg;
 
@@ -1917,7 +1917,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
if (msm_host->id < 0) {
ret = msm_host->id;
pr_err("%s: unable to identify DSI host index\n", __func__);
-   goto fail;
+   return ret;
}
 
/* fixup base address by io offset */
@@ -1927,19 +1927,19 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
cfg->regulator_data,
_host->supplies);
if (ret)
-   goto fail;
+   return ret;
 
ret = dsi_clk_init(msm_host);
if (ret) {
pr_err("%s: unable to initialize dsi clks\n", __func__);
-   goto fail;
+   return ret;
}
 
msm_host->rx_buf = devm_kzalloc(>dev, SZ_4K, GFP_KERNEL);
if (!msm_host->rx_buf) {
ret = -ENOMEM;
pr_err("%s: alloc rx temp buf failed\n", __func__);
-   goto fail;
+   return ret;
}
 
ret = devm_pm_opp_set_clkname(>dev, "byte");
@@ -1977,15 +1977,17 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
 
/* setup workqueue */
msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0);
+   if (!msm_host->workqueue) {
+   ret = -ENOMEM;
+   return ret;
+   }
+
INIT_WORK(_host->err_work, dsi_err_worker);
 
msm_dsi->id = msm_host->id;
 
DBG("Dsi Host %d initialized", msm_host->id);
return 0;
-
-fail:
-   return ret;
 }
 
 void msm_dsi_host_destroy(struct mipi_dsi_host *host)
-- 
2.25.1



[PATCH v2] drm/msm: Add missing check and destroy for alloc_ordered_workqueue

2023-01-08 Thread Jiasheng Jiang
Add check for the return value of alloc_ordered_workqueue as it may return
NULL pointer.
Moreover, use the destroy_workqueue in the later fails in order to avoid
memory leak.

Signed-off-by: Jiasheng Jiang 
---
Changelog:

v1 -> v2:

1. Convert "goto err_destroy_workqueue" into "goto err_msm_unit" and
remove "err_destroy_workqueue" label.
---
 drivers/gpu/drm/msm/msm_drv.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 8b0b0ac74a6f..54be323ed33d 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -418,6 +418,8 @@ static int msm_drm_init(struct device *dev, const struct 
drm_driver *drv)
priv->dev = ddev;
 
priv->wq = alloc_ordered_workqueue("msm", 0);
+   if (!priv->wq)
+   return -ENOMEM;
 
INIT_LIST_HEAD(>objects);
mutex_init(>obj_lock);
@@ -440,12 +442,12 @@ static int msm_drm_init(struct device *dev, const struct 
drm_driver *drv)
 
ret = msm_init_vram(ddev);
if (ret)
-   return ret;
+   goto err_msm_uninit;
 
/* Bind all our sub-components: */
ret = component_bind_all(dev, ddev);
if (ret)
-   return ret;
+   goto err_msm_uninit;
 
dma_set_max_seg_size(dev, UINT_MAX);
 
-- 
2.25.1



[PATCH v3 3/4] ARM: dts: qcom-msm8974: add SoC specific compat string to mdp5 node

2023-01-08 Thread Dmitry Baryshkov
Add SoC-specific compat string to the MDP5 device node to ease
distinguishing between various platforms.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi 
b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 8d216a3c0851..0cd59088f9c7 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -1549,7 +1549,7 @@ mdss: mdss@fd90 {
ranges;
 
mdp: mdp@fd90 {
-   compatible = "qcom,mdp5";
+   compatible = "qcom,msm8974-mdp5", "qcom,mdp5";
reg = <0xfd900100 0x22000>;
reg-names = "mdp_phys";
 
-- 
2.39.0



[PATCH v3 2/4] dt-bindings: display/msm: add SoC-specific compats to qcom, mdp5.yaml

2023-01-08 Thread Dmitry Baryshkov
Add platform-specific compatible entries to the qcom,mdp5.yaml to allow
distinguishing between various platforms. For msm8998 list
qcom,msm8998-dpu rather than -mdp5 to allow this binding to be handled
by either of the drivers.

Signed-off-by: Dmitry Baryshkov 
---
 .../bindings/display/msm/qcom,mdp5.yaml| 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
index cbcbe8b47e9b..9d9da987572f 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
@@ -16,7 +16,23 @@ maintainers:
 
 properties:
   compatible:
-const: qcom,mdp5
+oneOf:
+  - const: qcom,mdp5
+deprecated: true
+  - items:
+  - enum:
+  - qcom,apq8084-mdp5
+  - qcom,msm8916-mdp5
+  - qcom,msm8917-mdp5
+  - qcom,msm8953-mdp5
+  - qcom,msm8974-mdp5
+  - qcom,msm8976-mdp5
+  - qcom,msm8994-mdp5
+  - qcom,msm8996-mdp5
+  - qcom,msm8998-dpu
+  - qcom,sdm630-mdp5
+  - qcom,sdm660-mdp5
+  - const: qcom,mdp5
 
   reg:
 maxItems: 1
-- 
2.39.0



[PATCH v3 4/4] arm64: dts: qcom: add SoC specific compat strings to mdp5 nodes

2023-01-08 Thread Dmitry Baryshkov
Add SoC-specific compat string to the MDP5 device nodes to ease
distinguishing between various platforms.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +-
 arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +-
 arch/arm64/boot/dts/qcom/sdm630.dtsi  | 2 +-
 arch/arm64/boot/dts/qcom/sdm660.dtsi  | 2 ++
 4 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi 
b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 2ca8e977fc2a..0a23fb6efae8 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -989,7 +989,7 @@ mdss: mdss@1a0 {
ranges;
 
mdp: mdp@1a01000 {
-   compatible = "qcom,mdp5";
+   compatible = "qcom,msm8916-mdp5", "qcom,mdp5";
reg = <0x01a01000 0x89000>;
reg-names = "mdp_phys";
 
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi 
b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index d31464204f69..b5cd1bcad5eb 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -931,7 +931,7 @@ mdss: mdss@90 {
status = "disabled";
 
mdp: mdp@901000 {
-   compatible = "qcom,mdp5";
+   compatible = "qcom,msm8996-mdp5", "qcom,mdp5";
reg = <0x00901000 0x9>;
reg-names = "mdp_phys";
 
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi 
b/arch/arm64/boot/dts/qcom/sdm630.dtsi
index 13e6a4fbba27..65addd4c672e 100644
--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -1498,7 +1498,7 @@ mdss: mdss@c90 {
status = "disabled";
 
mdp: mdp@c901000 {
-   compatible = "qcom,mdp5";
+   compatible = "qcom,sdm630-mdp5", "qcom,mdp5";
reg = <0x0c901000 0x89000>;
reg-names = "mdp_phys";
 
diff --git a/arch/arm64/boot/dts/qcom/sdm660.dtsi 
b/arch/arm64/boot/dts/qcom/sdm660.dtsi
index d52123cb5cd3..cdaa0d7a66f3 100644
--- a/arch/arm64/boot/dts/qcom/sdm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm660.dtsi
@@ -142,6 +142,8 @@  {
 };
 
  {
+   compatible = "qcom,sdm660-mdp5", "qcom,mdp5";
+
ports {
port@1 {
reg = <1>;
-- 
2.39.0



[PATCH v3 0/4]

2023-01-08 Thread Dmitry Baryshkov
This patch concludes the conversion of display/msm schema from txt files
to YAML format.

The per-SoC compat (new addition) is required to ease migrating platform
support between mdp5 and dpu drivers.

Changes since v2:
- Fix MSM8998 compatible list: "qcom,msm8998-dpu", "msm,mdp5" to allow
  handling this device by either of the drivers.

Changes since v1:
- Renamed mdp@ to display-controller@ in the example (Krzysztof)
- Extended ports description to mention possible ports (Krzysztof)
- Fixed ports@ regexp to limit to just four ports (Krzysztof)
- Included patches adding per-SoC compat strings to the schema and to
  dtsi files.

Dmitry Baryshkov (4):
  dt-bindings: display/msm: convert MDP5 schema to YAML format
  dt-bindings: display/msm: add SoC-specific compats to qcom,mdp5.yaml
  ARM: dts: qcom-msm8974: add SoC specific compat string to mdp5 node
  arm64: dts: qcom: add SoC specific compat strings to mdp5 nodes

 .../devicetree/bindings/display/msm/mdp5.txt  | 132 ---
 .../bindings/display/msm/qcom,mdp5.yaml   | 154 ++
 arch/arm/boot/dts/qcom-msm8974.dtsi   |   2 +-
 arch/arm64/boot/dts/qcom/msm8916.dtsi |   2 +-
 arch/arm64/boot/dts/qcom/msm8996.dtsi |   2 +-
 arch/arm64/boot/dts/qcom/sdm630.dtsi  |   2 +-
 arch/arm64/boot/dts/qcom/sdm660.dtsi  |   2 +
 7 files changed, 160 insertions(+), 136 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/msm/mdp5.txt
 create mode 100644 Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml

-- 
2.39.0



[PATCH v3 1/4] dt-bindings: display/msm: convert MDP5 schema to YAML format

2023-01-08 Thread Dmitry Baryshkov
Convert the mdp5.txt into the yaml format. Changes to the existing (txt) schema:
 - MSM8996 has additional "iommu" clock, define it separately
 - Add new properties used on some of platforms:
   - interconnects, interconnect-names
   - iommus
   - power-domains
   - operating-points-v2, opp-table

Signed-off-by: Dmitry Baryshkov 
---
 .../devicetree/bindings/display/msm/mdp5.txt  | 132 -
 .../bindings/display/msm/qcom,mdp5.yaml   | 138 ++
 2 files changed, 138 insertions(+), 132 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/msm/mdp5.txt
 create mode 100644 Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml

diff --git a/Documentation/devicetree/bindings/display/msm/mdp5.txt 
b/Documentation/devicetree/bindings/display/msm/mdp5.txt
deleted file mode 100644
index 65d03c58dee6..
--- a/Documentation/devicetree/bindings/display/msm/mdp5.txt
+++ /dev/null
@@ -1,132 +0,0 @@
-Qualcomm adreno/snapdragon MDP5 display controller
-
-Description:
-
-This is the bindings documentation for the MDP5 display
-controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994 and MSM8996.
-
-MDP5:
-Required properties:
-- compatible:
-  * "qcom,mdp5" - MDP5
-- reg: Physical base address and length of the controller's registers.
-- reg-names: The names of register regions. The following regions are required:
-  * "mdp_phys"
-- interrupts: Interrupt line from MDP5 to MDSS interrupt controller.
-- clocks: device clocks. See ../clocks/clock-bindings.txt for details.
-- clock-names: the following clocks are required.
--   * "bus"
--   * "iface"
--   * "core"
--   * "vsync"
-- ports: contains the list of output ports from MDP. These connect to 
interfaces
-  that are external to the MDP hardware, such as HDMI, DSI, EDP etc (LVDS is a
-  special case since it is a part of the MDP block itself).
-
-  Each output port contains an endpoint that describes how it is connected to 
an
-  external interface. These are described by the standard properties documented
-  here:
-   Documentation/devicetree/bindings/graph.txt
-   Documentation/devicetree/bindings/media/video-interfaces.txt
-
-  The availability of output ports can vary across SoC revisions:
-
-  For MSM8974 and APQ8084:
-Port 0 -> MDP_INTF0 (eDP)
-Port 1 -> MDP_INTF1 (DSI1)
-Port 2 -> MDP_INTF2 (DSI2)
-Port 3 -> MDP_INTF3 (HDMI)
-
-  For MSM8916:
-Port 0 -> MDP_INTF1 (DSI1)
-
-  For MSM8994 and MSM8996:
-Port 0 -> MDP_INTF1 (DSI1)
-Port 1 -> MDP_INTF2 (DSI2)
-Port 2 -> MDP_INTF3 (HDMI)
-
-Optional properties:
-- clock-names: the following clocks are optional:
-  * "lut"
-  * "tbu"
-  * "tbu_rt"
-
-Example:
-
-/ {
-   ...
-
-   mdss: mdss@1a0 {
-   compatible = "qcom,mdss";
-   reg = <0x1a0 0x1000>,
- <0x1ac8000 0x3000>;
-   reg-names = "mdss_phys", "vbif_phys";
-
-   power-domains = < MDSS_GDSC>;
-
-   clocks = < GCC_MDSS_AHB_CLK>,
-< GCC_MDSS_AXI_CLK>,
-< GCC_MDSS_VSYNC_CLK>;
-   clock-names = "iface",
- "bus",
- "vsync"
-
-   interrupts = <0 72 0>;
-
-   interrupt-controller;
-   #interrupt-cells = <1>;
-
-   #address-cells = <1>;
-   #size-cells = <1>;
-   ranges;
-
-   mdp: mdp@1a01000 {
-   compatible = "qcom,mdp5";
-   reg = <0x1a01000 0x9>;
-   reg-names = "mdp_phys";
-
-   interrupt-parent = <>;
-   interrupts = <0 0>;
-
-   clocks = < GCC_MDSS_AHB_CLK>,
-< GCC_MDSS_AXI_CLK>,
-< GCC_MDSS_MDP_CLK>,
-< GCC_MDSS_VSYNC_CLK>;
-   clock-names = "iface",
- "bus",
- "core",
- "vsync";
-
-   ports {
-   #address-cells = <1>;
-   #size-cells = <0>;
-
-   port@0 {
-   reg = <0>;
-   mdp5_intf1_out: endpoint {
-   remote-endpoint = <_in>;
-   };
-   };
-   };
-   };
-
-   dsi0: dsi@1a98000 {
-   ...
-   ports {
-   ...
-   port@0 {
-   reg = <0>;
-   dsi0_in: endpoint {
-  

Re: [PATCH v2 6/8] drm/msm/dpu: Remove num_enc from topology struct in favour of num_dsc

2023-01-08 Thread Dmitry Baryshkov

On 22/12/2022 01:19, Marijn Suijten wrote:

Downstream calls this num_enc yet the DSC patches introduced a new
num_dsc struct member, leaving num_enc effectively unused.

Fixes: 7e9cc175b159 ("drm/msm/disp/dpu1: Add support for DSC in topology")
Signed-off-by: Marijn Suijten 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 9 -
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 4 ++--
  drivers/gpu/drm/msm/msm_drv.h   | 2 --
  3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 9c6817b5a194..a158cd502d38 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -579,19 +579,18 @@ static struct msm_display_topology 
dpu_encoder_get_topology(
topology.num_dspp = topology.num_lm;
}
  
-	topology.num_enc = 0;

topology.num_intf = intf_count;
  
  	if (dpu_enc->dsc) {

-   /* In case of Display Stream Compression (DSC), we would use
-* 2 encoders, 2 layer mixers and 1 interface
+   /*
+* In case of Display Stream Compression (DSC), we would use
+* 2 DSC encoders, 2 layer mixers and 1 interface
 * this is power optimal and can drive up to (including) 4k
 * screens
 */
-   topology.num_enc = 2;
topology.num_dsc = 2;
-   topology.num_intf = 1;
topology.num_lm = 2;
+   topology.num_intf = 1;


Unless there is a reason, please move num_intf assignment back while 
preparing v3.


With that fixed:

Reviewed-by: Dmitry Baryshkov 


}
  
  	return topology;

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index dcbf03d2940a..5e7aa0f3a31c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -548,8 +548,8 @@ static int _dpu_rm_populate_requirements(
  {
reqs->topology = req_topology;
  
-	DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n",

- reqs->topology.num_lm, reqs->topology.num_enc,
+   DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n",
+ reqs->topology.num_lm, reqs->topology.num_dsc,
  reqs->topology.num_intf);
  
  	return 0;

diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index d4e0ef608950..74626a271f46 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -82,14 +82,12 @@ enum msm_event_wait {
  /**
   * struct msm_display_topology - defines a display topology pipeline
   * @num_lm:   number of layer mixers used
- * @num_enc:  number of compression encoder blocks used
   * @num_intf: number of interfaces the panel is mounted on
   * @num_dspp: number of dspp blocks used
   * @num_dsc:  number of Display Stream Compression (DSC) blocks used
   */
  struct msm_display_topology {
u32 num_lm;
-   u32 num_enc;
u32 num_intf;
u32 num_dspp;
u32 num_dsc;


--
With best wishes
Dmitry



Re: [PATCH v2 4/8] drm/msm/dpu: Disallow unallocated resources to be returned

2023-01-08 Thread Dmitry Baryshkov

On 09/01/2023 01:28, Dmitry Baryshkov wrote:

On 22/12/2022 01:19, Marijn Suijten wrote:

In the event that the topology requests resources that have not been
created by the system (because they are typically not represented in
dpu_mdss_cfg ^1), the resource(s) in global_state (in this case DSC
blocks) remain NULL but will still be returned out of
dpu_rm_get_assigned_resources, where the caller expects to get an array
containing num_blks valid pointers (but instead gets these NULLs).

To prevent this from happening, where null-pointer dereferences
typically result in a hard-to-debug platform lockup, num_blks shouldn't
increase past NULL blocks and will print an error and break instead.
After all, max_blks represents the static size of the maximum number of
blocks whereas the actual amount varies per platform.

^1: which can happen after a git rebase ended up moving additions to
_dpu_cfg to a different struct which has the same patch context.

Fixes: bb00a452d6f7 ("drm/msm/dpu: Refactor resource manager")
Signed-off-by: Marijn Suijten 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 5 +
  1 file changed, 5 insertions(+)


I think the patch is not fully correct. Please check resource 
availability during allocation. I wouldn't expect an error from 
get_assigned_resources because of resource exhaustion.




Another option, since allocation functions (except DSC) already have 
these safety checks: check error message to mention internal 
inconstency: allocated resource doesn't exist.


--
With best wishes
Dmitry



Re: [PATCH v2 5/8] drm/msm/dpu: Reject topologies for which no DSC blocks are available

2023-01-08 Thread Dmitry Baryshkov

On 22/12/2022 01:19, Marijn Suijten wrote:

Resource allocation of DSC blocks should behave more like LMs and CTLs
where NULL resources (based on initial hw_blk creation via definitions
in the catalog) are skipped ^1.  The current hardcoded mapping of DSC
blocks however means that resource allocation shouldn't succeed at all
when the DSC block on the corresponding index doesn't exist, rather than
searching for the next free block.

This hardcoded mapping should be loosened separately as DPU 5.0.0
introduced a crossbar where DSC blocks can be "somewhat" freely bound to
any PP and CTL (in proper pairs).

^1: which, on hardware that supports DSC, can happen after a git rebase
ended up moving additions to _dpu_cfg to a different struct which has
the same patch context.

Fixes: f2803ee91a41 ("drm/msm/disp/dpu1: Add DSC support in RM")
Signed-off-by: Marijn Suijten 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 5 +
  1 file changed, 5 insertions(+)


Reviewed-by: Dmitry Baryshkov 

--
With best wishes
Dmitry



Re: [PATCH v2 4/8] drm/msm/dpu: Disallow unallocated resources to be returned

2023-01-08 Thread Dmitry Baryshkov

On 22/12/2022 01:19, Marijn Suijten wrote:

In the event that the topology requests resources that have not been
created by the system (because they are typically not represented in
dpu_mdss_cfg ^1), the resource(s) in global_state (in this case DSC
blocks) remain NULL but will still be returned out of
dpu_rm_get_assigned_resources, where the caller expects to get an array
containing num_blks valid pointers (but instead gets these NULLs).

To prevent this from happening, where null-pointer dereferences
typically result in a hard-to-debug platform lockup, num_blks shouldn't
increase past NULL blocks and will print an error and break instead.
After all, max_blks represents the static size of the maximum number of
blocks whereas the actual amount varies per platform.

^1: which can happen after a git rebase ended up moving additions to
_dpu_cfg to a different struct which has the same patch context.

Fixes: bb00a452d6f7 ("drm/msm/dpu: Refactor resource manager")
Signed-off-by: Marijn Suijten 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 5 +
  1 file changed, 5 insertions(+)


I think the patch is not fully correct. Please check resource 
availability during allocation. I wouldn't expect an error from 
get_assigned_resources because of resource exhaustion.


--
With best wishes
Dmitry



Re: [PATCH v2 1/8] drm/msm/dpu: Wire up DSC mask for active CTL configuration

2023-01-08 Thread Dmitry Baryshkov

On 22/12/2022 01:19, Marijn Suijten wrote:

Active CTLs have to configure what DSC block(s) have to be enabled, and
what DSC block(s) have to be flushed; this value was initialized to zero
resulting in the necessary register writes to never happen (or would
write zero otherwise).  This seems to have gotten lost in the DSC v4->v5
series while refactoring how the combination with merge_3d was handled.

Fixes: 58dca9810749 ("drm/msm/disp/dpu1: Add support for DSC in encoder")
Signed-off-by: Marijn Suijten 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 1 +
  2 files changed, 2 insertions(+)


Reviewed-by: Dmitry Baryshkov 


--
With best wishes
Dmitry



Re: [PATCH 3/6] drm/msm/dpu: add support for SM8550

2023-01-08 Thread Dmitry Baryshkov

On 04/01/2023 11:08, Neil Armstrong wrote:

Add definitions for the display hardware used on Qualcomm SM8550
platform.

Signed-off-by: Neil Armstrong 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 197 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |   1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h|   2 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|   1 +
  4 files changed, 201 insertions(+)


Reviewed-by: Dmitry Baryshkov 

--
With best wishes
Dmitry



Re: [PATCH 2/6] dt-bindings: display/msm: document the display hardware for SM8550

2023-01-08 Thread Dmitry Baryshkov

On 04/01/2023 11:08, Neil Armstrong wrote:

Document the MDSS and DPU blocks found on the Qualcomm SM8550
platform.

Signed-off-by: Neil Armstrong 


Please split this into two patches: one for mdss, one for dpu.


---
  .../bindings/display/msm/qcom,sm8550-dpu.yaml  | 134 +
  .../bindings/display/msm/qcom,sm8550-mdss.yaml | 331 +
  2 files changed, 465 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8550-dpu.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sm8550-dpu.yaml
new file mode 100644
index ..c3d5a98fe3c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8550-dpu.yaml
@@ -0,0 +1,134 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/msm/qcom,sm8550-dpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SM8550 Display DPU
+
+maintainers:
+  - Neil Armstrong 
+
+$ref: /schemas/display/msm/dpu-common.yaml#
+
+properties:
+  compatible:
+const: qcom,sm8550-dpu
+
+  reg:
+items:
+  - description: Address offset and size for mdp register set
+  - description: Address offset and size for vbif register set
+
+  reg-names:
+items:
+  - const: mdp
+  - const: vbif
+
+  clocks:
+items:
+  - description: Display AHB
+  - description: Display hf axi
+  - description: Display MDSS ahb
+  - description: Display lut
+  - description: Display core
+  - description: Display vsync
+
+  clock-names:
+items:
+  - const: bus
+  - const: nrt_bus
+  - const: iface
+  - const: lut
+  - const: core
+  - const: vsync
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+#include 
+#include 
+
+display-controller@ae01000 {
+compatible = "qcom,sm8550-dpu";
+reg = <0x0ae01000 0x8f000>,
+  <0x0aeb 0x2008>;
+reg-names = "mdp", "vbif";
+
+clocks = < GCC_DISP_AHB_CLK>,
+< GCC_DISP_HF_AXI_CLK>,
+< DISP_CC_MDSS_AHB_CLK>,
+< DISP_CC_MDSS_MDP_LUT_CLK>,
+< DISP_CC_MDSS_MDP_CLK>,
+< DISP_CC_MDSS_VSYNC_CLK>;
+clock-names = "bus",
+  "nrt_bus",
+  "iface",
+  "lut",
+  "core",
+  "vsync";
+
+assigned-clocks = < DISP_CC_MDSS_VSYNC_CLK>;
+assigned-clock-rates = <1920>;
+
+operating-points-v2 = <_opp_table>;
+power-domains = < SM8550_MMCX>;
+
+interrupt-parent = <>;
+interrupts = <0>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+dpu_intf1_out: endpoint {
+remote-endpoint = <_in>;
+};
+};
+
+port@1 {
+reg = <1>;
+dpu_intf2_out: endpoint {
+remote-endpoint = <_in>;
+};
+};
+};
+
+mdp_opp_table: opp-table {
+compatible = "operating-points-v2";
+
+opp-2 {
+opp-hz = /bits/ 64 <2>;
+required-opps = <_opp_low_svs>;
+};
+
+opp-32500 {
+opp-hz = /bits/ 64 <32500>;
+required-opps = <_opp_svs>;
+};
+
+opp-37500 {
+opp-hz = /bits/ 64 <37500>;
+required-opps = <_opp_svs_l1>;
+};
+
+opp-51400 {
+opp-hz = /bits/ 64 <51400>;
+required-opps = <_opp_nom>;
+};
+};
+};
+...
diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,sm8550-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sm8550-mdss.yaml
new file mode 100644
index ..71b5b5f75969
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8550-mdss.yaml
@@ -0,0 +1,331 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/msm/qcom,sm8550-mdss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SM8550 Display MDSS
+
+maintainers:
+  - Neil Armstrong 
+
+description:
+  SM8550 MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like
+  DPU display controller, DSI and DP interfaces etc.
+
+$ref: /schemas/display/msm/mdss-common.yaml#
+
+properties:
+  compatible:
+const: qcom,sm8550-mdss
+
+  clocks:
+items:
+  - description: Display MDSS AHB
+  - description: Display AHB
+  - description: Display hf AXI
+  - description: Display core
+
+  iommus:
+maxItems: 1
+
+  

Re: [PATCH 0/6] drm/msm: add support for SM8450

2023-01-08 Thread Dmitry Baryshkov

On 04/01/2023 11:08, Neil Armstrong wrote:

This adds support for the MDSS/DPU/DSI on the Qualcomm SM8550 platform.


Nit: please change the subject for v2. It's 8550, not 8450.



This patchset is based on the SM8450 display support serie at [1].

In order to work, the following patchsets are required:
- PM8550 LDO fix at [2]
- DISPCC driver at [3]

+ the DT changes.

[1] 
https://lore.kernel.org/all/20221207012231.112059-1-dmitry.barysh...@linaro.org/
[2] 
https://lore.kernel.org/all/20230102-topic-sm8550-upstream-fixes-reg-l11b-nldo-v1-1-d97def246...@linaro.org/
[3] 
https://lore.kernel.org/all/20230103-topic-sm8550-upstream-dispcc-v1-0-81bfcc26b...@linaro.org/

To: Rob Clark 
To: Abhinav Kumar 
To: Dmitry Baryshkov 
To: Sean Paul 
To: David Airlie 
To: Daniel Vetter 
To: Rob Herring 
To: Krzysztof Kozlowski 
To: Jonathan Marek 
Cc: linux-arm-...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: freedr...@lists.freedesktop.org
Cc: devicet...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Neil Armstrong 

---
Neil Armstrong (6):
   dt-bindings: display/msm: document the SM8550 DSI PHY
   dt-bindings: display/msm: document the display hardware for SM8550
   drm/msm/dpu: add support for SM8550
   drm/msm: mdss: add support for SM8550
   drm/msm/dsi: add support for DSI-PHY on SM8550
   drm/msm/dsi: add support for DSI 2.7.0

  .../bindings/display/msm/dsi-phy-7nm.yaml  |   1 +
  .../bindings/display/msm/qcom,sm8550-dpu.yaml  | 134 +
  .../bindings/display/msm/qcom,sm8550-mdss.yaml | 331 +
  drivers/gpu/drm/msm/Kconfig|   4 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 197 
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |   1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h|   2 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|   1 +
  drivers/gpu/drm/msm/dsi/dsi_cfg.c  |  16 +
  drivers/gpu/drm/msm/dsi/dsi_cfg.h  |   1 +
  drivers/gpu/drm/msm/dsi/phy/dsi_phy.c  |   2 +
  drivers/gpu/drm/msm/dsi/phy/dsi_phy.h  |   1 +
  drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c  | 102 +--
  drivers/gpu/drm/msm/msm_mdss.c |   2 +
  14 files changed, 775 insertions(+), 20 deletions(-)
---
base-commit: d862fd95b9c924bd0a257f7708a6e3868d39ff43
change-id: 20230103-topic-sm8550-upstream-mdss-dsi-35ca8acea529

Best regards,


--
With best wishes
Dmitry



Re: [PATCH 1/6] dt-bindings: display/msm: document the SM8550 DSI PHY

2023-01-08 Thread Dmitry Baryshkov

On 06/01/2023 17:41, Krzysztof Kozlowski wrote:

On 04/01/2023 10:08, Neil Armstrong wrote:

Document the SM8550 DSI PHY which is very close from the 7nm
and 5nm DSI PHYs found in earlier platforms.

Signed-off-by: Neil Armstrong 
---
  Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml | 1 +
  1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml
index bffd161fedfd..f72727f81076 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml
@@ -15,6 +15,7 @@ allOf:
  properties:
compatible:
  enum:
+  - qcom,dsi-phy-4nm-8550
- qcom,dsi-phy-5nm-8350
- qcom,dsi-phy-5nm-8450


Poor patterns once allowed like to keep growing... I commented here:
https://lore.kernel.org/all/ccbb47e4-d780-0b1d-814e-27e86b6c3...@linaro.org/

so let's wait for response about other compatibles.


I have fixed 8350 & 8450 while applying. Please rebase on top of 
msm-next-lumag-next with fixed compatibles.


Note: the DPU changes are not yet part of the msm-lumag-next.




- qcom,dsi-phy-7nm



Best regards,
Krzysztof



--
With best wishes
Dmitry



Re: [PATCH RESEND] drm/msm: Add missing check and destroy for alloc_ordered_workqueue

2023-01-08 Thread Dmitry Baryshkov

On 06/01/2023 10:47, Jiasheng Jiang wrote:

Add check for the return value of alloc_ordered_workqueue as it may return
NULL pointer.
Moreover, use the destroy_workqueue in the later fails in order to avoid
memory leak.

Fixes: c8afe684c95c ("drm/msm: basic KMS driver for snapdragon")
Signed-off-by: Jiasheng Jiang 
---
  drivers/gpu/drm/msm/msm_drv.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 8b0b0ac74a6f..b82d938226ad 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -418,6 +418,8 @@ static int msm_drm_init(struct device *dev, const struct 
drm_driver *drv)
priv->dev = ddev;
  
  	priv->wq = alloc_ordered_workqueue("msm", 0);

+   if (!priv->wq)
+   return -ENOMEM;
  
  	INIT_LIST_HEAD(>objects);

mutex_init(>obj_lock);
@@ -440,12 +442,12 @@ static int msm_drm_init(struct device *dev, const struct 
drm_driver *drv)
  
  	ret = msm_init_vram(ddev);

if (ret)
-   return ret;
+   goto err_destroy_workqueue;
  
  	/* Bind all our sub-components: */

ret = component_bind_all(dev, ddev);
if (ret)
-   return ret;
+   goto err_destroy_workqueue;
  
  	dma_set_max_seg_size(dev, UINT_MAX);
  
@@ -540,6 +542,8 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
  
  err_msm_uninit:

msm_drm_uninit(dev);


return ret is missing here. Your code will result in double free.

However the intent was to unroll each and every action of msm_drm_init() 
in msm_drm_uninit(). So in all your cases please goto err_msm_unit.



+err_destroy_workqueue:
+   destroy_workqueue(priv->wq);
return ret;
  }
  


--
With best wishes
Dmitry



Re: [PATCH] drm/msm/dsi: Add missing check for alloc_ordered_workqueue

2023-01-08 Thread Dmitry Baryshkov

On 06/01/2023 04:56, Jiasheng Jiang wrote:

Add check for the return value of alloc_ordered_workqueue as it may return
NULL pointer and cause NULL pointer dereference.
Moreover, change the "return ret" into "goto fail" in order to be
consistent with the others.

Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
Fixes: 32d3e0feccfe ("drm/msm: dsi: Use OPP API to set clk/perf state")
Signed-off-by: Jiasheng Jiang 
---
  drivers/gpu/drm/msm/dsi/dsi_host.c | 13 +
  1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 89aadd3b3202..12239f628d5a 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1944,19 +1944,19 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
  
  	ret = devm_pm_opp_set_clkname(>dev, "byte");

if (ret)
-   return ret;
+   goto fail;


fail: is just 'return ret', so these changes are not required. Instead 
the fail label can be dropped.



/* OPP table is optional */
ret = devm_pm_opp_of_add_table(>dev);
if (ret && ret != -ENODEV) {
dev_err(>dev, "invalid OPP table in device tree\n");
-   return ret;
+   goto fail;
}
  
  	msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);

if (msm_host->irq < 0) {
ret = msm_host->irq;
dev_err(>dev, "failed to get irq: %d\n", ret);
-   return ret;
+   goto fail;
}
  
  	/* do not autoenable, will be enabled later */

@@ -1966,7 +1966,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
if (ret < 0) {
dev_err(>dev, "failed to request IRQ%u: %d\n",
msm_host->irq, ret);
-   return ret;
+   goto fail;
}
  
  	init_completion(_host->dma_comp);

@@ -1977,6 +1977,11 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
  
  	/* setup workqueue */

msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0);
+   if (!msm_host->workqueue) {
+   ret = -ENOMEM;
+   goto fail;
+   }
+
INIT_WORK(_host->err_work, dsi_err_worker);
  
  	msm_dsi->id = msm_host->id;


--
With best wishes
Dmitry



Re: [PATCH] drm/msm/hdmi: Add missing check for alloc_ordered_workqueue

2023-01-08 Thread Dmitry Baryshkov

On 06/01/2023 04:30, Jiasheng Jiang wrote:

Add check for the return value of alloc_ordered_workqueue as it may return
NULL pointer and cause NULL pointer dereference in `hdmi_hdcp.c` and
`hdmi_hpd.c`.

Fixes: c6a57a50ad56 ("drm/msm/hdmi: add hdmi hdcp support (V3)")
Signed-off-by: Jiasheng Jiang 
---
  drivers/gpu/drm/msm/hdmi/hdmi.c | 4 
  1 file changed, 4 insertions(+)


Reviewed-by: Dmitry Baryshkov 

--
With best wishes
Dmitry



Re: [PATCH] drm/msm/dpu: Add check for cstate

2023-01-08 Thread Dmitry Baryshkov

On 08/01/2023 23:56, Dmitry Baryshkov wrote:

On 06/12/2022 10:05, Jiasheng Jiang wrote:

As kzalloc may fail and return NULL pointer,
it should be better to check cstate
in order to avoid the NULL pointer dereference
in __drm_atomic_helper_crtc_reset.

Fixes: 1cff7440a86e ("drm/msm: Convert to using 
__drm_atomic_helper_crtc_reset() for reset.")

Signed-off-by: Jiasheng Jiang 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

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

index 13ce321283ff..22c2787b7b38 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -968,7 +968,10 @@ static void dpu_crtc_reset(struct drm_crtc *crtc)
  if (crtc->state)
  dpu_crtc_destroy_state(crtc, crtc->state);
-    __drm_atomic_helper_crtc_reset(crtc, >base);
+    if (cstate)
+    __drm_atomic_helper_crtc_reset(crtc, >base);
+    else
+    __drm_atomic_helper_crtc_reset(crtc, NULL);


NAK.

The proper fix is to add the if() but to skip the else clause. We should 
not reset the crtc's state if memory allocation failed.


On the other hand... Some of the drivers do exactly this ops.

With the message fixed:

Reviewed-by: Dmitry Baryshkov 

--
With best wishes
Dmitry



Re: [PATCH] drm/msm/dpu: Add check for cstate

2023-01-08 Thread Dmitry Baryshkov

On 06/12/2022 10:05, Jiasheng Jiang wrote:

As kzalloc may fail and return NULL pointer,
it should be better to check cstate
in order to avoid the NULL pointer dereference
in __drm_atomic_helper_crtc_reset.

Fixes: 1cff7440a86e ("drm/msm: Convert to using __drm_atomic_helper_crtc_reset() for 
reset.")
Signed-off-by: Jiasheng Jiang 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 13ce321283ff..22c2787b7b38 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -968,7 +968,10 @@ static void dpu_crtc_reset(struct drm_crtc *crtc)
if (crtc->state)
dpu_crtc_destroy_state(crtc, crtc->state);
  
-	__drm_atomic_helper_crtc_reset(crtc, >base);

+   if (cstate)
+   __drm_atomic_helper_crtc_reset(crtc, >base);
+   else
+   __drm_atomic_helper_crtc_reset(crtc, NULL);


NAK.

The proper fix is to add the if() but to skip the else clause. We should 
not reset the crtc's state if memory allocation failed.



  }
  
  /**


--
With best wishes
Dmitry



Re: [PATCH v5 02/12] drm/msm/dpu: Introduce SC8280XP

2023-01-08 Thread Dmitry Baryshkov

On 09/12/2022 01:31, Kuogee Hsieh wrote:


On 12/7/2022 2:00 PM, Bjorn Andersson wrote:

From: Bjorn Andersson 

The Qualcomm SC8280XP platform contains DPU version 8.0.0, has 9
interfaces, 2 DSI controllers and 4 DisplayPort controllers. Extend the
necessary definitions and describe the DPU in the SC8280XP.

Signed-off-by: Bjorn Andersson 
Signed-off-by: Bjorn Andersson 

Reviewed-by: Kuogee Hsieh 

---

Changes since v4:
- Fix highest_bank_bit, based on downstream
- Add ubwc_swizzle
- Use CTL_SC7280_MASK instead of listing the bits directly

  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 217 ++
  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   1 +
  .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  18 ++
  .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |   3 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h   |   2 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   1 +
  drivers/gpu/drm/msm/msm_drv.h |   1 +
  7 files changed, 243 insertions(+)

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

index 2196e205efa5..0315fe68af2f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -124,6 +124,19 @@
    BIT(MDP_AD4_0_INTR) | \
    BIT(MDP_AD4_1_INTR))
+#define IRQ_SC8280XP_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
+   BIT(MDP_SSPP_TOP0_INTR2) | \
+   BIT(MDP_SSPP_TOP0_HIST_INTR) | \
+   BIT(MDP_INTF0_7xxx_INTR) | \
+   BIT(MDP_INTF1_7xxx_INTR) | \
+   BIT(MDP_INTF2_7xxx_INTR) | \
+   BIT(MDP_INTF3_7xxx_INTR) | \
+   BIT(MDP_INTF4_7xxx_INTR) | \
+   BIT(MDP_INTF5_7xxx_INTR) | \
+   BIT(MDP_INTF6_7xxx_INTR) | \
+   BIT(MDP_INTF7_7xxx_INTR) | \
+   BIT(MDP_INTF8_7xxx_INTR))
+
  #define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \
   BIT(DPU_WB_UBWC) | \
   BIT(DPU_WB_YUV_CONFIG) | \
@@ -365,6 +378,20 @@ static const struct dpu_caps sc8180x_dpu_caps = {
  .max_vdeci_exp = MAX_VERT_DECIMATION,
  };
+static const struct dpu_caps sc8280xp_dpu_caps = {
+    .max_mixer_width = 2560,
+    .max_mixer_blendstages = 11,
+    .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
+    .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+    .ubwc_version = DPU_HW_UBWC_VER_40,
+    .has_src_split = true,
+    .has_dim_layer = true,
+    .has_idle_pc = true,
+    .has_3d_merge = true,
+    .max_linewidth = 5120,
+    .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
  static const struct dpu_caps sm8250_dpu_caps = {
  .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
  .max_mixer_blendstages = 0xb,
@@ -545,6 +572,25 @@ static const struct dpu_mdp_cfg sc7280_mdp[] = {
  },
  };
+static const struct dpu_mdp_cfg sc8280xp_mdp[] = {
+    {
+    .name = "top_0", .id = MDP_TOP,
+    .base = 0x0, .len = 0x494,
+    .features = 0,
+    .highest_bank_bit = 2,
+    .ubwc_swizzle = 6,
+    .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0},
+    .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0},
+    .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0},
+    .clk_ctrls[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0},
+    .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8},
+    .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8},
+    .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x2bc, .bit_off = 
8},
+    .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x2c4, .bit_off = 
8},
+    .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 
20},

+    },
+};
+
  static const struct dpu_mdp_cfg qcm2290_mdp[] = {
  {
  .name = "top_0", .id = MDP_TOP,
@@ -648,6 +694,45 @@ static const struct dpu_ctl_cfg sc7180_ctl[] = {
  },
  };
+static const struct dpu_ctl_cfg sc8280xp_ctl[] = {
+    {
+    .name = "ctl_0", .id = CTL_0,
+    .base = 0x15000, .len = 0x204,
+    .features = CTL_SC7280_MASK,
+    .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+    },
+    {
+    .name = "ctl_1", .id = CTL_1,
+    .base = 0x16000, .len = 0x204,
+    .features = CTL_SC7280_MASK,
+    .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+    },
+    {
+    .name = "ctl_2", .id = CTL_2,
+    .base = 0x17000, .len = 0x204,
+    .features = CTL_SC7280_MASK,
+    .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+    },
+    {
+    .name = "ctl_3", .id = CTL_3,
+    .base = 0x18000, .len = 0x204,
+    .features = CTL_SC7280_MASK,
+    .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+    },
+    {
+    .name = "ctl_4", .id = CTL_4,
+    .base = 0x19000, .len = 0x204,
+    .features = CTL_SC7280_MASK,
+    .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+    },
+    {
+    .name = "ctl_5", .id = CTL_5,
+    .base = 0x1a000, .len = 0x204,
+    .features = CTL_SC7280_MASK,
+    .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 

[PATCH v1] drm/shmem-helper: Remove another errant put in error path

2023-01-08 Thread Dmitry Osipenko
drm_gem_shmem_mmap() doesn't own reference in error code path, resulting
in the dma-buf shmem GEM object getting prematurely freed leading to a
later use-after-free.

Fixes: f49a51bfdc8e ("drm/shme-helpers: Fix dma_buf_mmap forwarding bug")
Cc: sta...@vger.kernel.org
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index f21f47737817..8b20b41497e8 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -624,11 +624,14 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object 
*shmem, struct vm_area_struct
int ret;
 
if (obj->import_attach) {
-   /* Drop the reference drm_gem_mmap_obj() acquired.*/
-   drm_gem_object_put(obj);
vma->vm_private_data = NULL;
+   ret = dma_buf_mmap(obj->dma_buf, vma, 0);
+
+   /* Drop the reference drm_gem_mmap_obj() acquired.*/
+   if (!ret)
+   drm_gem_object_put(obj);
 
-   return dma_buf_mmap(obj->dma_buf, vma, 0);
+   return ret;
}
 
ret = drm_gem_shmem_get_pages(shmem);
-- 
2.38.1



[PATCH] drm/msm/dpu: sort entries in the HW catalog

2023-01-08 Thread Dmitry Baryshkov
Different entries into the catalog were added quite randomly. Enforce
the sorting order of some kind. It is not alphabetic to prevent the
patch from growing uncontrollably. Thus SDM comes before SC and SM
platforms and QCM is kept as the last one. There are no functional
changes in this patch.

Signed-off-by: Dmitry Baryshkov 
---

Yes, I hate such mass-moves too. However the entries in this file are
slowly becoming uncontrollable. Let's enforce some order now (while it's
late already, but not _that_ late).

---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 484 +-
 1 file changed, 244 insertions(+), 240 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index fef33e89678d..6f346a940c61 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -3,6 +3,17 @@
  * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
+/*
+ * Individual entries are sorted by the SoC type and index.
+ * Please keep the following sorting order:
+ *
+ * - MSM
+ * - SDM
+ * - SC
+ * - SM
+ * - QCM*
+ */
+
 #define pr_fmt(fmt)"[drm:%s:%d] " fmt, __func__, __LINE__
 #include 
 #include 
@@ -102,15 +113,6 @@
 BIT(MDP_INTF1_7xxx_INTR) | \
 BIT(MDP_INTF5_7xxx_INTR))
 
-#define IRQ_SM8250_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
-BIT(MDP_SSPP_TOP0_INTR2) | \
-BIT(MDP_SSPP_TOP0_HIST_INTR) | \
-BIT(MDP_INTF0_INTR) | \
-BIT(MDP_INTF1_INTR) | \
-BIT(MDP_INTF2_INTR) | \
-BIT(MDP_INTF3_INTR) | \
-BIT(MDP_INTF4_INTR))
-
 #define IRQ_SC8180X_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
  BIT(MDP_SSPP_TOP0_INTR2) | \
  BIT(MDP_SSPP_TOP0_HIST_INTR) | \
@@ -123,6 +125,15 @@
  BIT(MDP_AD4_0_INTR) | \
  BIT(MDP_AD4_1_INTR))
 
+#define IRQ_SM8250_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
+BIT(MDP_SSPP_TOP0_INTR2) | \
+BIT(MDP_SSPP_TOP0_HIST_INTR) | \
+BIT(MDP_INTF0_INTR) | \
+BIT(MDP_INTF1_INTR) | \
+BIT(MDP_INTF2_INTR) | \
+BIT(MDP_INTF3_INTR) | \
+BIT(MDP_INTF4_INTR))
+
 #define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \
 BIT(DPU_WB_UBWC) | \
 BIT(DPU_WB_YUV_CONFIG) | \
@@ -320,19 +331,19 @@ static const struct dpu_caps sc7180_dpu_caps = {
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 };
 
-static const struct dpu_caps sm6115_dpu_caps = {
+static const struct dpu_caps sc7280_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
-   .max_mixer_blendstages = 0x4,
-   .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
-   .ubwc_version = DPU_HW_UBWC_VER_20,
+   .max_mixer_blendstages = 0x7,
+   .qseed_type = DPU_SSPP_SCALER_QSEED4,
+   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
+   .ubwc_version = DPU_HW_UBWC_VER_30,
.has_dim_layer = true,
.has_idle_pc = true,
-   .max_linewidth = 2160,
+   .max_linewidth = 2400,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 };
 
-static const struct dpu_caps sm8150_dpu_caps = {
+static const struct dpu_caps sc8180x_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
@@ -348,7 +359,19 @@ static const struct dpu_caps sm8150_dpu_caps = {
.max_vdeci_exp = MAX_VERT_DECIMATION,
 };
 
-static const struct dpu_caps sc8180x_dpu_caps = {
+static const struct dpu_caps sm6115_dpu_caps = {
+   .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+   .max_mixer_blendstages = 0x4,
+   .qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
+   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+   .ubwc_version = DPU_HW_UBWC_VER_20,
+   .has_dim_layer = true,
+   .has_idle_pc = true,
+   .max_linewidth = 2160,
+   .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_caps sm8150_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
@@ -378,18 +401,6 @@ static const struct dpu_caps sm8250_dpu_caps = {
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 };
 
-static const struct dpu_caps sc7280_dpu_caps = {
-   .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
-   .max_mixer_blendstages = 0x7,
-   .qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
-   .ubwc_version = DPU_HW_UBWC_VER_30,
-   .has_dim_layer = true,
-   

[PATCH v10 11/11] drm/panfrost: Switch to generic memory shrinker

2023-01-08 Thread Dmitry Osipenko
Replace Panfrost's custom memory shrinker with a common drm-shmem
memory shrinker.

Tested-by: Steven Price  # Firefly-RK3288
Reviewed-by: Steven Price 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c|   2 -
 drivers/gpu/drm/panfrost/Makefile |   1 -
 drivers/gpu/drm/panfrost/panfrost_device.h|   4 -
 drivers/gpu/drm/panfrost/panfrost_drv.c   |  27 ++--
 drivers/gpu/drm/panfrost/panfrost_gem.c   |  30 ++--
 drivers/gpu/drm/panfrost/panfrost_gem.h   |   9 --
 .../gpu/drm/panfrost/panfrost_gem_shrinker.c  | 129 --
 drivers/gpu/drm/panfrost/panfrost_job.c   |  18 ++-
 include/drm/drm_gem_shmem_helper.h|   7 -
 9 files changed, 47 insertions(+), 180 deletions(-)
 delete mode 100644 drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 3ab5ec325ddb..c963cbc7a915 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -89,8 +89,6 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, 
bool private)
if (ret)
goto err_release;
 
-   INIT_LIST_HEAD(>madv_list);
-
if (!private) {
/*
 * Our buffers are kept pinned, so allocating them
diff --git a/drivers/gpu/drm/panfrost/Makefile 
b/drivers/gpu/drm/panfrost/Makefile
index 7da2b3f02ed9..11622e22cf15 100644
--- a/drivers/gpu/drm/panfrost/Makefile
+++ b/drivers/gpu/drm/panfrost/Makefile
@@ -5,7 +5,6 @@ panfrost-y := \
panfrost_device.o \
panfrost_devfreq.o \
panfrost_gem.o \
-   panfrost_gem_shrinker.o \
panfrost_gpu.o \
panfrost_job.o \
panfrost_mmu.o \
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index d9ba68cffb77..28f28bbdbda9 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -116,10 +116,6 @@ struct panfrost_device {
atomic_t pending;
} reset;
 
-   struct mutex shrinker_lock;
-   struct list_head shrinker_list;
-   struct shrinker shrinker;
-
struct panfrost_devfreq pfdevfreq;
 };
 
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 9f3f2283b67a..e31cf9db005b 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -169,7 +169,6 @@ panfrost_lookup_bos(struct drm_device *dev,
break;
}
 
-   atomic_inc(>gpu_usecount);
job->mappings[i] = mapping;
}
 
@@ -401,7 +400,6 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, 
void *data,
 {
struct panfrost_file_priv *priv = file_priv->driver_priv;
struct drm_panfrost_madvise *args = data;
-   struct panfrost_device *pfdev = dev->dev_private;
struct drm_gem_object *gem_obj;
struct panfrost_gem_object *bo;
int ret = 0;
@@ -414,11 +412,15 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, 
void *data,
 
bo = to_panfrost_bo(gem_obj);
 
+   if (bo->is_heap) {
+   args->retained = 1;
+   goto out_put_object;
+   }
+
ret = dma_resv_lock_interruptible(bo->base.base.resv, NULL);
if (ret)
goto out_put_object;
 
-   mutex_lock(>shrinker_lock);
mutex_lock(>mappings.lock);
if (args->madv == PANFROST_MADV_DONTNEED) {
struct panfrost_gem_mapping *first;
@@ -444,17 +446,8 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, 
void *data,
 
args->retained = drm_gem_shmem_madvise(>base, args->madv);
 
-   if (args->retained) {
-   if (args->madv == PANFROST_MADV_DONTNEED)
-   list_move_tail(>base.madv_list,
-  >shrinker_list);
-   else if (args->madv == PANFROST_MADV_WILLNEED)
-   list_del_init(>base.madv_list);
-   }
-
 out_unlock_mappings:
mutex_unlock(>mappings.lock);
-   mutex_unlock(>shrinker_lock);
dma_resv_unlock(bo->base.base.resv);
 out_put_object:
drm_gem_object_put(gem_obj);
@@ -586,9 +579,6 @@ static int panfrost_probe(struct platform_device *pdev)
ddev->dev_private = pfdev;
pfdev->ddev = ddev;
 
-   mutex_init(>shrinker_lock);
-   INIT_LIST_HEAD(>shrinker_list);
-
err = panfrost_device_init(pfdev);
if (err) {
if (err != -EPROBE_DEFER)
@@ -610,10 +600,14 @@ static int panfrost_probe(struct platform_device *pdev)
if (err < 0)
goto err_out1;
 
-   panfrost_gem_shrinker_init(ddev);
+   err = drmm_gem_shmem_init(ddev);
+   if (err < 0)
+   goto err_out2;
 
return 0;
 
+err_out2:
+   drm_dev_unregister(ddev);
 err_out1:
   

[PATCH v10 10/11] drm/virtio: Support memory shrinking

2023-01-08 Thread Dmitry Osipenko
Support generic drm-shmem memory shrinker and add new madvise IOCTL to
the VirtIO-GPU driver. BO cache manager of Mesa driver will mark BOs as
"don't need" using the new IOCTL to let shrinker purge the marked BOs on
OOM, the shrinker will also evict unpurgeable shmem BOs from memory if
guest supports SWAP file or partition.

Signed-off-by: Daniel Almeida 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h|  18 +++-
 drivers/gpu/drm/virtio/virtgpu_gem.c|  52 ++
 drivers/gpu/drm/virtio/virtgpu_ioctl.c  |  37 +++
 drivers/gpu/drm/virtio/virtgpu_kms.c|   8 ++
 drivers/gpu/drm/virtio/virtgpu_object.c | 132 +++-
 drivers/gpu/drm/virtio/virtgpu_plane.c  |  22 +++-
 drivers/gpu/drm/virtio/virtgpu_vq.c |  40 +++
 include/uapi/drm/virtgpu_drm.h  |  14 +++
 8 files changed, 293 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index af6ffb696086..07eb8d3e5cfd 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -89,6 +89,7 @@ struct virtio_gpu_object {
uint32_t hw_res_handle;
bool dumb;
bool created;
+   bool detached;
bool host3d_blob, guest_blob;
uint32_t blob_mem, blob_flags;
 
@@ -277,7 +278,7 @@ struct virtio_gpu_fpriv {
 };
 
 /* virtgpu_ioctl.c */
-#define DRM_VIRTIO_NUM_IOCTLS 12
+#define DRM_VIRTIO_NUM_IOCTLS 13
 extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
 void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file);
 
@@ -313,6 +314,10 @@ void virtio_gpu_array_put_free(struct 
virtio_gpu_object_array *objs);
 void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev,
   struct virtio_gpu_object_array *objs);
 void virtio_gpu_array_put_free_work(struct work_struct *work);
+int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev,
+struct virtio_gpu_object_array *objs);
+int virtio_gpu_gem_host_mem_release(struct virtio_gpu_object *bo);
+int virtio_gpu_gem_madvise(struct virtio_gpu_object *obj, int madv);
 
 /* virtgpu_vq.c */
 int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev);
@@ -324,6 +329,8 @@ void virtio_gpu_cmd_create_resource(struct 
virtio_gpu_device *vgdev,
struct virtio_gpu_fence *fence);
 void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev,
   struct virtio_gpu_object *bo);
+int virtio_gpu_cmd_release_resource(struct virtio_gpu_device *vgdev,
+   struct virtio_gpu_object *bo);
 void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
uint64_t offset,
uint32_t width, uint32_t height,
@@ -344,6 +351,9 @@ void virtio_gpu_object_attach(struct virtio_gpu_device 
*vgdev,
  struct virtio_gpu_object *obj,
  struct virtio_gpu_mem_entry *ents,
  unsigned int nents);
+void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev,
+ struct virtio_gpu_object *obj,
+ struct virtio_gpu_fence *fence);
 int virtio_gpu_attach_status_page(struct virtio_gpu_device *vgdev);
 int virtio_gpu_detach_status_page(struct virtio_gpu_device *vgdev);
 void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev,
@@ -456,6 +466,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
*vgdev,
 
 bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo);
 
+int virtio_gpu_reattach_shmem_object(struct virtio_gpu_object *bo);
+
 int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev,
   uint32_t *resid);
 /* virtgpu_prime.c */
@@ -486,4 +498,8 @@ void virtio_gpu_vram_unmap_dma_buf(struct device *dev,
   struct sg_table *sgt,
   enum dma_data_direction dir);
 
+/* virtgpu_gem_shrinker.c */
+int virtio_gpu_gem_shrinker_init(struct virtio_gpu_device *vgdev);
+void virtio_gpu_gem_shrinker_fini(struct virtio_gpu_device *vgdev);
+
 #endif
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c 
b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 7db48d17ee3a..8f65911b1e99 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -294,3 +294,55 @@ void virtio_gpu_array_put_free_work(struct work_struct 
*work)
}
spin_unlock(>obj_free_lock);
 }
+
+int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev,
+struct virtio_gpu_object_array *objs)
+{
+   struct virtio_gpu_object *bo;
+   int ret = 0;
+   u32 i;
+
+   for (i = 0; i < objs->nents; i++) {
+   bo = gem_to_virtio_gpu_obj(objs->objs[i]);
+
+   if 

[PATCH v10 09/11] drm/gem: Add drm_gem_pin_unlocked()

2023-01-08 Thread Dmitry Osipenko
Add unlocked variants of drm_gem_un/pin() functions. These new helpers
will take care of GEM dma-reservation locking for DRM drivers.

VirtIO-GPU driver will use these helpers to pin shmem framebuffers,
preventing them from eviction during scanout.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem.c | 29 +
 include/drm/drm_gem.h |  3 +++
 2 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index dbb48fc9dff3..0b8d3da985c7 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1167,6 +1167,35 @@ void drm_gem_unpin(struct drm_gem_object *obj)
obj->funcs->unpin(obj);
 }
 
+int drm_gem_pin_unlocked(struct drm_gem_object *obj)
+{
+   int ret;
+
+   if (!obj->funcs->pin)
+   return 0;
+
+   ret = dma_resv_lock_interruptible(obj->resv, NULL);
+   if (ret)
+   return ret;
+
+   ret = obj->funcs->pin(obj);
+   dma_resv_unlock(obj->resv);
+
+   return ret;
+}
+EXPORT_SYMBOL(drm_gem_pin_unlocked);
+
+void drm_gem_unpin_unlocked(struct drm_gem_object *obj)
+{
+   if (!obj->funcs->unpin)
+   return;
+
+   dma_resv_lock(obj->resv, NULL);
+   obj->funcs->unpin(obj);
+   dma_resv_unlock(obj->resv);
+}
+EXPORT_SYMBOL(drm_gem_unpin_unlocked);
+
 int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map)
 {
int ret;
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 8e5c22f25691..6f6d96f79a67 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -493,4 +493,7 @@ unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru,
 
 bool drm_gem_object_evict(struct drm_gem_object *obj);
 
+int drm_gem_pin_unlocked(struct drm_gem_object *obj);
+void drm_gem_unpin_unlocked(struct drm_gem_object *obj);
+
 #endif /* __DRM_GEM_H__ */
-- 
2.38.1



[PATCH v10 08/11] drm/shmem-helper: Add memory shrinker

2023-01-08 Thread Dmitry Osipenko
Introduce common drm-shmem shrinker for DRM drivers.

To start using drm-shmem shrinker drivers should do the following:

1. Implement evict() callback of GEM object where driver should check
   whether object is purgeable or evictable using drm-shmem helpers and
   perform the shrinking action

2. Initialize drm-shmem internals using drmm_gem_shmem_init(drm_device),
   which will register drm-shmem shrinker

3. Implement madvise IOCTL that will use drm_gem_shmem_madvise()

Signed-off-by: Daniel Almeida 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c| 460 --
 .../gpu/drm/panfrost/panfrost_gem_shrinker.c  |   9 +-
 include/drm/drm_device.h  |  10 +-
 include/drm/drm_gem_shmem_helper.h|  61 ++-
 4 files changed, 490 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index a1f2f2158c50..3ab5ec325ddb 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -128,6 +129,57 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct 
drm_device *dev, size_t
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
 
+static void drm_gem_shmem_resv_assert_held(struct drm_gem_shmem_object *shmem)
+{
+   /*
+* Destroying the object is a special case.. drm_gem_shmem_free()
+* calls many things that WARN_ON if the obj lock is not held.  But
+* acquiring the obj lock in drm_gem_shmem_free() can cause a locking
+* order inversion between reservation_ww_class_mutex and fs_reclaim.
+*
+* This deadlock is not actually possible, because no one should
+* be already holding the lock when msm_gem_free_object() is called.
+* Unfortunately lockdep is not aware of this detail.  So when the
+* refcount drops to zero, we pretend it is already locked.
+*/
+   if (kref_read(>base.refcount))
+   dma_resv_assert_held(shmem->base.resv);
+}
+
+static bool drm_gem_shmem_is_evictable(struct drm_gem_shmem_object *shmem)
+{
+   dma_resv_assert_held(shmem->base.resv);
+
+   return (shmem->madv >= 0) && shmem->base.funcs->evict &&
+   shmem->pages_use_count && !shmem->pages_pin_count &&
+   !shmem->base.dma_buf && !shmem->base.import_attach &&
+   shmem->sgt && !shmem->evicted;
+}
+
+static void
+drm_gem_shmem_update_pages_state(struct drm_gem_shmem_object *shmem)
+{
+   struct drm_gem_object *obj = >base;
+   struct drm_gem_shmem *shmem_mm = obj->dev->shmem_mm;
+   struct drm_gem_shmem_shrinker *gem_shrinker = _mm->shrinker;
+
+   drm_gem_shmem_resv_assert_held(shmem);
+
+   if (!gem_shrinker || obj->import_attach)
+   return;
+
+   if (shmem->madv < 0)
+   drm_gem_lru_remove(>base);
+   else if (drm_gem_shmem_is_evictable(shmem) || 
drm_gem_shmem_is_purgeable(shmem))
+   drm_gem_lru_move_tail(_shrinker->lru_evictable, 
>base);
+   else if (shmem->evicted)
+   drm_gem_lru_move_tail(_shrinker->lru_evicted, >base);
+   else if (!shmem->pages)
+   drm_gem_lru_remove(>base);
+   else
+   drm_gem_lru_move_tail(_shrinker->lru_pinned, >base);
+}
+
 /**
  * drm_gem_shmem_free - Free resources associated with a shmem GEM object
  * @shmem: shmem GEM object to free
@@ -142,7 +194,8 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
if (obj->import_attach) {
drm_prime_gem_destroy(obj, shmem->sgt);
} else {
-   dma_resv_lock(shmem->base.resv, NULL);
+   /* take out shmem GEM object from the memory shrinker */
+   drm_gem_shmem_madvise(shmem, -1);
 
drm_WARN_ON(obj->dev, shmem->vmap_use_count);
 
@@ -152,12 +205,10 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object 
*shmem)
sg_free_table(shmem->sgt);
kfree(shmem->sgt);
}
-   if (shmem->pages)
+   if (shmem->pages_use_count)
drm_gem_shmem_put_pages(shmem);
 
drm_WARN_ON(obj->dev, shmem->pages_use_count);
-
-   dma_resv_unlock(shmem->base.resv);
}
 
drm_gem_object_release(obj);
@@ -165,19 +216,31 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object 
*shmem)
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_free);
 
-static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
+static int
+drm_gem_shmem_acquire_pages(struct drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = >base;
struct page **pages;
 
-   if (shmem->pages_use_count++ > 0)
+   dma_resv_assert_held(shmem->base.resv);
+
+   if (shmem->madv < 0) {
+   drm_WARN_ON(obj->dev, shmem->pages);
+   return -ENOMEM;
+   

[PATCH v10 07/11] drm/shmem-helper: Switch to reservation lock

2023-01-08 Thread Dmitry Osipenko
Replace all drm-shmem locks with a GEM reservation lock. This makes locks
consistent with dma-buf locking convention where importers are responsible
for holding reservation lock for all operations performed over dma-bufs,
preventing deadlock between dma-buf importers and exporters.

Suggested-by: Daniel Vetter 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c| 185 +++---
 drivers/gpu/drm/lima/lima_gem.c   |   8 +-
 drivers/gpu/drm/panfrost/panfrost_drv.c   |   7 +-
 .../gpu/drm/panfrost/panfrost_gem_shrinker.c  |   6 +-
 drivers/gpu/drm/panfrost/panfrost_mmu.c   |  19 +-
 include/drm/drm_gem_shmem_helper.h|  14 +-
 6 files changed, 94 insertions(+), 145 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 1392cbd3cc02..a1f2f2158c50 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -88,8 +88,6 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, 
bool private)
if (ret)
goto err_release;
 
-   mutex_init(>pages_lock);
-   mutex_init(>vmap_lock);
INIT_LIST_HEAD(>madv_list);
 
if (!private) {
@@ -141,11 +139,13 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object 
*shmem)
 {
struct drm_gem_object *obj = >base;
 
-   drm_WARN_ON(obj->dev, shmem->vmap_use_count);
-
if (obj->import_attach) {
drm_prime_gem_destroy(obj, shmem->sgt);
} else {
+   dma_resv_lock(shmem->base.resv, NULL);
+
+   drm_WARN_ON(obj->dev, shmem->vmap_use_count);
+
if (shmem->sgt) {
dma_unmap_sgtable(obj->dev->dev, shmem->sgt,
  DMA_BIDIRECTIONAL, 0);
@@ -154,18 +154,18 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object 
*shmem)
}
if (shmem->pages)
drm_gem_shmem_put_pages(shmem);
-   }
 
-   drm_WARN_ON(obj->dev, shmem->pages_use_count);
+   drm_WARN_ON(obj->dev, shmem->pages_use_count);
+
+   dma_resv_unlock(shmem->base.resv);
+   }
 
drm_gem_object_release(obj);
-   mutex_destroy(>pages_lock);
-   mutex_destroy(>vmap_lock);
kfree(shmem);
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_free);
 
-static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem)
+static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = >base;
struct page **pages;
@@ -197,35 +197,16 @@ static int drm_gem_shmem_get_pages_locked(struct 
drm_gem_shmem_object *shmem)
 }
 
 /*
- * drm_gem_shmem_get_pages - Allocate backing pages for a shmem GEM object
+ * drm_gem_shmem_put_pages - Decrease use count on the backing pages for a 
shmem GEM object
  * @shmem: shmem GEM object
  *
- * This function makes sure that backing pages exists for the shmem GEM object
- * and increases the use count.
- *
- * Returns:
- * 0 on success or a negative error code on failure.
+ * This function decreases the use count and puts the backing pages when use 
drops to zero.
  */
-int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
+void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = >base;
-   int ret;
 
-   drm_WARN_ON(obj->dev, obj->import_attach);
-
-   ret = mutex_lock_interruptible(>pages_lock);
-   if (ret)
-   return ret;
-   ret = drm_gem_shmem_get_pages_locked(shmem);
-   mutex_unlock(>pages_lock);
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_gem_shmem_get_pages);
-
-static void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem)
-{
-   struct drm_gem_object *obj = >base;
+   dma_resv_assert_held(shmem->base.resv);
 
if (drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count))
return;
@@ -243,19 +224,6 @@ static void drm_gem_shmem_put_pages_locked(struct 
drm_gem_shmem_object *shmem)
  shmem->pages_mark_accessed_on_put);
shmem->pages = NULL;
 }
-
-/*
- * drm_gem_shmem_put_pages - Decrease use count on the backing pages for a 
shmem GEM object
- * @shmem: shmem GEM object
- *
- * This function decreases the use count and puts the backing pages when use 
drops to zero.
- */
-void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem)
-{
-   mutex_lock(>pages_lock);
-   drm_gem_shmem_put_pages_locked(shmem);
-   mutex_unlock(>pages_lock);
-}
 EXPORT_SYMBOL(drm_gem_shmem_put_pages);
 
 /**
@@ -272,6 +240,8 @@ int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = >base;
 
+   dma_resv_assert_held(shmem->base.resv);
+
drm_WARN_ON(obj->dev, obj->import_attach);
 
return drm_gem_shmem_get_pages(shmem);
@@ -289,14 +259,31 @@ void drm_gem_shmem_unpin(struct 

[PATCH v10 06/11] drm/shmem-helper: Don't use vmap_use_count for dma-bufs

2023-01-08 Thread Dmitry Osipenko
DMA-buf core has its own refcounting of vmaps, use it instead of drm-shmem
counting. This change prepares drm-shmem for addition of memory shrinker
support where drm-shmem will use a single dma-buf reservation lock for
all operations performed over dma-bufs.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 35 +++---
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 5006f7da7f2d..1392cbd3cc02 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -301,24 +301,22 @@ static int drm_gem_shmem_vmap_locked(struct 
drm_gem_shmem_object *shmem,
struct drm_gem_object *obj = >base;
int ret = 0;
 
-   if (shmem->vmap_use_count++ > 0) {
-   iosys_map_set_vaddr(map, shmem->vaddr);
-   return 0;
-   }
-
if (obj->import_attach) {
ret = dma_buf_vmap(obj->import_attach->dmabuf, map);
if (!ret) {
if (drm_WARN_ON(obj->dev, map->is_iomem)) {
dma_buf_vunmap(obj->import_attach->dmabuf, map);
-   ret = -EIO;
-   goto err_put_pages;
+   return -EIO;
}
-   shmem->vaddr = map->vaddr;
}
} else {
pgprot_t prot = PAGE_KERNEL;
 
+   if (shmem->vmap_use_count++ > 0) {
+   iosys_map_set_vaddr(map, shmem->vaddr);
+   return 0;
+   }
+
ret = drm_gem_shmem_get_pages(shmem);
if (ret)
goto err_zero_use;
@@ -384,15 +382,15 @@ static void drm_gem_shmem_vunmap_locked(struct 
drm_gem_shmem_object *shmem,
 {
struct drm_gem_object *obj = >base;
 
-   if (drm_WARN_ON_ONCE(obj->dev, !shmem->vmap_use_count))
-   return;
-
-   if (--shmem->vmap_use_count > 0)
-   return;
-
if (obj->import_attach) {
dma_buf_vunmap(obj->import_attach->dmabuf, map);
} else {
+   if (drm_WARN_ON_ONCE(obj->dev, !shmem->vmap_use_count))
+   return;
+
+   if (--shmem->vmap_use_count > 0)
+   return;
+
vunmap(shmem->vaddr);
drm_gem_shmem_put_pages(shmem);
}
@@ -660,7 +658,14 @@ void drm_gem_shmem_print_info(const struct 
drm_gem_shmem_object *shmem,
  struct drm_printer *p, unsigned int indent)
 {
drm_printf_indent(p, indent, "pages_use_count=%u\n", 
shmem->pages_use_count);
-   drm_printf_indent(p, indent, "vmap_use_count=%u\n", 
shmem->vmap_use_count);
+
+   if (shmem->base.import_attach)
+   drm_printf_indent(p, indent, "vmap_use_count=%u\n",
+ shmem->base.dma_buf->vmapping_counter);
+   else
+   drm_printf_indent(p, indent, "vmap_use_count=%u\n",
+ shmem->vmap_use_count);
+
drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr);
 }
 EXPORT_SYMBOL(drm_gem_shmem_print_info);
-- 
2.38.1



[PATCH v10 05/11] drm/shmem: Switch to use drm_* debug helpers

2023-01-08 Thread Dmitry Osipenko
Ease debugging of a multi-GPU system by using drm_WARN_*() and
drm_dbg_kms() helpers that print out DRM device name corresponding
to shmem GEM.

Suggested-by: Thomas Zimmermann 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 38 +++---
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index f21f47737817..5006f7da7f2d 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -141,7 +141,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = >base;
 
-   WARN_ON(shmem->vmap_use_count);
+   drm_WARN_ON(obj->dev, shmem->vmap_use_count);
 
if (obj->import_attach) {
drm_prime_gem_destroy(obj, shmem->sgt);
@@ -156,7 +156,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
drm_gem_shmem_put_pages(shmem);
}
 
-   WARN_ON(shmem->pages_use_count);
+   drm_WARN_ON(obj->dev, shmem->pages_use_count);
 
drm_gem_object_release(obj);
mutex_destroy(>pages_lock);
@@ -175,7 +175,8 @@ static int drm_gem_shmem_get_pages_locked(struct 
drm_gem_shmem_object *shmem)
 
pages = drm_gem_get_pages(obj);
if (IS_ERR(pages)) {
-   DRM_DEBUG_KMS("Failed to get pages (%ld)\n", PTR_ERR(pages));
+   drm_dbg_kms(obj->dev, "Failed to get pages (%ld)\n",
+   PTR_ERR(pages));
shmem->pages_use_count = 0;
return PTR_ERR(pages);
}
@@ -207,9 +208,10 @@ static int drm_gem_shmem_get_pages_locked(struct 
drm_gem_shmem_object *shmem)
  */
 int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
 {
+   struct drm_gem_object *obj = >base;
int ret;
 
-   WARN_ON(shmem->base.import_attach);
+   drm_WARN_ON(obj->dev, obj->import_attach);
 
ret = mutex_lock_interruptible(>pages_lock);
if (ret)
@@ -225,7 +227,7 @@ static void drm_gem_shmem_put_pages_locked(struct 
drm_gem_shmem_object *shmem)
 {
struct drm_gem_object *obj = >base;
 
-   if (WARN_ON_ONCE(!shmem->pages_use_count))
+   if (drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count))
return;
 
if (--shmem->pages_use_count > 0)
@@ -268,7 +270,9 @@ EXPORT_SYMBOL(drm_gem_shmem_put_pages);
  */
 int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
 {
-   WARN_ON(shmem->base.import_attach);
+   struct drm_gem_object *obj = >base;
+
+   drm_WARN_ON(obj->dev, obj->import_attach);
 
return drm_gem_shmem_get_pages(shmem);
 }
@@ -283,7 +287,9 @@ EXPORT_SYMBOL(drm_gem_shmem_pin);
  */
 void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem)
 {
-   WARN_ON(shmem->base.import_attach);
+   struct drm_gem_object *obj = >base;
+
+   drm_WARN_ON(obj->dev, obj->import_attach);
 
drm_gem_shmem_put_pages(shmem);
 }
@@ -303,7 +309,7 @@ static int drm_gem_shmem_vmap_locked(struct 
drm_gem_shmem_object *shmem,
if (obj->import_attach) {
ret = dma_buf_vmap(obj->import_attach->dmabuf, map);
if (!ret) {
-   if (WARN_ON(map->is_iomem)) {
+   if (drm_WARN_ON(obj->dev, map->is_iomem)) {
dma_buf_vunmap(obj->import_attach->dmabuf, map);
ret = -EIO;
goto err_put_pages;
@@ -328,7 +334,7 @@ static int drm_gem_shmem_vmap_locked(struct 
drm_gem_shmem_object *shmem,
}
 
if (ret) {
-   DRM_DEBUG_KMS("Failed to vmap pages, error %d\n", ret);
+   drm_dbg_kms(obj->dev, "Failed to vmap pages, error %d\n", ret);
goto err_put_pages;
}
 
@@ -378,7 +384,7 @@ static void drm_gem_shmem_vunmap_locked(struct 
drm_gem_shmem_object *shmem,
 {
struct drm_gem_object *obj = >base;
 
-   if (WARN_ON_ONCE(!shmem->vmap_use_count))
+   if (drm_WARN_ON_ONCE(obj->dev, !shmem->vmap_use_count))
return;
 
if (--shmem->vmap_use_count > 0)
@@ -463,7 +469,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object 
*shmem)
struct drm_gem_object *obj = >base;
struct drm_device *dev = obj->dev;
 
-   WARN_ON(!drm_gem_shmem_is_purgeable(shmem));
+   drm_WARN_ON(obj->dev, !drm_gem_shmem_is_purgeable(shmem));
 
dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
sg_free_table(shmem->sgt);
@@ -555,7 +561,7 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
mutex_lock(>pages_lock);
 
if (page_offset >= num_pages ||
-   WARN_ON_ONCE(!shmem->pages) ||
+   drm_WARN_ON_ONCE(obj->dev, !shmem->pages) ||
shmem->madv < 0) {
ret = VM_FAULT_SIGBUS;
} else {
@@ -574,7 +580,7 @@ static void 

[PATCH v10 04/11] drm/shmem: Put booleans in the end of struct drm_gem_shmem_object

2023-01-08 Thread Dmitry Osipenko
Group all 1-bit boolean members of struct drm_gem_shmem_object in the end
of the structure, allowing compiler to pack data better and making code to
look more consistent.

Suggested-by: Thomas Zimmermann 
Signed-off-by: Dmitry Osipenko 
---
 include/drm/drm_gem_shmem_helper.h | 30 +++---
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index a2201b2488c5..5994fed5e327 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -60,20 +60,6 @@ struct drm_gem_shmem_object {
 */
struct list_head madv_list;
 
-   /**
-* @pages_mark_dirty_on_put:
-*
-* Mark pages as dirty when they are put.
-*/
-   unsigned int pages_mark_dirty_on_put: 1;
-
-   /**
-* @pages_mark_accessed_on_put:
-*
-* Mark pages as accessed when they are put.
-*/
-   unsigned int pages_mark_accessed_on_put : 1;
-
/**
 * @sgt: Scatter/gather table for imported PRIME buffers
 */
@@ -97,10 +83,24 @@ struct drm_gem_shmem_object {
 */
unsigned int vmap_use_count;
 
+   /**
+* @pages_mark_dirty_on_put:
+*
+* Mark pages as dirty when they are put.
+*/
+   bool pages_mark_dirty_on_put : 1;
+
+   /**
+* @pages_mark_accessed_on_put:
+*
+* Mark pages as accessed when they are put.
+*/
+   bool pages_mark_accessed_on_put : 1;
+
/**
 * @map_wc: map object write-combined (instead of using shmem defaults).
 */
-   bool map_wc;
+   bool map_wc : 1;
 };
 
 #define to_drm_gem_shmem_obj(obj) \
-- 
2.38.1



[PATCH v10 03/11] drm/gem: Add evict() callback to drm_gem_object_funcs

2023-01-08 Thread Dmitry Osipenko
Add new common evict() callback to drm_gem_object_funcs and corresponding
drm_gem_object_evict() helper. This is a first step on a way to providing
common GEM-shrinker API for DRM drivers.

Suggested-by: Thomas Zimmermann 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem.c | 16 
 include/drm/drm_gem.h | 12 
 2 files changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index c6bca5ac6e0f..dbb48fc9dff3 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1471,3 +1471,19 @@ drm_gem_lru_scan(struct drm_gem_lru *lru,
return freed;
 }
 EXPORT_SYMBOL(drm_gem_lru_scan);
+
+/**
+ * drm_gem_object_evict - helper to evict backing pages for a GEM object
+ * @obj: obj in question
+ */
+bool
+drm_gem_object_evict(struct drm_gem_object *obj)
+{
+   dma_resv_assert_held(obj->resv);
+
+   if (obj->funcs->evict)
+   return obj->funcs->evict(obj);
+
+   return false;
+}
+EXPORT_SYMBOL(drm_gem_object_evict);
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index f1f00fc2dba6..8e5c22f25691 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -172,6 +172,16 @@ struct drm_gem_object_funcs {
 * This is optional but necessary for mmap support.
 */
const struct vm_operations_struct *vm_ops;
+
+   /**
+* @evict:
+*
+* Evicts gem object out from memory. Used by the drm_gem_object_evict()
+* helper. Returns true on success, false otherwise.
+*
+* This callback is optional.
+*/
+   bool (*evict)(struct drm_gem_object *obj);
 };
 
 /**
@@ -481,4 +491,6 @@ unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru,
   unsigned long *remaining,
   bool (*shrink)(struct drm_gem_object *obj));
 
+bool drm_gem_object_evict(struct drm_gem_object *obj);
+
 #endif /* __DRM_GEM_H__ */
-- 
2.38.1



[PATCH v10 02/11] drm/panfrost: Don't sync rpm suspension after mmu flushing

2023-01-08 Thread Dmitry Osipenko
Lockdep warns about potential circular locking dependency of devfreq
with the fs_reclaim caused by immediate device suspension when mapping is
released by shrinker. Fix it by doing the suspension asynchronously.

Reviewed-by: Steven Price 
Fixes: ec7eba47da86 ("drm/panfrost: Rework page table flushing and runtime PM 
interaction ")
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/panfrost/panfrost_mmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index 4e83a1891f3e..666a5e53fe19 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -282,7 +282,7 @@ static void panfrost_mmu_flush_range(struct panfrost_device 
*pfdev,
if (pm_runtime_active(pfdev->dev))
mmu_hw_do_operation(pfdev, mmu, iova, size, 
AS_COMMAND_FLUSH_PT);
 
-   pm_runtime_put_sync_autosuspend(pfdev->dev);
+   pm_runtime_put_autosuspend(pfdev->dev);
 }
 
 static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu,
-- 
2.38.1



[PATCH v10 01/11] drm/msm/gem: Prevent blocking within shrinker loop

2023-01-08 Thread Dmitry Osipenko
Consider this scenario:

1. APP1 continuously creates lots of small GEMs
2. APP2 triggers `drop_caches`
3. Shrinker starts to evict APP1 GEMs, while APP1 produces new purgeable
   GEMs
4. msm_gem_shrinker_scan() returns non-zero number of freed pages
   and causes shrinker to try shrink more
5. msm_gem_shrinker_scan() returns non-zero number of freed pages again,
   goto 4
6. The APP2 is blocked in `drop_caches` until APP1 stops producing
   purgeable GEMs

To prevent this blocking scenario, check number of remaining pages
that GPU shrinker couldn't release due to a GEM locking contention
or shrinking rejection. If there are no remaining pages left to shrink,
then there is no need to free up more pages and shrinker may break out
from the loop.

This problem was found during shrinker/madvise IOCTL testing of
virtio-gpu driver. The MSM driver is affected in the same way.

Reviewed-by: Rob Clark 
Fixes: b352ba54a820 ("drm/msm/gem: Convert to using drm_gem_lru")
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem.c  | 9 +++--
 drivers/gpu/drm/msm/msm_gem_shrinker.c | 8 ++--
 include/drm/drm_gem.h  | 4 +++-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 59a0bb5ebd85..c6bca5ac6e0f 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1388,10 +1388,13 @@ EXPORT_SYMBOL(drm_gem_lru_move_tail);
  *
  * @lru: The LRU to scan
  * @nr_to_scan: The number of pages to try to reclaim
+ * @remaining: The number of pages left to reclaim
  * @shrink: Callback to try to shrink/reclaim the object.
  */
 unsigned long
-drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan,
+drm_gem_lru_scan(struct drm_gem_lru *lru,
+unsigned int nr_to_scan,
+unsigned long *remaining,
 bool (*shrink)(struct drm_gem_object *obj))
 {
struct drm_gem_lru still_in_lru;
@@ -1430,8 +1433,10 @@ drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned 
nr_to_scan,
 * hit shrinker in response to trying to get backing pages
 * for this obj (ie. while it's lock is already held)
 */
-   if (!dma_resv_trylock(obj->resv))
+   if (!dma_resv_trylock(obj->resv)) {
+   *remaining += obj->size >> PAGE_SHIFT;
goto tail;
+   }
 
if (shrink(obj)) {
freed += obj->size >> PAGE_SHIFT;
diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c 
b/drivers/gpu/drm/msm/msm_gem_shrinker.c
index 051bdbc093cf..b7c1242014ec 100644
--- a/drivers/gpu/drm/msm/msm_gem_shrinker.c
+++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c
@@ -116,12 +116,14 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct 
shrink_control *sc)
};
long nr = sc->nr_to_scan;
unsigned long freed = 0;
+   unsigned long remaining = 0;
 
for (unsigned i = 0; (nr > 0) && (i < ARRAY_SIZE(stages)); i++) {
if (!stages[i].cond)
continue;
stages[i].freed =
-   drm_gem_lru_scan(stages[i].lru, nr, stages[i].shrink);
+   drm_gem_lru_scan(stages[i].lru, nr, ,
+stages[i].shrink);
nr -= stages[i].freed;
freed += stages[i].freed;
}
@@ -132,7 +134,7 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct 
shrink_control *sc)
 stages[3].freed);
}
 
-   return (freed > 0) ? freed : SHRINK_STOP;
+   return (freed > 0 && remaining > 0) ? freed : SHRINK_STOP;
 }
 
 #ifdef CONFIG_DEBUG_FS
@@ -182,10 +184,12 @@ msm_gem_shrinker_vmap(struct notifier_block *nb, unsigned 
long event, void *ptr)
NULL,
};
unsigned idx, unmapped = 0;
+   unsigned long remaining = 0;
 
for (idx = 0; lrus[idx] && unmapped < vmap_shrink_limit; idx++) {
unmapped += drm_gem_lru_scan(lrus[idx],
 vmap_shrink_limit - unmapped,
+,
 vmap_shrink);
}
 
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 772a4adf5287..f1f00fc2dba6 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -476,7 +476,9 @@ int drm_gem_dumb_map_offset(struct drm_file *file, struct 
drm_device *dev,
 void drm_gem_lru_init(struct drm_gem_lru *lru, struct mutex *lock);
 void drm_gem_lru_remove(struct drm_gem_object *obj);
 void drm_gem_lru_move_tail(struct drm_gem_lru *lru, struct drm_gem_object 
*obj);
-unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan,
+unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru,
+  unsigned int nr_to_scan,
+  unsigned long *remaining,
  

[PATCH v10 00/11] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers

2023-01-08 Thread Dmitry Osipenko
This series:

  1. Makes minor fixes for drm_gem_lru and Panfrost
  2. Brings refactoring for older code
  3. Adds common drm-shmem memory shrinker
  4. Enables shrinker for VirtIO-GPU driver
  5. Switches Panfrost driver to the common shrinker

Changelog:

v10:- Rebased on a recent linux-next.

- Added Rob's ack to MSM "Prevent blocking within shrinker loop" patch.

- Added Steven's ack/r-b/t-b for the Panfrost patches.

- Fixed missing export of the new drm_gem_object_evict() function.

- Added fixes tags to the first two patches that are making minor fixes,
  for consistency.

v9: - Replaced struct drm_gem_shmem_shrinker with drm_gem_shmem and
  moved it to drm_device, like was suggested by Thomas Zimmermann.

- Replaced drm_gem_shmem_shrinker_register() with drmm_gem_shmem_init(),
  like was suggested by Thomas Zimmermann.

- Moved evict() callback to drm_gem_object_funcs and added common
  drm_gem_object_evict() helper, like was suggested by Thomas Zimmermann.

- The shmem object now is evictable by default, like was suggested by
  Thomas Zimmermann. Dropped the set_evictable/purgeble() functions
  as well, drivers will decide whether BO is evictable within theirs
  madvise IOCTL.

- Added patches that convert drm-shmem code to use drm_WARN_ON() and
  drm_dbg_kms(), like was requested by Thomas Zimmermann.

- Turned drm_gem_shmem_object booleans into 1-bit bit fields, like was
  suggested by Thomas Zimmermann.

- Switched to use drm_dev->unique for the shmem shrinker name. Drivers
  don't need to specify the name explicitly anymore.

- Re-added dma_resv_test_signaled() that was missing in v8 and also
  fixed its argument to DMA_RESV_USAGE_READ. See comment to
  dma_resv_usage_rw().

- Added new fix for Panfrost driver that silences lockdep warning
  caused by shrinker. Both Panfrost old and new shmem shrinkers are
  affected.

v8: - Rebased on top of recent linux-next that now has dma-buf locking
  convention patches merged, which was blocking shmem shrinker before.

- Shmem shrinker now uses new drm_gem_lru helper.

- Dropped Steven Price t-b from the Panfrost patch because code
  changed significantly since v6 and should be re-tested.

v7: - dma-buf locking convention

v6: 
https://lore.kernel.org/dri-devel/20220526235040.678984-1-dmitry.osipe...@collabora.com/

Related patches:

Mesa: https://gitlab.freedesktop.org/digetx/mesa/-/commits/virgl-madvise
igt:  
https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/virtio-madvise
  
https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/panfrost-madvise

The Mesa and IGT patches will be sent out once the kernel part will land.

Dmitry Osipenko (11):
  drm/msm/gem: Prevent blocking within shrinker loop
  drm/panfrost: Don't sync rpm suspension after mmu flushing
  drm/gem: Add evict() callback to drm_gem_object_funcs
  drm/shmem: Put booleans in the end of struct drm_gem_shmem_object
  drm/shmem: Switch to use drm_* debug helpers
  drm/shmem-helper: Don't use vmap_use_count for dma-bufs
  drm/shmem-helper: Switch to reservation lock
  drm/shmem-helper: Add memory shrinker
  drm/gem: Add drm_gem_pin_unlocked()
  drm/virtio: Support memory shrinking
  drm/panfrost: Switch to generic memory shrinker

 drivers/gpu/drm/drm_gem.c |  54 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c| 646 +-
 drivers/gpu/drm/lima/lima_gem.c   |   8 +-
 drivers/gpu/drm/msm/msm_gem_shrinker.c|   8 +-
 drivers/gpu/drm/panfrost/Makefile |   1 -
 drivers/gpu/drm/panfrost/panfrost_device.h|   4 -
 drivers/gpu/drm/panfrost/panfrost_drv.c   |  34 +-
 drivers/gpu/drm/panfrost/panfrost_gem.c   |  30 +-
 drivers/gpu/drm/panfrost/panfrost_gem.h   |   9 -
 .../gpu/drm/panfrost/panfrost_gem_shrinker.c  | 122 
 drivers/gpu/drm/panfrost/panfrost_job.c   |  18 +-
 drivers/gpu/drm/panfrost/panfrost_mmu.c   |  21 +-
 drivers/gpu/drm/virtio/virtgpu_drv.h  |  18 +-
 drivers/gpu/drm/virtio/virtgpu_gem.c  |  52 ++
 drivers/gpu/drm/virtio/virtgpu_ioctl.c|  37 +
 drivers/gpu/drm/virtio/virtgpu_kms.c  |   8 +
 drivers/gpu/drm/virtio/virtgpu_object.c   | 132 +++-
 drivers/gpu/drm/virtio/virtgpu_plane.c|  22 +-
 drivers/gpu/drm/virtio/virtgpu_vq.c   |  40 ++
 include/drm/drm_device.h  |  10 +-
 include/drm/drm_gem.h |  19 +-
 include/drm/drm_gem_shmem_helper.h| 112 +--
 include/uapi/drm/virtgpu_drm.h|  14 +
 23 files changed, 1010 insertions(+), 409 deletions(-)
 delete mode 100644 drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c

-- 
2.38.1



Re: [PATCH 15/15] backlight: backlight: Drop the deprecated fb_blank property

2023-01-08 Thread Stephen Kitt
On Sat, 07 Jan 2023 19:26:29 +0100, Sam Ravnborg via B4 Submission Endpoint
 wrote:

> From: Sam Ravnborg 
> 
> With all users gone remove the deprecated fb_blank member in
> backlight_properties.
> 
> Signed-off-by: Sam Ravnborg 
> Cc: Lee Jones 
> Cc: Daniel Thompson 
> Cc: Jingoo Han 
> ---
>  drivers/video/backlight/backlight.c |  2 --
>  include/linux/backlight.h   | 22 --
>  2 files changed, 24 deletions(-)
> 
> diff --git a/drivers/video/backlight/backlight.c
> b/drivers/video/backlight/backlight.c index b788ff3d0f45..9b0557d094c5
> 100644 --- a/drivers/video/backlight/backlight.c
> +++ b/drivers/video/backlight/backlight.c
> @@ -118,14 +118,12 @@ static int fb_notifier_callback(struct notifier_block
> *self, bd->fb_bl_on[node] = true;
>   if (!bd->use_count++) {
>   bd->props.state &= ~BL_CORE_FBBLANK;
> - bd->props.fb_blank = FB_BLANK_UNBLANK;
>   backlight_update_status(bd);
>   }
>   } else if (fb_blank != FB_BLANK_UNBLANK && bd->fb_bl_on[node]) {
>   bd->fb_bl_on[node] = false;
>   if (!(--bd->use_count)) {
>   bd->props.state |= BL_CORE_FBBLANK;
> - bd->props.fb_blank = fb_blank;
>   backlight_update_status(bd);
>   }
>   }
> diff --git a/include/linux/backlight.h b/include/linux/backlight.h
> index 614653e07e3a..c8622d6cc8c5 100644
> --- a/include/linux/backlight.h
> +++ b/include/linux/backlight.h
> @@ -218,25 +218,6 @@ struct backlight_properties {
>*/
>   int power;
>  
> - /**
> -  * @fb_blank: The power state from the FBIOBLANK ioctl.
> -  *
> -  * When the FBIOBLANK ioctl is called @fb_blank is set to the
> -  * blank parameter and the update_status() operation is called.
> -  *
> -  * When the backlight device is enabled @fb_blank is set
> -  * to FB_BLANK_UNBLANK. When the backlight device is disabled
> -  * @fb_blank is set to FB_BLANK_POWERDOWN.
> -  *
> -  * Backlight drivers should avoid using this property. It has been
> -  * replaced by state & BL_CORE_FBLANK (although most drivers should
> -  * use backlight_is_blank() as the preferred means to get the blank
> -  * state).
> -  *
> -  * fb_blank is deprecated and will be removed.
> -  */
> - int fb_blank;
> -
>   /**
>* @type: The type of backlight supported.
>*
> @@ -366,7 +347,6 @@ static inline int backlight_enable(struct
> backlight_device *bd) return 0;
>  
>   bd->props.power = FB_BLANK_UNBLANK;
> - bd->props.fb_blank = FB_BLANK_UNBLANK;
>   bd->props.state &= ~BL_CORE_FBBLANK;
>  
>   return backlight_update_status(bd);
> @@ -382,7 +362,6 @@ static inline int backlight_disable(struct
> backlight_device *bd) return 0;
>  
>   bd->props.power = FB_BLANK_POWERDOWN;
> - bd->props.fb_blank = FB_BLANK_POWERDOWN;
>   bd->props.state |= BL_CORE_FBBLANK;
>  
>   return backlight_update_status(bd);
> @@ -403,7 +382,6 @@ static inline int backlight_disable(struct
> backlight_device *bd) static inline bool backlight_is_blank(const struct
> backlight_device *bd) {
>   return bd->props.power != FB_BLANK_UNBLANK ||
> -bd->props.fb_blank != FB_BLANK_UNBLANK ||
>  bd->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK);
>  }
>  
> 
> -- 
> 2.34.1

Reviewed-by: Stephen Kitt 


pgpl8q7sIZKqi.pgp
Description: OpenPGP digital signature


Re: [PATCH v4 04/11] drm/msm/dpu: Add support for SM8350

2023-01-08 Thread Dmitry Baryshkov

On 30/12/2022 17:35, Robert Foss wrote:

Add compatibles string, "qcom,sm8350-dpu", for the display processing unit
used on Qualcomm SM8350 platform.

Signed-off-by: Robert Foss 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 1 +
  1 file changed, 1 insertion(+)


Reviewed-by: Dmitry Baryshkov 

--
With best wishes
Dmitry



Re: [PATCH 09/15] staging: fbtft: fb_ssd1351.c: Introduce backlight_is_blank()

2023-01-08 Thread Sam Ravnborg
Hi Stephen,

On Sun, Jan 08, 2023 at 08:28:17PM +0100, Stephen Kitt wrote:
> On Sat, 07 Jan 2023 19:26:23 +0100, Sam Ravnborg via B4 Submission Endpoint
>  wrote:
> 
> > From: Sam Ravnborg 
> > 
> > Avoiding direct access to backlight_properties.props.
> > 
> > Access to the deprecated props.fb_blank replaced by backlight_is_blank().
> > Access to props.power is dropped - it was only used for debug.
> > 
> > Signed-off-by: Sam Ravnborg 
> > Cc: Stephen Kitt 
> > Cc: Greg Kroah-Hartman 
> > Cc: Daniel Thompson 
> > Cc: Andy Shevchenko 
> > Cc: linux-fb...@vger.kernel.org
> > ---
> >  drivers/staging/fbtft/fb_ssd1351.c | 9 +++--
> >  1 file changed, 3 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/staging/fbtft/fb_ssd1351.c
> > b/drivers/staging/fbtft/fb_ssd1351.c index b8d55aa8c5c7..995fbd2f3dc6 100644
> > --- a/drivers/staging/fbtft/fb_ssd1351.c
> > +++ b/drivers/staging/fbtft/fb_ssd1351.c
> > @@ -190,15 +190,12 @@ static struct fbtft_display display = {
> >  static int update_onboard_backlight(struct backlight_device *bd)
> >  {
> > struct fbtft_par *par = bl_get_data(bd);
> > -   bool on;
> > +   bool blank = backlight_is_blank(bd);
> >  
> > -   fbtft_par_dbg(DEBUG_BACKLIGHT, par,
> > - "%s: power=%d, fb_blank=%d\n",
> > - __func__, bd->props.power, bd->props.fb_blank);
> > +   fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s: blank=%d\n", __func__,
> > blank); 
> > -   on = !backlight_is_blank(bd);
> > /* Onboard backlight connected to GPIO0 on SSD1351, GPIO1 unused */
> > -   write_reg(par, 0xB5, on ? 0x03 : 0x02);
> > +   write_reg(par, 0xB5, !blank ? 0x03 : 0x02);
> >  
> > return 0;
> >  }
> > 
> > -- 
> > 2.34.1
> 
> For debugging purposes here, would there be any point in logging props.state?
> As in
> 
> fbtft_par_dbg(DEBUG_BACKLIGHT, par,
> - "%s: power=%d, fb_blank=%d\n",
> - __func__, bd->props.power, bd->props.fb_blank);
> + "%s: power=%d, state=%u\n",
> + __func__, bd->props.power, bd->props.state);

Thanks for the suggestion - and the reviews!

I was tempted to just remove the debugging.
If we require debugging, then this could be added in the backlight core,
thus everyone would benefit from it.

The solution above avoid any direct use of backlight_properties
which I consider a layer violation outside the backlight core.
(We cannot avoid it today with the current interface - but we can
minimize it).

Sam


Re: [PATCH 01/15] video: fbdev: atmel_lcdfb: Rework backlight handling

2023-01-08 Thread Sam Ravnborg
Hi Helge,

> > 
> > Helge - could you pick the reviewed patches from:
> > https://lore.kernel.org/all/20220607192335.1137249-1-st...@sk2.org/
> > [This is the same mail as Stephen refer to above - looked up via lore].
> 
> I just pulled those 7 patches into fbdev/for-next.
> If you need more, please let me know,

Thanks, we have one pending patch for atmel_lcdfb, but it need a small
adjustment before it is ready.

With this all fbdev drivers have the backlight_properties.fb_blank
removed.

Sam


Re: [PATCH 01/15] video: fbdev: atmel_lcdfb: Rework backlight handling

2023-01-08 Thread Sam Ravnborg
Hi Stephen.

 
> Here are my pending patches from last June on lore:
> 

All patches are handled I think except this:
> * https://lore.kernel.org/lkml/20220608205623.2106113-1-st...@sk2.org/

Can I ask you to drop the assignment that is not needed, and resend with
the collected acks/r-b.

With this, then all fbdev patches are handled.

Sam


Re: [PATCH 11/15] powerpc: via-pmu-backlight: Introduce backlight_get_brightness()

2023-01-08 Thread Stephen Kitt
On Sat, 07 Jan 2023 19:26:25 +0100, Sam Ravnborg via B4 Submission Endpoint
 wrote:

> From: Sam Ravnborg 
> 
> Introduce backlight_get_brightness() to simplify logic
> and avoid direct access to backlight properties.
> 
> Signed-off-by: Sam Ravnborg 
> Cc: Benjamin Herrenschmidt 
> Cc: Sam Ravnborg 
> Cc: linuxppc-...@lists.ozlabs.org
> ---
>  drivers/macintosh/via-pmu-backlight.c | 7 +--
>  1 file changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/drivers/macintosh/via-pmu-backlight.c
> b/drivers/macintosh/via-pmu-backlight.c index 2194016122d2..c2d87e7fa85b
> 100644 --- a/drivers/macintosh/via-pmu-backlight.c
> +++ b/drivers/macintosh/via-pmu-backlight.c
> @@ -71,12 +71,7 @@ static int pmu_backlight_get_level_brightness(int level)
>  static int __pmu_backlight_update_status(struct backlight_device *bd)
>  {
>   struct adb_request req;
> - int level = bd->props.brightness;
> -
> -
> - if (bd->props.power != FB_BLANK_UNBLANK ||
> - bd->props.fb_blank != FB_BLANK_UNBLANK)
> - level = 0;
> + int level = backlight_get_brightness(bd);
>  
>   if (level > 0) {
>   int pmulevel = pmu_backlight_get_level_brightness(level);
> 
> -- 
> 2.34.1

This one is already in 6.2-rc1, it went in via powerpc/next.

Regards,

Stephen


pgprywE4Y8KXL.pgp
Description: OpenPGP digital signature


Re: [PATCH 10/15] staging: fbtft: core: Introduce backlight_is_blank()

2023-01-08 Thread Stephen Kitt
On Sat, 07 Jan 2023 19:26:24 +0100, Sam Ravnborg via B4 Submission Endpoint
 wrote:

> From: Sam Ravnborg 
> 
> Avoiding direct access to backlight_properties.props.
> 
> Access to the deprecated props.fb_blank replaced by backlight_is_blank().
> Access to props.power is dropped - it was only used for debug.
> 
> Signed-off-by: Sam Ravnborg 
> Cc: Thomas Zimmermann 
> Cc: Andy Shevchenko 
> Cc: Javier Martinez Canillas 
> Cc: Greg Kroah-Hartman 
> Cc: Sam Ravnborg 
> Cc: Stephen Kitt 
> Cc: Peter Suti 
> Cc: linux-fb...@vger.kernel.org
> ---
>  drivers/staging/fbtft/fbtft-core.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/fbtft/fbtft-core.c
> b/drivers/staging/fbtft/fbtft-core.c index afaba94d1d1c..1746327e1939 100644
> --- a/drivers/staging/fbtft/fbtft-core.c
> +++ b/drivers/staging/fbtft/fbtft-core.c
> @@ -132,15 +132,15 @@ static int fbtft_backlight_update_status(struct
> backlight_device *bd) {
>   struct fbtft_par *par = bl_get_data(bd);
>   bool polarity = par->polarity;
> + bool blank = backlight_is_blank(bd);
>  
> - fbtft_par_dbg(DEBUG_BACKLIGHT, par,
> -   "%s: polarity=%d, power=%d, fb_blank=%d\n",
> -   __func__, polarity, bd->props.power,
> bd->props.fb_blank);
> + fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s: polarity=%d, blank=%d\n",
> +   __func__, polarity, blank);
>  
> - if (!backlight_is_blank(bd))
> - gpiod_set_value(par->gpio.led[0], polarity);
> - else
> + if (blank)
>   gpiod_set_value(par->gpio.led[0], !polarity);
> + else
> + gpiod_set_value(par->gpio.led[0], polarity);
>  
>   return 0;
>  }
> 
> -- 
> 2.34.1

Reviewed-by: Stephen Kitt 


pgpiJ7cx7VMKJ.pgp
Description: OpenPGP digital signature


Re: [PATCH 13/15] backlight: omap1: Use backlight helpers

2023-01-08 Thread Stephen Kitt
On Sat, 07 Jan 2023 19:26:27 +0100, Sam Ravnborg via B4 Submission Endpoint
 wrote:

> From: Sam Ravnborg 
> 
> Rework backlight handling to avoid access to the deprecated
> backlight_properties.fb_blank member.
> 
> The rework includes removal of get_brightness() operation,
> because there was no read back from HW so no use for it.
> 
> Signed-off-by: Sam Ravnborg 
> Cc: Lee Jones 
> Cc: Daniel Thompson 
> Cc: Jingoo Han 
> ---
>  drivers/video/backlight/omap1_bl.c | 67
> +- 1 file changed, 9 insertions(+), 58
> deletions(-)
> 
> diff --git a/drivers/video/backlight/omap1_bl.c
> b/drivers/video/backlight/omap1_bl.c index 69a49384b3de..49f37da857e7 100644
> --- a/drivers/video/backlight/omap1_bl.c
> +++ b/drivers/video/backlight/omap1_bl.c
> @@ -20,9 +20,6 @@
>  #define OMAPBL_MAX_INTENSITY 0xff
>  
>  struct omap_backlight {
> - int powermode;
> - int current_intensity;
> -
>   struct device *dev;
>   struct omap_backlight_config *pdata;
>  };
> @@ -37,82 +34,40 @@ static inline void omapbl_send_enable(int enable)
>   omap_writeb(enable, OMAP_PWL_CLK_ENABLE);
>  }
>  
> -static void omapbl_blank(struct omap_backlight *bl, int mode)
> -{
> - if (bl->pdata->set_power)
> - bl->pdata->set_power(bl->dev, mode);
> -
> - switch (mode) {
> - case FB_BLANK_NORMAL:
> - case FB_BLANK_VSYNC_SUSPEND:
> - case FB_BLANK_HSYNC_SUSPEND:
> - case FB_BLANK_POWERDOWN:
> - omapbl_send_intensity(0);
> - omapbl_send_enable(0);
> - break;
> -
> - case FB_BLANK_UNBLANK:
> - omapbl_send_intensity(bl->current_intensity);
> - omapbl_send_enable(1);
> - break;
> - }
> -}
> -
>  #ifdef CONFIG_PM_SLEEP
>  static int omapbl_suspend(struct device *dev)
>  {
>   struct backlight_device *bl_dev = dev_get_drvdata(dev);
> - struct omap_backlight *bl = bl_get_data(bl_dev);
>  
> - omapbl_blank(bl, FB_BLANK_POWERDOWN);
> + backlight_disable(bl_dev);
>   return 0;
>  }
>  
>  static int omapbl_resume(struct device *dev)
>  {
>   struct backlight_device *bl_dev = dev_get_drvdata(dev);
> - struct omap_backlight *bl = bl_get_data(bl_dev);
>  
> - omapbl_blank(bl, bl->powermode);
> + backlight_enable(bl_dev);
>   return 0;
>  }
>  #endif
>  
> -static int omapbl_set_power(struct backlight_device *dev, int state)
> -{
> - struct omap_backlight *bl = bl_get_data(dev);
> -
> - omapbl_blank(bl, state);
> - bl->powermode = state;
> -
> - return 0;
> -}
> -
>  static int omapbl_update_status(struct backlight_device *dev)
>  {
> - struct omap_backlight *bl = bl_get_data(dev);
> + int brightness = backlight_get_brightness(dev);
>  
> - if (bl->current_intensity != dev->props.brightness) {
> - if (bl->powermode == FB_BLANK_UNBLANK)
> - omapbl_send_intensity(dev->props.brightness);
> - bl->current_intensity = dev->props.brightness;
> + if (brightness > 0) {
> + omapbl_send_intensity(dev->props.brightness);
> + omapbl_send_enable(1);
> + } else {
> + omapbl_send_intensity(0);
> + omapbl_send_enable(0);
>   }
>  
> - if (dev->props.fb_blank != bl->powermode)
> - omapbl_set_power(dev, dev->props.fb_blank);
> -
>   return 0;
>  }
>  
> -static int omapbl_get_intensity(struct backlight_device *dev)
> -{
> - struct omap_backlight *bl = bl_get_data(dev);
> -
> - return bl->current_intensity;
> -}
> -
>  static const struct backlight_ops omapbl_ops = {
> - .get_brightness = omapbl_get_intensity,
>   .update_status  = omapbl_update_status,
>  };
>  
> @@ -139,9 +94,6 @@ static int omapbl_probe(struct platform_device *pdev)
>   if (IS_ERR(dev))
>   return PTR_ERR(dev);
>  
> - bl->powermode = FB_BLANK_POWERDOWN;
> - bl->current_intensity = 0;
> -
>   bl->pdata = pdata;
>   bl->dev = >dev;
>  
> @@ -149,7 +101,6 @@ static int omapbl_probe(struct platform_device *pdev)
>  
>   omap_cfg_reg(PWL);  /* Conflicts with UART3 */
>  
> - dev->props.fb_blank = FB_BLANK_UNBLANK;
>   dev->props.brightness = pdata->default_intensity;
>   omapbl_update_status(dev);
>  
> 
> -- 
> 2.34.1

Wow that gets rid of a lot of unnecessary code!

Reviewed-by: Stephen Kitt 


pgpoLis1h6Y9E.pgp
Description: OpenPGP digital signature


Re: [PATCH 09/15] staging: fbtft: fb_ssd1351.c: Introduce backlight_is_blank()

2023-01-08 Thread Stephen Kitt
On Sat, 07 Jan 2023 19:26:23 +0100, Sam Ravnborg via B4 Submission Endpoint
 wrote:

> From: Sam Ravnborg 
> 
> Avoiding direct access to backlight_properties.props.
> 
> Access to the deprecated props.fb_blank replaced by backlight_is_blank().
> Access to props.power is dropped - it was only used for debug.
> 
> Signed-off-by: Sam Ravnborg 
> Cc: Stephen Kitt 
> Cc: Greg Kroah-Hartman 
> Cc: Daniel Thompson 
> Cc: Andy Shevchenko 
> Cc: linux-fb...@vger.kernel.org
> ---
>  drivers/staging/fbtft/fb_ssd1351.c | 9 +++--
>  1 file changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/fbtft/fb_ssd1351.c
> b/drivers/staging/fbtft/fb_ssd1351.c index b8d55aa8c5c7..995fbd2f3dc6 100644
> --- a/drivers/staging/fbtft/fb_ssd1351.c
> +++ b/drivers/staging/fbtft/fb_ssd1351.c
> @@ -190,15 +190,12 @@ static struct fbtft_display display = {
>  static int update_onboard_backlight(struct backlight_device *bd)
>  {
>   struct fbtft_par *par = bl_get_data(bd);
> - bool on;
> + bool blank = backlight_is_blank(bd);
>  
> - fbtft_par_dbg(DEBUG_BACKLIGHT, par,
> -   "%s: power=%d, fb_blank=%d\n",
> -   __func__, bd->props.power, bd->props.fb_blank);
> + fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s: blank=%d\n", __func__,
> blank); 
> - on = !backlight_is_blank(bd);
>   /* Onboard backlight connected to GPIO0 on SSD1351, GPIO1 unused */
> - write_reg(par, 0xB5, on ? 0x03 : 0x02);
> + write_reg(par, 0xB5, !blank ? 0x03 : 0x02);
>  
>   return 0;
>  }
> 
> -- 
> 2.34.1

For debugging purposes here, would there be any point in logging props.state?
As in

fbtft_par_dbg(DEBUG_BACKLIGHT, par,
- "%s: power=%d, fb_blank=%d\n",
- __func__, bd->props.power, bd->props.fb_blank);
+ "%s: power=%d, state=%u\n",
+ __func__, bd->props.power, bd->props.state);

In any case,

Reviewed-by: Stephen Kitt 

Regards,

Stephen


pgp3gjGKcFw5v.pgp
Description: OpenPGP digital signature


Re: [PATCH v3 1/1] dt-bindings: msm: dsi-phy-28nm: Add missing qcom,dsi-phy-regulator-ldo-mode

2023-01-08 Thread Rob Herring


On Thu, 29 Dec 2022 12:44:38 +, Bryan O'Donoghue wrote:
> Add in missing qcom,dsi-phy-regulator-ldo-mode to the 28nm DSI PHY.
> When converting from .txt to .yaml we missed this one.
> 
> Fixes: 4dbe55c97741 ("dt-bindings: msm: dsi: add yaml schemas for DSI 
> bindings")
> Reviewed-by: Dmitry Baryshkov 
> Signed-off-by: Bryan O'Donoghue 
> ---
>  .../devicetree/bindings/display/msm/dsi-phy-28nm.yaml | 4 
>  1 file changed, 4 insertions(+)
> 

Acked-by: Rob Herring 


Re: [PATCH 2/2] dt-bindings: display: msm: drop unneeded list for single compatible

2023-01-08 Thread Rob Herring


On Sun, 25 Dec 2022 12:59:25 +0100, Krzysztof Kozlowski wrote:
> With only one compatible, there is no need to define it as list (items).
> 
> Signed-off-by: Krzysztof Kozlowski 
> ---
>  .../devicetree/bindings/display/msm/qcom,msm8998-dpu.yaml  | 3 +--
>  .../devicetree/bindings/display/msm/qcom,msm8998-mdss.yaml | 3 +--
>  .../devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml  | 3 +--
>  .../devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml | 3 +--
>  .../devicetree/bindings/display/msm/qcom,sc7180-dpu.yaml   | 3 +--
>  .../devicetree/bindings/display/msm/qcom,sc7180-mdss.yaml  | 3 +--
>  .../devicetree/bindings/display/msm/qcom,sdm845-dpu.yaml   | 3 +--
>  .../devicetree/bindings/display/msm/qcom,sdm845-mdss.yaml  | 3 +--
>  .../devicetree/bindings/display/msm/qcom,sm6115-dpu.yaml   | 3 +--
>  .../devicetree/bindings/display/msm/qcom,sm6115-mdss.yaml  | 3 +--
>  .../devicetree/bindings/display/msm/qcom,sm8250-mdss.yaml  | 3 +--
>  11 files changed, 11 insertions(+), 22 deletions(-)
> 

Acked-by: Rob Herring 


Re: [PATCH 1/2] dt-bindings: display: msm: drop redundant part of title

2023-01-08 Thread Rob Herring


On Sun, 25 Dec 2022 12:59:24 +0100, Krzysztof Kozlowski wrote:
> The Devicetree bindings document does not have to say in the title that
> contains "DT properties", but instead just describe the hardware.
> 
> Signed-off-by: Krzysztof Kozlowski 
> ---
>  .../devicetree/bindings/display/msm/dsi-phy-common.yaml| 7 +++
>  .../devicetree/bindings/display/msm/qcom,msm8998-dpu.yaml  | 2 +-
>  .../devicetree/bindings/display/msm/qcom,qcm2290-dpu.yaml  | 2 +-
>  .../devicetree/bindings/display/msm/qcom,sc7180-dpu.yaml   | 2 +-
>  .../devicetree/bindings/display/msm/qcom,sc7280-dpu.yaml   | 2 +-
>  .../devicetree/bindings/display/msm/qcom,sdm845-dpu.yaml   | 2 +-
>  .../devicetree/bindings/display/msm/qcom,sm6115-dpu.yaml   | 2 +-
>  7 files changed, 9 insertions(+), 10 deletions(-)
> 

Acked-by: Rob Herring 


Re: [PATCH V7 2/4] dt-bindings: display: panel: Add Samsung AMS495QA01

2023-01-08 Thread Rob Herring


On Tue, 03 Jan 2023 13:07:05 -0600, Chris Morgan wrote:
> From: Chris Morgan 
> 
> Add documentation for Samsung AMS495QA01 panel (with Magnachip
> D53E6EA8966 controller IC).
> 
> Signed-off-by: Chris Morgan 
> Signed-off-by: Maya Matuszczyk 
> ---
>  .../display/panel/samsung,ams495qa01.yaml | 57 +++
>  1 file changed, 57 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.

Missing tags:

Reviewed-by: Rob Herring 




Re: [PATCH 01/15] video: fbdev: atmel_lcdfb: Rework backlight handling

2023-01-08 Thread Helge Deller

On 1/7/23 21:53, Sam Ravnborg wrote:

Hi Stephen.

On Sat, Jan 07, 2023 at 09:36:47PM +0100, Stephen Kitt wrote:

On 7 January 2023 19:26:15 CET, Sam Ravnborg via B4 Submission Endpoint 
 wrote:

From: Sam Ravnborg 

The atmel_lcdfb had code to save/restore power state.
This is not needed so drop it.

Introduce backlight_is_brightness() to make logic simpler.

Signed-off-by: Sam Ravnborg 
Cc: Nicolas Ferre 
Cc: Alexandre Belloni 
Cc: Ludovic Desroches 
Cc: linux-fb...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
---
drivers/video/fbdev/atmel_lcdfb.c | 24 +++-
1 file changed, 3 insertions(+), 21 deletions(-)

...


Hi Sam,

I’d submitted quite a few more of these previously (and you’d reviewed them), 
see e.g. the thread starting at https://lkml.org/lkml/2022/6/7/4365, and 
yesterday, https://lkml.org/lkml/2023/1/6/520, 
https://lkml.org/lkml/2023/1/6/656, https://lkml.org/lkml/2023/1/6/970, 
https://lkml.org/lkml/2023/1/6/643, and https://lkml.org/lkml/2023/1/6/680. 
There are a few more, I can find them if it’s any use.


The patches from yesterday was what triggered me to resurrect an old
branch of mine where I had done something similar. I had lost all
memory of reviewing similar patches from you.


Helge - could you pick the reviewed patches from:
https://lore.kernel.org/all/20220607192335.1137249-1-st...@sk2.org/
[This is the same mail as Stephen refer to above - looked up via lore].


I just pulled those 7 patches into fbdev/for-next.
If you need more, please let me know,

Thanks!
Helge




Stephen - I expect Daniel/Lee to take care of the patches from yesterday.
If you can look up other pending patches from you please do so, so we
can have them applied.
Preferably with links to lore - as this makes it easier to apply them.

Review of what is unique in this set would be appreciated.

Sam




[PATCH v2 03/13] drm/bridge: lt9611: fix polarity programming

2023-01-08 Thread Dmitry Baryshkov
Fix programming of hsync and vsync polarities

Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 58f39b279217..deb503ca956a 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -207,7 +207,6 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
 
/* stage 2 */
{ 0x834a, 0x40 },
-   { 0x831d, 0x10 },
 
/* MK limit */
{ 0x832d, 0x38 },
@@ -222,11 +221,19 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
{ 0x8325, 0x00 },
{ 0x832a, 0x01 },
{ 0x834a, 0x10 },
-   { 0x831d, 0x10 },
-   { 0x8326, 0x37 },
};
+   u8 pol = 0x10;
 
-   regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+   if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+   pol |= 0x2;
+   if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+   pol |= 0x1;
+   regmap_write(lt9611->regmap, 0x831d, pol);
+
+   if (mode->hdisplay == 3840)
+   regmap_multi_reg_write(lt9611->regmap, reg_cfg2, 
ARRAY_SIZE(reg_cfg2));
+   else
+   regmap_multi_reg_write(lt9611->regmap, reg_cfg, 
ARRAY_SIZE(reg_cfg));
 
switch (mode->hdisplay) {
case 640:
@@ -236,7 +243,7 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
regmap_write(lt9611->regmap, 0x8326, 0x37);
break;
case 3840:
-   regmap_multi_reg_write(lt9611->regmap, reg_cfg2, 
ARRAY_SIZE(reg_cfg2));
+   regmap_write(lt9611->regmap, 0x8326, 0x37);
break;
}
 
-- 
2.39.0



[PATCH v2 12/13] drm/bridge: lt9611: stop filtering modes via the table

2023-01-08 Thread Dmitry Baryshkov
The lt9611 bridge can support different modes, it makes no sense to list
them in the table. Drop the table and check the number of interfaces
using the fixed value.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 41 +++--
 1 file changed, 4 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 82af1f954cc6..df9f015aa3a0 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -84,24 +84,6 @@ static const struct regmap_config lt9611_regmap_config = {
.num_ranges = ARRAY_SIZE(lt9611_ranges),
 };
 
-struct lt9611_mode {
-   u16 hdisplay;
-   u16 vdisplay;
-   u8 vrefresh;
-   u8 lanes;
-   u8 intfs;
-};
-
-static struct lt9611_mode lt9611_modes[] = {
-   { 3840, 2160, 30, 4, 2 }, /* 3840x2160 24bit 30Hz 4Lane 2ports */
-   { 1920, 1080, 60, 4, 1 }, /* 1080P 24bit 60Hz 4lane 1port */
-   { 1920, 1080, 30, 3, 1 }, /* 1080P 24bit 30Hz 3lane 1port */
-   { 1920, 1080, 24, 3, 1 },
-   { 720, 480, 60, 4, 1 },
-   { 720, 576, 50, 2, 1 },
-   { 640, 480, 60, 2, 1 },
-};
-
 static struct lt9611 *bridge_to_lt9611(struct drm_bridge *bridge)
 {
return container_of(bridge, struct lt9611, bridge);
@@ -603,21 +585,6 @@ static int lt9611_regulator_enable(struct lt9611 *lt9611)
return 0;
 }
 
-static struct lt9611_mode *lt9611_find_mode(const struct drm_display_mode 
*mode)
-{
-   int i;
-
-   for (i = 0; i < ARRAY_SIZE(lt9611_modes); i++) {
-   if (lt9611_modes[i].hdisplay == mode->hdisplay &&
-   lt9611_modes[i].vdisplay == mode->vdisplay &&
-   lt9611_modes[i].vrefresh == drm_mode_vrefresh(mode)) {
-   return _modes[i];
-   }
-   }
-
-   return NULL;
-}
-
 static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge 
*bridge)
 {
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
@@ -832,12 +799,12 @@ static enum drm_mode_status 
lt9611_bridge_mode_valid(struct drm_bridge *bridge,
 const struct 
drm_display_info *info,
 const struct 
drm_display_mode *mode)
 {
-   struct lt9611_mode *lt9611_mode = lt9611_find_mode(mode);
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
 
-   if (!lt9611_mode)
-   return MODE_BAD;
-   else if (lt9611_mode->intfs > 1 && !lt9611->dsi1)
+   if (mode->hdisplay >= 3840 && drm_mode_vrefresh(mode) >= 31)
+   return MODE_CLOCK_HIGH;
+
+   if (mode->hdisplay > 2000 && !lt9611->dsi1_node)
return MODE_PANEL;
else
return MODE_OK;
-- 
2.39.0



[PATCH v2 09/13] drm/bridge: lt9611: fix sync polarity for DVI output

2023-01-08 Thread Dmitry Baryshkov
Attaching DVI sink to the lt9611 requires different setup. Fix the
register write to make the DVI displays sync onto the correct sync
pulse.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 773d7a56f86f..7f9be74acf0d 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -352,13 +352,16 @@ static int lt9611_video_check(struct lt9611 *lt9611)
return temp;
 }
 
-static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611)
+static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611, bool is_hdmi)
 {
regmap_write(lt9611->regmap, 0x8443, 0x46 - lt9611->vic);
regmap_write(lt9611->regmap, 0x8447, lt9611->vic);
regmap_write(lt9611->regmap, 0x843d, 0x0a); /* UD1 infoframe */
 
-   regmap_write(lt9611->regmap, 0x82d6, 0x8c);
+   if (is_hdmi)
+   regmap_write(lt9611->regmap, 0x82d6, 0x8c);
+   else
+   regmap_write(lt9611->regmap, 0x82d6, 0x0c);
regmap_write(lt9611->regmap, 0x82d7, 0x04);
 }
 
@@ -719,7 +722,7 @@ lt9611_bridge_atomic_enable(struct drm_bridge *bridge,
}
 
lt9611_mipi_input_analog(lt9611);
-   lt9611_hdmi_tx_digital(lt9611);
+   lt9611_hdmi_tx_digital(lt9611, connector->display_info.is_hdmi);
lt9611_hdmi_tx_phy(lt9611);
 
msleep(500);
-- 
2.39.0



[PATCH v2 11/13] drm/bridge: lt9611: rework infoframes handling

2023-01-08 Thread Dmitry Baryshkov
Rework handling infoframes:
- Write full HDMI AVI infoframe instead of just fixing the VIC value
- Also send the HDMI Vendor Specific infoframe, as recommended by the
  HDMI spec.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 57 +++--
 1 file changed, 44 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 1396ab081f61..82af1f954cc6 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -59,7 +59,6 @@ struct lt9611 {
enum drm_connector_status status;
 
u8 edid_buf[EDID_SEG_SIZE];
-   u32 vic;
 };
 
 #define LT9611_PAGE_CONTROL0xff
@@ -352,12 +351,51 @@ static int lt9611_video_check(struct lt9611 *lt9611)
return temp;
 }
 
-static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611, bool is_hdmi)
+static void lt9611_hdmi_set_infoframes(struct lt9611 *lt9611,
+  struct drm_connector *connector,
+  struct drm_display_mode *mode)
 {
-   regmap_write(lt9611->regmap, 0x8443, 0x46 - lt9611->vic);
-   regmap_write(lt9611->regmap, 0x8447, lt9611->vic);
-   regmap_write(lt9611->regmap, 0x843d, 0x0a); /* UD1 infoframe */
+   union hdmi_infoframe infoframe;
+   ssize_t len;
+   u8 iframes = 0x0a; /* UD1 infoframe */
+   u8 buf[32];
+   int ret;
+   int i;
+
+   ret = drm_hdmi_avi_infoframe_from_display_mode(,
+  connector,
+  mode);
+   if (ret < 0)
+   goto out;
+
+   len = hdmi_infoframe_pack(, buf, sizeof(buf));
+   if (len < 0)
+   goto out;
+
+   for (i = 0; i < len; i++)
+   regmap_write(lt9611->regmap, 0x8440 + i, buf[i]);
+
+   ret = 
drm_hdmi_vendor_infoframe_from_display_mode(,
+ connector,
+ mode);
+   if (ret < 0)
+   goto out;
+
+   len = hdmi_infoframe_pack(, buf, sizeof(buf));
+   if (len < 0)
+   goto out;
 
+   for (i = 0; i < len; i++)
+   regmap_write(lt9611->regmap, 0x8474 + i, buf[i]);
+
+   iframes |= 0x20;
+
+out:
+   regmap_write(lt9611->regmap, 0x843d, iframes); /* UD1 infoframe */
+}
+
+static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611, bool is_hdmi)
+{
if (is_hdmi)
regmap_write(lt9611->regmap, 0x82d6, 0x8c);
else
@@ -687,9 +725,7 @@ lt9611_bridge_atomic_enable(struct drm_bridge *bridge,
struct drm_connector_state *conn_state;
struct drm_crtc_state *crtc_state;
struct drm_display_mode *mode;
-   struct hdmi_avi_infoframe avi_frame;
unsigned int postdiv;
-   int ret;
 
connector = drm_atomic_get_new_connector_for_encoder(state, 
bridge->encoder);
if (WARN_ON(!connector))
@@ -710,18 +746,13 @@ lt9611_bridge_atomic_enable(struct drm_bridge *bridge,
lt9611_mipi_video_setup(lt9611, mode);
lt9611_pcr_setup(lt9611, mode, postdiv);
 
-   ret = drm_hdmi_avi_infoframe_from_display_mode(_frame,
-  connector,
-  mode);
-   if (!ret)
-   lt9611->vic = avi_frame.video_code;
-
if (lt9611_power_on(lt9611)) {
dev_err(lt9611->dev, "power on failed\n");
return;
}
 
lt9611_mipi_input_analog(lt9611);
+   lt9611_hdmi_set_infoframes(lt9611, connector, mode);
lt9611_hdmi_tx_digital(lt9611, connector->display_info.is_hdmi);
lt9611_hdmi_tx_phy(lt9611);
 
-- 
2.39.0



[PATCH v2 13/13] drm/bridge: lt9611: properly program the dual host mode

2023-01-08 Thread Dmitry Baryshkov
If the bridge is connected using both DSI ports, the driver should use
both of them all the time. Correct programming sequence to always use
dual-port mode if both dsi0 and dsi1 are connected.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 28 -
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index df9f015aa3a0..561da6bd2698 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -118,7 +118,7 @@ static int lt9611_mipi_input_digital(struct lt9611 *lt9611,
{ 0x8306, 0x0a },
};
 
-   if (mode->hdisplay == 3840)
+   if (lt9611->dsi1_node)
reg_cfg[1].def = 0x03;
 
return regmap_multi_reg_write(lt9611->regmap, reg_cfg, 
ARRAY_SIZE(reg_cfg));
@@ -191,16 +191,6 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
{ 0x832d, 0x38 },
{ 0x8331, 0x08 },
};
-   const struct reg_sequence reg_cfg2[] = {
-   { 0x830b, 0x03 },
-   { 0x830c, 0xd0 },
-   { 0x8348, 0x03 },
-   { 0x8349, 0xe0 },
-   { 0x8324, 0x72 },
-   { 0x8325, 0x00 },
-   { 0x832a, 0x01 },
-   { 0x834a, 0x10 },
-   };
u8 pol = 0x10;
 
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
@@ -209,10 +199,18 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const 
struct drm_display_mod
pol |= 0x1;
regmap_write(lt9611->regmap, 0x831d, pol);
 
-   if (mode->hdisplay == 3840)
-   regmap_multi_reg_write(lt9611->regmap, reg_cfg2, 
ARRAY_SIZE(reg_cfg2));
-   else
-   regmap_multi_reg_write(lt9611->regmap, reg_cfg, 
ARRAY_SIZE(reg_cfg));
+   regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+   if (lt9611->dsi1_node) {
+   unsigned int hact = mode->hdisplay;
+
+   hact >>= 2;
+   hact += 0x50;
+   hact = min(hact, 0x3e0U);
+   regmap_write(lt9611->regmap, 0x830b, hact / 256);
+   regmap_write(lt9611->regmap, 0x830c, hact % 256);
+   regmap_write(lt9611->regmap, 0x8348, hact / 256);
+   regmap_write(lt9611->regmap, 0x8349, hact % 256);
+   }
 
regmap_write(lt9611->regmap, 0x8326, pcr_m);
 
-- 
2.39.0



[PATCH v2 08/13] drm/bridge: lt9611: attach to the next bridge

2023-01-08 Thread Dmitry Baryshkov
The bindings require that there is a next bridge after the lt9611. If
nothing else it can be the hdmi-connector (as used on the RB3 platform,
see sdm845-db845c.dts).

Bring in the next bridge into the drm bridges chain and attach to it.

Since lt9611 is not anymore the last bridge in the chain, this also
allows us to drop all the !DRM_BRIDGE_ATTACH_NO_CONNECTOR functionality.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 99 ++---
 1 file changed, 7 insertions(+), 92 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 1b65a573be27..773d7a56f86f 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -33,7 +34,7 @@
 struct lt9611 {
struct device *dev;
struct drm_bridge bridge;
-   struct drm_connector connector;
+   struct drm_bridge *next_bridge;
 
struct regmap *regmap;
 
@@ -107,11 +108,6 @@ static struct lt9611 *bridge_to_lt9611(struct drm_bridge 
*bridge)
return container_of(bridge, struct lt9611, bridge);
 }
 
-static struct lt9611 *connector_to_lt9611(struct drm_connector *connector)
-{
-   return container_of(connector, struct lt9611, connector);
-}
-
 static int lt9611_mipi_input_analog(struct lt9611 *lt9611)
 {
const struct reg_sequence reg_cfg[] = {
@@ -581,9 +577,9 @@ static struct lt9611_mode *lt9611_find_mode(const struct 
drm_display_mode *mode)
return NULL;
 }
 
-/* connector funcs */
-static enum drm_connector_status __lt9611_detect(struct lt9611 *lt9611)
+static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge 
*bridge)
 {
+   struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
unsigned int reg_val = 0;
int connected = 0;
 
@@ -596,12 +592,6 @@ static enum drm_connector_status __lt9611_detect(struct 
lt9611 *lt9611)
return lt9611->status;
 }
 
-static enum drm_connector_status
-lt9611_connector_detect(struct drm_connector *connector, bool force)
-{
-   return __lt9611_detect(connector_to_lt9611(connector));
-}
-
 static int lt9611_read_edid(struct lt9611 *lt9611)
 {
unsigned int temp;
@@ -683,30 +673,6 @@ lt9611_get_edid_block(void *data, u8 *buf, unsigned int 
block, size_t len)
return 0;
 }
 
-static int lt9611_connector_get_modes(struct drm_connector *connector)
-{
-   struct lt9611 *lt9611 = connector_to_lt9611(connector);
-   unsigned int count;
-   struct edid *edid;
-
-   lt9611_power_on(lt9611);
-   edid = drm_do_get_edid(connector, lt9611_get_edid_block, lt9611);
-   drm_connector_update_edid_property(connector, edid);
-   count = drm_add_edid_modes(connector, edid);
-   kfree(edid);
-
-   return count;
-}
-
-static enum drm_mode_status
-lt9611_connector_mode_valid(struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   struct lt9611_mode *lt9611_mode = lt9611_find_mode(mode);
-
-   return lt9611_mode ? MODE_OK : MODE_BAD;
-}
-
 /* bridge funcs */
 static void
 lt9611_bridge_atomic_enable(struct drm_bridge *bridge,
@@ -784,21 +750,6 @@ lt9611_bridge_atomic_disable(struct drm_bridge *bridge,
}
 }
 
-static struct
-drm_connector_helper_funcs lt9611_bridge_connector_helper_funcs = {
-   .get_modes = lt9611_connector_get_modes,
-   .mode_valid = lt9611_connector_mode_valid,
-};
-
-static const struct drm_connector_funcs lt9611_bridge_connector_funcs = {
-   .fill_modes = drm_helper_probe_single_connector_modes,
-   .detect = lt9611_connector_detect,
-   .destroy = drm_connector_cleanup,
-   .reset = drm_atomic_helper_connector_reset,
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
 static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
 struct device_node *dsi_node)
 {
@@ -834,44 +785,13 @@ static struct mipi_dsi_device *lt9611_attach_dsi(struct 
lt9611 *lt9611,
return dsi;
 }
 
-static int lt9611_connector_init(struct drm_bridge *bridge, struct lt9611 
*lt9611)
-{
-   int ret;
-
-   ret = drm_connector_init(bridge->dev, >connector,
-_bridge_connector_funcs,
-DRM_MODE_CONNECTOR_HDMIA);
-   if (ret) {
-   DRM_ERROR("Failed to initialize connector with drm\n");
-   return ret;
-   }
-
-   drm_connector_helper_add(>connector,
-_bridge_connector_helper_funcs);
-
-   if (!bridge->encoder) {
-   DRM_ERROR("Parent encoder object not found");
-   return -ENODEV;
-   }
-
-   drm_connector_attach_encoder(>connector, bridge->encoder);
-
-   return 0;
-}
-

[PATCH v2 02/13] drm/bridge: lt9611: fix HPD reenablement

2023-01-08 Thread Dmitry Baryshkov
The driver will reset the bridge in the atomic_pre_enable(). However
this will also drop the HPD interrupt state. Instead of resetting the
bridge, properly wake it up. This fixes the HPD interrupt delivery after
the disable/enable cycle.

Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 2714184cc53f..58f39b279217 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -856,12 +856,18 @@ static enum drm_mode_status 
lt9611_bridge_mode_valid(struct drm_bridge *bridge,
 static void lt9611_bridge_pre_enable(struct drm_bridge *bridge)
 {
struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+   static const struct reg_sequence reg_cfg[] = {
+   { 0x8102, 0x12 },
+   { 0x8123, 0x40 },
+   { 0x8130, 0xea },
+   { 0x8011, 0xfa },
+   };
 
if (!lt9611->sleep)
return;
 
-   lt9611_reset(lt9611);
-   regmap_write(lt9611->regmap, 0x80ee, 0x01);
+   regmap_multi_reg_write(lt9611->regmap,
+  reg_cfg, ARRAY_SIZE(reg_cfg));
 
lt9611->sleep = false;
 }
-- 
2.39.0



[PATCH v2 10/13] drm/bridge: lt9611: simplify video timings programming

2023-01-08 Thread Dmitry Baryshkov
Inline calculated values to simplify the calculation in
lt9611_mipi_video_setup().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/bridge/lontium-lt9611.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c 
b/drivers/gpu/drm/bridge/lontium-lt9611.c
index 7f9be74acf0d..1396ab081f61 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -155,12 +155,12 @@ static void lt9611_mipi_video_setup(struct lt9611 *lt9611,
hactive = mode->hdisplay;
hsync_len = mode->hsync_end - mode->hsync_start;
hfront_porch = mode->hsync_start - mode->hdisplay;
-   hsync_porch = hsync_len + mode->htotal - mode->hsync_end;
+   hsync_porch = mode->htotal - mode->hsync_start;
 
vactive = mode->vdisplay;
vsync_len = mode->vsync_end - mode->vsync_start;
vfront_porch = mode->vsync_start - mode->vdisplay;
-   vsync_porch = vsync_len + mode->vtotal - mode->vsync_end;
+   vsync_porch = mode->vtotal - mode->vsync_start;
 
regmap_write(lt9611->regmap, 0x830d, (u8)(v_total / 256));
regmap_write(lt9611->regmap, 0x830e, (u8)(v_total % 256));
-- 
2.39.0



  1   2   >