diff options
100 files changed, 2219 insertions, 1009 deletions
| diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml index e00b88332f2f..246bbb509bea 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -31,6 +31,7 @@ properties:            - qcom,sm8650-dp        - items:            - enum: +              - qcom,sar2130p-dp                - qcom,sm6350-dp                - qcom,sm8150-dp                - qcom,sm8250-dp diff --git a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml index 2aab33cd0017..82fe95a6d959 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml @@ -23,6 +23,8 @@ properties:                - qcom,msm8996-dsi-ctrl                - qcom,msm8998-dsi-ctrl                - qcom,qcm2290-dsi-ctrl +              - qcom,sa8775p-dsi-ctrl +              - qcom,sar2130p-dsi-ctrl                - qcom,sc7180-dsi-ctrl                - qcom,sc7280-dsi-ctrl                - qcom,sdm660-dsi-ctrl @@ -314,6 +316,8 @@ allOf:            contains:              enum:                - qcom,msm8998-dsi-ctrl +              - qcom,sa8775p-dsi-ctrl +              - qcom,sar2130p-dsi-ctrl                - qcom,sc7180-dsi-ctrl                - qcom,sc7280-dsi-ctrl                - qcom,sdm845-dsi-ctrl diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml index 321470435e65..3c75ff42999a 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml @@ -17,6 +17,8 @@ properties:      enum:        - qcom,dsi-phy-7nm        - qcom,dsi-phy-7nm-8150 +      - qcom,sa8775p-dsi-phy-5nm +      - qcom,sar2130p-dsi-phy-5nm        - qcom,sc7280-dsi-phy-7nm        - qcom,sm6375-dsi-phy-7nm        - qcom,sm8350-dsi-phy-5nm diff --git a/Documentation/devicetree/bindings/display/msm/hdmi.yaml b/Documentation/devicetree/bindings/display/msm/hdmi.yaml index d4a2033afea8..dfec6c3480f3 100644 --- a/Documentation/devicetree/bindings/display/msm/hdmi.yaml +++ b/Documentation/devicetree/bindings/display/msm/hdmi.yaml @@ -66,21 +66,6 @@ properties:      maxItems: 1      description: hpd pin -  qcom,hdmi-tx-mux-en-gpios: -    maxItems: 1 -    deprecated: true -    description: HDMI mux enable pin - -  qcom,hdmi-tx-mux-sel-gpios: -    maxItems: 1 -    deprecated: true -    description: HDMI mux select pin - -  qcom,hdmi-tx-mux-lpm-gpios: -    maxItems: 1 -    deprecated: true -    description: HDMI mux lpm pin -    '#sound-dai-cells':      const: 1 @@ -89,12 +74,12 @@ properties:      $ref: /schemas/graph.yaml#/properties/ports      properties:        port@0: -        $ref: /schemas/graph.yaml#/$defs/port-base +        $ref: /schemas/graph.yaml#/properties/port          description: |            Input endpoints of the controller.        port@1: -        $ref: /schemas/graph.yaml#/$defs/port-base +        $ref: /schemas/graph.yaml#/properties/port          description: |            Output endpoints of the controller. diff --git a/Documentation/devicetree/bindings/display/msm/mdp4.yaml b/Documentation/devicetree/bindings/display/msm/mdp4.yaml index 35204a287579..03ee09faa335 100644 --- a/Documentation/devicetree/bindings/display/msm/mdp4.yaml +++ b/Documentation/devicetree/bindings/display/msm/mdp4.yaml @@ -18,9 +18,10 @@ properties:    clocks:      minItems: 6 -    maxItems: 6 +    maxItems: 8    clock-names: +    minItems: 6      items:        - const: core_clk        - const: iface_clk @@ -28,6 +29,12 @@ properties:        - const: lut_clk        - const: hdmi_clk        - const: tv_clk +      - const: lcdc_clk +      - const: pxo +        description: XO used to drive the internal LVDS PLL + +  '#clock-cells': +    const: 0    reg:      maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml index 7c6462caa442..db9c43b20e2a 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml @@ -84,6 +84,18 @@ properties:      items:        - description: MDSS_CORE reset +  interconnects: +    minItems: 1 +    items: +      - description: Interconnect path from mdp0 (or a single mdp) port to the data bus +      - description: Interconnect path from CPU to the reg bus + +  interconnect-names: +    minItems: 1 +    items: +      - const: mdp0-mem +      - const: cpu-cfg +  required:    - compatible    - reg diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml index 5fac3e266703..1053b3bc4908 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sa8775p-mdss.yaml @@ -52,12 +52,23 @@ patternProperties:          items:            - const: qcom,sa8775p-dp +  "^dsi@[0-9a-f]+$": +    type: object +    additionalProperties: true +    properties: +      compatible: +        contains: +          const: qcom,sa8775p-dsi-ctrl +    "^phy@[0-9a-f]+$":      type: object      additionalProperties: true      properties:        compatible: -        const: qcom,sa8775p-edp-phy +        contains: +          enum: +            - qcom,sa8775p-dsi-phy-5nm +            - qcom,sa8775p-edp-phy  required:    - compatible @@ -139,6 +150,20 @@ examples:                          remote-endpoint = <&mdss0_dp0_in>;                      };                  }; + +                port@1 { +                    reg = <1>; +                    dpu_intf1_out: endpoint { +                        remote-endpoint = <&mdss0_dsi0_in>; +                    }; +                }; + +                port@2 { +                    reg = <2>; +                    dpu_intf2_out: endpoint { +                        remote-endpoint = <&mdss0_dsi1_in>; +                    }; +                };              };              mdss0_mdp_opp_table: opp-table { @@ -186,6 +211,160 @@ examples:              vdda-pll-supply = <&vreg_l4a>;          }; +        dsi@ae94000 { +            compatible = "qcom,sa8775p-dsi-ctrl", "qcom,mdss-dsi-ctrl"; +            reg = <0x0ae94000 0x400>; +            reg-names = "dsi_ctrl"; + +            interrupt-parent = <&mdss>; +            interrupts = <4>; + +            clocks = <&dispc_byte_clk>, +                     <&dispcc_intf_clk>, +                     <&dispcc_pclk>, +                     <&dispcc_esc_clk>, +                     <&dispcc_ahb_clk>, +                     <&gcc_bus_clk>; +            clock-names = "byte", +                          "byte_intf", +                          "pixel", +                          "core", +                          "iface", +                          "bus"; +            assigned-clocks = <&dispcc_byte_clk>, +                              <&dispcc_pclk>; +            assigned-clock-parents = <&mdss0_dsi0_phy 0>, <&mdss0_dsi0_phy 1>; +            phys = <&mdss0_dsi0_phy>; + +            operating-points-v2 = <&dsi0_opp_table>; +            power-domains = <&rpmhpd SA8775P_MMCX>; + +            #address-cells = <1>; +            #size-cells = <0>; + +            ports { +                #address-cells = <1>; +                #size-cells = <0>; + +                port@0 { +                    reg = <0>; +                    mdss0_dsi0_in: endpoint { +                        remote-endpoint = <&dpu_intf1_out>; +                    }; +                }; + +                port@1 { +                    reg = <1>; +                    mdss0_dsi0_out: endpoint { }; +                }; +            }; + +            dsi0_opp_table: opp-table { +                compatible = "operating-points-v2"; + +                opp-358000000 { +                    opp-hz = /bits/ 64 <358000000>; +                    required-opps = <&rpmhpd_opp_svs_l1>; +                }; +            }; +        }; + +        mdss0_dsi0_phy: phy@ae94400 { +            compatible = "qcom,sa8775p-dsi-phy-5nm"; +            reg = <0x0ae94400 0x200>, +                  <0x0ae94600 0x280>, +                  <0x0ae94900 0x27c>; +            reg-names = "dsi_phy", +                        "dsi_phy_lane", +                        "dsi_pll"; + +            #clock-cells = <1>; +            #phy-cells = <0>; + +            clocks = <&dispcc_iface_clk>, +                     <&rpmhcc_ref_clk>; +            clock-names = "iface", "ref"; + +            vdds-supply = <&vreg_dsi_supply>; +        }; + +        dsi@ae96000 { +            compatible = "qcom,sa8775p-dsi-ctrl", "qcom,mdss-dsi-ctrl"; +            reg = <0x0ae96000 0x400>; +            reg-names = "dsi_ctrl"; + +            interrupt-parent = <&mdss>; +            interrupts = <4>; + +            clocks = <&dispc_byte_clk>, +                     <&dispcc_intf_clk>, +                     <&dispcc_pclk>, +                     <&dispcc_esc_clk>, +                     <&dispcc_ahb_clk>, +                     <&gcc_bus_clk>; +            clock-names = "byte", +                          "byte_intf", +                          "pixel", +                          "core", +                          "iface", +                          "bus"; +            assigned-clocks = <&dispcc_byte_clk>, +                              <&dispcc_pclk>; +            assigned-clock-parents = <&mdss0_dsi1_phy 0>, <&mdss0_dsi1_phy 1>; +            phys = <&mdss0_dsi1_phy>; + +            operating-points-v2 = <&dsi1_opp_table>; +            power-domains = <&rpmhpd SA8775P_MMCX>; + +            #address-cells = <1>; +            #size-cells = <0>; + +            ports { +                #address-cells = <1>; +                #size-cells = <0>; + +                port@0 { +                    reg = <0>; +                    mdss0_dsi1_in: endpoint { +                        remote-endpoint = <&dpu_intf2_out>; +                    }; +                }; + +                port@1 { +                    reg = <1>; +                    mdss0_dsi1_out: endpoint { }; +                }; +            }; + +            dsi1_opp_table: opp-table { +                compatible = "operating-points-v2"; + +                opp-358000000 { +                    opp-hz = /bits/ 64 <358000000>; +                    required-opps = <&rpmhpd_opp_svs_l1>; +                }; +            }; +        }; + +        mdss0_dsi1_phy: phy@ae96400 { +            compatible = "qcom,sa8775p-dsi-phy-5nm"; +            reg = <0x0ae96400 0x200>, +                  <0x0ae96600 0x280>, +                  <0x0ae96900 0x27c>; +            reg-names = "dsi_phy", +                        "dsi_phy_lane", +                        "dsi_pll"; + +            #clock-cells = <1>; +            #phy-cells = <0>; + +            clocks = <&dispcc_iface_clk>, +                     <&rpmhcc_ref_clk>; +            clock-names = "iface", "ref"; + +            vdds-supply = <&vreg_dsi_supply>; +        }; +          displayport-controller@af54000 {              compatible = "qcom,sa8775p-dp"; diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sar2130p-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sar2130p-mdss.yaml new file mode 100644 index 000000000000..870144b53cec --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/qcom,sar2130p-mdss.yaml @@ -0,0 +1,439 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/msm/qcom,sar2130p-mdss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SAR2130P Display MDSS + +maintainers: +  - Dmitry Baryshkov <lumag@kernel.org> + +description: +  SAR2310P 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,sar2130p-mdss + +  clocks: +    items: +      - description: Display MDSS AHB +      - description: Display AHB +      - description: Display hf AXI +      - description: Display core + +  iommus: +    maxItems: 1 + +  interconnects: +    items: +      - description: Interconnect path from mdp0 port to the data bus +      - description: Interconnect path from CPU to the reg bus + +  interconnect-names: +    items: +      - const: mdp0-mem +      - const: cpu-cfg + +patternProperties: +  "^display-controller@[0-9a-f]+$": +    type: object +    additionalProperties: true +    properties: +      compatible: +        const: qcom,sar2130p-dpu + +  "^displayport-controller@[0-9a-f]+$": +    type: object +    additionalProperties: true +    properties: +      compatible: +        contains: +          const: qcom,sar2130p-dp + +  "^dsi@[0-9a-f]+$": +    type: object +    additionalProperties: true +    properties: +      compatible: +        contains: +          const: qcom,sar2130p-dsi-ctrl + +  "^phy@[0-9a-f]+$": +    type: object +    additionalProperties: true +    properties: +      compatible: +        const: qcom,sar2130p-dsi-phy-5nm + +required: +  - compatible + +unevaluatedProperties: false + +examples: +  - | +    #include <dt-bindings/interrupt-controller/arm-gic.h> +    #include <dt-bindings/power/qcom,rpmhpd.h> +    #include <dt-bindings/phy/phy-qcom-qmp.h> + +    display-subsystem@ae00000 { +        compatible = "qcom,sar2130p-mdss"; +        reg = <0x0ae00000 0x1000>; +        reg-names = "mdss"; + +        interconnects = <&mmss_noc_master_mdp &mc_virt_slave_ebi1>, +                        <&gem_noc_master_appss_proc &config_noc_slave_display_cfg>; +        interconnect-names = "mdp0-mem", "cpu-cfg"; + +        resets = <&dispcc_disp_cc_mdss_core_bcr>; + +        power-domains = <&dispcc_mdss_gdsc>; + +        clocks = <&dispcc_disp_cc_mdss_ahb_clk>, +                 <&gcc_gcc_disp_ahb_clk>, +                 <&gcc_gcc_disp_hf_axi_clk>, +                 <&dispcc_disp_cc_mdss_mdp_clk>; +        clock-names = "iface", "bus", "nrt_bus", "core"; + +        interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; +        interrupt-controller; +        #interrupt-cells = <1>; + +        iommus = <&apps_smmu 0x1c00 0x2>; + +        #address-cells = <1>; +        #size-cells = <1>; +        ranges; + +        display-controller@ae01000 { +            compatible = "qcom,sar2130p-dpu"; +            reg = <0x0ae01000 0x8f000>, +                  <0x0aeb0000 0x2008>; +            reg-names = "mdp", "vbif"; + +            clocks = <&gcc_gcc_disp_ahb_clk>, +                     <&gcc_gcc_disp_hf_axi_clk>, +                     <&dispcc_disp_cc_mdss_ahb_clk>, +                     <&dispcc_disp_cc_mdss_mdp_lut_clk>, +                     <&dispcc_disp_cc_mdss_mdp_clk>, +                     <&dispcc_disp_cc_mdss_vsync_clk>; +            clock-names = "bus", +                          "nrt_bus", +                          "iface", +                          "lut", +                          "core", +                          "vsync"; + +            assigned-clocks = <&dispcc_disp_cc_mdss_vsync_clk>; +            assigned-clock-rates = <19200000>; + +            operating-points-v2 = <&mdp_opp_table>; +            power-domains = <&rpmhpd RPMHPD_MMCX>; + +            interrupt-parent = <&mdss>; +            interrupts = <0>; + +            ports { +                #address-cells = <1>; +                #size-cells = <0>; + +                port@0 { +                    reg = <0>; + +                    dpu_intf0_out: endpoint { +                        remote-endpoint = <&mdss_dp0_in>; +                    }; +                }; + +                port@1 { +                    reg = <1>; + +                    dpu_intf1_out: endpoint { +                        remote-endpoint = <&mdss_dsi0_in>; +                    }; +                }; + +                port@2 { +                    reg = <2>; + +                    dpu_intf2_out: endpoint { +                        remote-endpoint = <&mdss_dsi1_in>; +                    }; +                }; +            }; + +            mdp_opp_table: opp-table { +                compatible = "operating-points-v2"; + +                opp-200000000 { +                    opp-hz = /bits/ 64 <200000000>; +                    required-opps = <&rpmhpd_opp_low_svs>; +                }; + +                opp-325000000 { +                    opp-hz = /bits/ 64 <325000000>; +                    required-opps = <&rpmhpd_opp_svs>; +                }; + +                opp-375000000 { +                    opp-hz = /bits/ 64 <375000000>; +                    required-opps = <&rpmhpd_opp_svs_l1>; +                }; + +                opp-514000000 { +                    opp-hz = /bits/ 64 <514000000>; +                    required-opps = <&rpmhpd_opp_nom>; +                }; +            }; +        }; + +        displayport-controller@ae90000 { +            compatible = "qcom,sar2130p-dp", +                         "qcom,sm8350-dp"; +            reg = <0xae90000 0x200>, +                  <0xae90200 0x200>, +                  <0xae90400 0xc00>, +                  <0xae91000 0x400>, +                  <0xae91400 0x400>; + +            interrupt-parent = <&mdss>; +            interrupts = <12>; +            clocks = <&dispcc_disp_cc_mdss_ahb_clk>, +                     <&dispcc_disp_cc_mdss_dptx0_aux_clk>, +                     <&dispcc_disp_cc_mdss_dptx0_link_clk>, +                     <&dispcc_disp_cc_mdss_dptx0_link_intf_clk>, +                     <&dispcc_disp_cc_mdss_dptx0_pixel0_clk>; +            clock-names = "core_iface", +                          "core_aux", +                          "ctrl_link", +                          "ctrl_link_iface", +                          "stream_pixel"; + +            assigned-clocks = <&dispcc_disp_cc_mdss_dptx0_link_clk_src>, +                              <&dispcc_disp_cc_mdss_dptx0_pixel0_clk_src>; +            assigned-clock-parents = <&usb_dp_qmpphy_QMP_USB43DP_DP_LINK_CLK>, +                                     <&usb_dp_qmpphy_QMP_USB43DP_DP_VCO_DIV_CLK>; + +            phys = <&usb_dp_qmpphy QMP_USB43DP_DP_PHY>; +            phy-names = "dp"; + +            #sound-dai-cells = <0>; + +            operating-points-v2 = <&dp_opp_table>; +            power-domains = <&rpmhpd RPMHPD_MMCX>; + +            ports { +                #address-cells = <1>; +                #size-cells = <0>; + +                port@0 { +                    reg = <0>; +                    mdss_dp0_in: endpoint { +                        remote-endpoint = <&dpu_intf0_out>; +                    }; +                }; + +                port@1 { +                    reg = <1>; +                    mdss_dp0_out: endpoint { +                        remote-endpoint = <&usb_dp_qmpphy_dp_in>; +                    }; +                }; +        }; + +        dp_opp_table: opp-table { +                compatible = "operating-points-v2"; + +                opp-162000000 { +                    opp-hz = /bits/ 64 <162000000>; +                    required-opps = <&rpmhpd_opp_low_svs_d1>; +                }; + +                opp-270000000 { +                    opp-hz = /bits/ 64 <270000000>; +                    required-opps = <&rpmhpd_opp_low_svs>; +                }; + +                opp-540000000 { +                    opp-hz = /bits/ 64 <540000000>; +                    required-opps = <&rpmhpd_opp_svs_l1>; +                }; + +                opp-810000000 { +                    opp-hz = /bits/ 64 <810000000>; +                    required-opps = <&rpmhpd_opp_nom>; +                }; +            }; +        }; + +        dsi@ae94000 { +            compatible = "qcom,sar2130p-dsi-ctrl", +                         "qcom,mdss-dsi-ctrl"; +            reg = <0x0ae94000 0x400>; +            reg-names = "dsi_ctrl"; + +            interrupt-parent = <&mdss>; +            interrupts = <4>; + +            clocks = <&dispcc_disp_cc_mdss_byte0_clk>, +                     <&dispcc_disp_cc_mdss_byte0_intf_clk>, +                     <&dispcc_disp_cc_mdss_pclk0_clk>, +                     <&dispcc_disp_cc_mdss_esc0_clk>, +                     <&dispcc_disp_cc_mdss_ahb_clk>, +                     <&gcc_gcc_disp_hf_axi_clk>; +            clock-names = "byte", +                          "byte_intf", +                          "pixel", +                          "core", +                          "iface", +                          "bus"; + +            assigned-clocks = <&dispcc_disp_cc_mdss_byte0_clk_src>, +                              <&dispcc_disp_cc_mdss_pclk0_clk_src>; +            assigned-clock-parents = <&mdss_dsi0_phy 0>, <&mdss_dsi0_phy 1>; + +            operating-points-v2 = <&dsi_opp_table>; +            power-domains = <&rpmhpd RPMHPD_MMCX>; + +            phys = <&mdss_dsi0_phy>; +            phy-names = "dsi"; + +            #address-cells = <1>; +            #size-cells = <0>; + +            ports { +                #address-cells = <1>; +                #size-cells = <0>; + +                port@0 { +                    reg = <0>; + +                    mdss_dsi0_in: endpoint { +                        remote-endpoint = <&dpu_intf1_out>; +                    }; +                }; + +                port@1 { +                    reg = <1>; + +                    mdss_dsi0_out: endpoint { +                    }; +                }; +            }; + +            dsi_opp_table: opp-table { +                compatible = "operating-points-v2"; + +                opp-187500000 { +                    opp-hz = /bits/ 64 <187500000>; +                    required-opps = <&rpmhpd_opp_low_svs>; +                }; + +                opp-300000000 { +                    opp-hz = /bits/ 64 <300000000>; +                    required-opps = <&rpmhpd_opp_svs>; +                }; + +                opp-358000000 { +                    opp-hz = /bits/ 64 <358000000>; +                    required-opps = <&rpmhpd_opp_svs_l1>; +                }; +            }; +        }; + +        mdss_dsi0_phy: phy@ae94400 { +            compatible = "qcom,sar2130p-dsi-phy-5nm"; +            reg = <0x0ae95000 0x200>, +                  <0x0ae95200 0x280>, +                  <0x0ae95500 0x400>; +            reg-names = "dsi_phy", +                        "dsi_phy_lane", +                        "dsi_pll"; + +            #clock-cells = <1>; +            #phy-cells = <0>; + +            clocks = <&dispcc_disp_cc_mdss_ahb_clk>, +                     <&rpmhcc_rpmh_cxo_clk>; +            clock-names = "iface", "ref"; +        }; + +        dsi@ae96000 { +            compatible = "qcom,sar2130p-dsi-ctrl", +                         "qcom,mdss-dsi-ctrl"; +            reg = <0x0ae96000 0x400>; +            reg-names = "dsi_ctrl"; + +            interrupt-parent = <&mdss>; +            interrupts = <5>; + +            clocks = <&dispcc_disp_cc_mdss_byte1_clk>, +                     <&dispcc_disp_cc_mdss_byte1_intf_clk>, +                     <&dispcc_disp_cc_mdss_pclk1_clk>, +                     <&dispcc_disp_cc_mdss_esc1_clk>, +                     <&dispcc_disp_cc_mdss_ahb_clk>, +                     <&gcc_gcc_disp_hf_axi_clk>; +            clock-names = "byte", +                          "byte_intf", +                          "pixel", +                          "core", +                          "iface", +                          "bus"; + +            assigned-clocks = <&dispcc_disp_cc_mdss_byte1_clk_src>, +                              <&dispcc_disp_cc_mdss_pclk1_clk_src>; +            assigned-clock-parents = <&mdss_dsi1_phy 0>, <&mdss_dsi1_phy 1>; + +            operating-points-v2 = <&dsi_opp_table>; +            power-domains = <&rpmhpd RPMHPD_MMCX>; + +            phys = <&mdss_dsi1_phy>; +            phy-names = "dsi"; + +            #address-cells = <1>; +            #size-cells = <0>; + +            ports { +                #address-cells = <1>; +                #size-cells = <0>; + +                port@0 { +                    reg = <0>; + +                    mdss_dsi1_in: endpoint { +                        remote-endpoint = <&dpu_intf2_out>; +                    }; +                }; + +                port@1 { +                    reg = <1>; + +                    mdss_dsi1_out: endpoint { +                    }; +                }; +            }; +        }; + +        mdss_dsi1_phy: phy@ae97000 { +            compatible = "qcom,sar2130p-dsi-phy-5nm"; +            reg = <0x0ae97000 0x200>, +                  <0x0ae97200 0x280>, +                  <0x0ae97500 0x400>; +            reg-names = "dsi_phy", +                        "dsi_phy_lane", +                        "dsi_pll"; + +            #clock-cells = <1>; +            #phy-cells = <0>; + +            clocks = <&dispcc_disp_cc_mdss_ahb_clk>, +                     <&rpmhcc_rpmh_cxo_clk>; +            clock-names = "iface", "ref"; +        }; +    }; +... diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sc7280-dpu.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sc7280-dpu.yaml index 6902795b4e2c..df9ec15ad6c3 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sc7280-dpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sc7280-dpu.yaml @@ -17,6 +17,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#  properties:    compatible:      enum: +      - qcom,sar2130p-dpu        - qcom,sc7280-dpu        - qcom,sc8280xp-dpu        - qcom,sm8350-dpu diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml index 163fc83c1e80..68176de854b3 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml @@ -38,12 +38,16 @@ properties:      maxItems: 1    interconnects: -    maxItems: 2 +    items: +      - description: Interconnect path from the MDP0 port to the data bus +      - description: Interconnect path from the MDP1 port to the data bus +      - description: Interconnect path from the CPU to the reg bus    interconnect-names:      items:        - const: mdp0-mem        - const: mdp1-mem +      - const: cpu-cfg  patternProperties:    "^display-controller@[0-9a-f]+$": @@ -88,6 +92,7 @@ examples:      #include <dt-bindings/clock/qcom,gcc-sm8350.h>      #include <dt-bindings/clock/qcom,rpmh.h>      #include <dt-bindings/interrupt-controller/arm-gic.h> +    #include <dt-bindings/interconnect/qcom,icc.h>      #include <dt-bindings/interconnect/qcom,sm8350.h>      #include <dt-bindings/power/qcom,rpmhpd.h> @@ -97,8 +102,10 @@ examples:          reg-names = "mdss";          interconnects = <&mmss_noc MASTER_MDP0 0 &mc_virt SLAVE_EBI1 0>, -                        <&mmss_noc MASTER_MDP1 0 &mc_virt SLAVE_EBI1 0>; -        interconnect-names = "mdp0-mem", "mdp1-mem"; +                        <&mmss_noc MASTER_MDP1 0 &mc_virt SLAVE_EBI1 0>, +                        <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY +                         &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; +        interconnect-names = "mdp0-mem", "mdp1-mem", "cpu-cfg";          power-domains = <&dispcc MDSS_GDSC>;          resets = <&dispcc DISP_CC_MDSS_CORE_BCR>; diff --git a/Documentation/devicetree/bindings/opp/opp-v2-qcom-adreno.yaml b/Documentation/devicetree/bindings/opp/opp-v2-qcom-adreno.yaml new file mode 100644 index 000000000000..a27ba7b663d4 --- /dev/null +++ b/Documentation/devicetree/bindings/opp/opp-v2-qcom-adreno.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/opp/opp-v2-qcom-adreno.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Adreno compatible OPP supply + +description: +  Adreno GPUs present in Qualcomm's Snapdragon chipsets uses an OPP specific +  ACD related information tailored for the specific chipset. This binding +  provides the information needed to describe such a hardware value. + +maintainers: +  - Rob Clark <robdclark@gmail.com> + +allOf: +  - $ref: opp-v2-base.yaml# + +properties: +  compatible: +    contains: +      const: operating-points-v2-adreno + +patternProperties: +  '^opp-[0-9]+$': +    type: object +    additionalProperties: false + +    properties: +      opp-hz: true + +      opp-level: true + +      opp-peak-kBps: true + +      opp-supported-hw: true + +      qcom,opp-acd-level: +        description: | +          A positive value representing the ACD (Adaptive Clock Distribution, +          a fancy name for clk throttling during voltage droop) level associated +          with this OPP node. This value is shared to a co-processor inside GPU +          (called Graphics Management Unit a.k.a GMU) during wake up. It may not +          be present for some OPPs and GMU will disable ACD while transitioning +          to that OPP. This value encodes a voltage threshold, delay cycles & +          calibration margins which are identified by characterization of the +          SoC. So, it doesn't have any unit. This data is passed to GMU firmware +          via 'HFI_H2F_MSG_ACD' packet. +        $ref: /schemas/types.yaml#/definitions/uint32 + +    required: +      - opp-hz +      - opp-level + +required: +  - compatible + +additionalProperties: false + +examples: +  - | +    #include <dt-bindings/power/qcom-rpmpd.h> + +    gpu_opp_table: opp-table { +        compatible = "operating-points-v2-adreno", "operating-points-v2"; + +        opp-687000000 { +            opp-hz = /bits/ 64 <687000000>; +            opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>; +            opp-peak-kBps = <8171875>; +            qcom,opp-acd-level = <0x882e5ffd>; +        }; + +        opp-550000000 { +            opp-hz = /bits/ 64 <550000000>; +            opp-level = <RPMH_REGULATOR_LEVEL_SVS>; +            opp-peak-kBps = <6074219>; +            qcom,opp-acd-level = <0xc0285ffd>; +        }; + +        opp-390000000 { +            opp-hz = /bits/ 64 <390000000>; +            opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; +            opp-peak-kBps = <3000000>; +            qcom,opp-acd-level = <0xc0285ffd>; +        }; + +        opp-300000000 { +            opp-hz = /bits/ 64 <300000000>; +            opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>; +            opp-peak-kBps = <2136719>; +            /* Intentionally left out qcom,opp-acd-level property here */ +        }; + +    }; diff --git a/MAINTAINERS b/MAINTAINERS index fe9773af465a..9f3cb7ea2798 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7521,6 +7521,7 @@ S:	Maintained  B:	https://gitlab.freedesktop.org/drm/msm/-/issues  T:	git https://gitlab.freedesktop.org/drm/msm.git  F:	Documentation/devicetree/bindings/display/msm/gpu.yaml +F:	Documentation/devicetree/bindings/opp/opp-v2-qcom-adreno.yaml  F:	drivers/gpu/drm/msm/adreno/  F:	drivers/gpu/drm/msm/msm_gpu.*  F:	drivers/gpu/drm/msm/msm_gpu_devfreq.* diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi index 4936fa5b98ff..8eddf0c96098 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi @@ -3752,60 +3752,83 @@  			};  			gpu_opp_table: opp-table { -				compatible = "operating-points-v2"; +				compatible = "operating-points-v2-adreno", "operating-points-v2"; + +				opp-1250000000 { +					opp-hz = /bits/ 64 <1250000000>; +					opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3>; +					opp-peak-kBps = <16500000>; +					qcom,opp-acd-level = <0xa82a5ffd>; +				}; + +				opp-1175000000 { +					opp-hz = /bits/ 64 <1175000000>; +					opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L2>; +					opp-peak-kBps = <14398438>; +					qcom,opp-acd-level = <0xa82a5ffd>; +				};  				opp-1100000000 {  					opp-hz = /bits/ 64 <1100000000>;  					opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>; -					opp-peak-kBps = <16500000>; +					opp-peak-kBps = <14398438>; +					qcom,opp-acd-level = <0xa82a5ffd>;  				};  				opp-1000000000 {  					opp-hz = /bits/ 64 <1000000000>;  					opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;  					opp-peak-kBps = <14398438>; +					qcom,opp-acd-level = <0xa82b5ffd>;  				};  				opp-925000000 {  					opp-hz = /bits/ 64 <925000000>;  					opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;  					opp-peak-kBps = <14398438>; +					qcom,opp-acd-level = <0xa82b5ffd>;  				};  				opp-800000000 {  					opp-hz = /bits/ 64 <800000000>;  					opp-level = <RPMH_REGULATOR_LEVEL_NOM>;  					opp-peak-kBps = <12449219>; +					qcom,opp-acd-level = <0xa82c5ffd>;  				};  				opp-744000000 {  					opp-hz = /bits/ 64 <744000000>;  					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;  					opp-peak-kBps = <10687500>; +					qcom,opp-acd-level = <0x882e5ffd>;  				};  				opp-687000000 {  					opp-hz = /bits/ 64 <687000000>;  					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;  					opp-peak-kBps = <8171875>; +					qcom,opp-acd-level = <0x882e5ffd>;  				};  				opp-550000000 {  					opp-hz = /bits/ 64 <550000000>;  					opp-level = <RPMH_REGULATOR_LEVEL_SVS>;  					opp-peak-kBps = <6074219>; +					qcom,opp-acd-level = <0xc0285ffd>;  				};  				opp-390000000 {  					opp-hz = /bits/ 64 <390000000>;  					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;  					opp-peak-kBps = <3000000>; +					qcom,opp-acd-level = <0xc0285ffd>;  				};  				opp-300000000 {  					opp-hz = /bits/ 64 <300000000>;  					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;  					opp-peak-kBps = <2136719>; +					qcom,opp-acd-level = <0xc02b5ffd>;  				};  			};  		}; diff --git a/drivers/gpu/drm/ci/build-igt.sh b/drivers/gpu/drm/ci/build-igt.sh index eddb5f782a5e..caa2f4804ed5 100644 --- a/drivers/gpu/drm/ci/build-igt.sh +++ b/drivers/gpu/drm/ci/build-igt.sh @@ -71,4 +71,4 @@ tar -cf artifacts/igt.tar /igt  # Pass needed files to the test stage  S3_ARTIFACT_NAME="igt.tar.gz"  gzip -c artifacts/igt.tar > ${S3_ARTIFACT_NAME} -ci-fairy s3cp --token-file "${S3_JWT_FILE}" ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${KERNEL_ARCH}/${S3_ARTIFACT_NAME} +s3_upload ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${KERNEL_ARCH}/ diff --git a/drivers/gpu/drm/ci/build.sh b/drivers/gpu/drm/ci/build.sh index 284873e94d8d..6fb74c51abe2 100644 --- a/drivers/gpu/drm/ci/build.sh +++ b/drivers/gpu/drm/ci/build.sh @@ -148,13 +148,13 @@ if [[ "$UPLOAD_TO_MINIO" = "1" ]]; then      ls -l "${S3_JWT_FILE}"      for f in $FILES_TO_UPLOAD; do -        ci-fairy s3cp --token-file "${S3_JWT_FILE}" /kernel/$f \ -                https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/$f +        s3_upload /kernel/$f \ +                https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/      done      S3_ARTIFACT_NAME="kernel-files.tar.zst"      tar --zstd -cf $S3_ARTIFACT_NAME install -    ci-fairy s3cp --token-file "${S3_JWT_FILE}" ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/${S3_ARTIFACT_NAME} +    s3_upload ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/      echo "Download vmlinux.xz from https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/vmlinux.xz"  fi diff --git a/drivers/gpu/drm/ci/gitlab-ci.yml b/drivers/gpu/drm/ci/gitlab-ci.yml index 65adcd97e06b..ba75b3a7eca4 100644 --- a/drivers/gpu/drm/ci/gitlab-ci.yml +++ b/drivers/gpu/drm/ci/gitlab-ci.yml @@ -1,6 +1,6 @@  variables:    DRM_CI_PROJECT_PATH: &drm-ci-project-path mesa/mesa -  DRM_CI_COMMIT_SHA: &drm-ci-commit-sha 82ab58f6c6f94fa80ca7e1615146f08356e3ba69 +  DRM_CI_COMMIT_SHA: &drm-ci-commit-sha f73132f1215a37ce8ffc711a0136c90649aaf128    UPSTREAM_REPO: https://gitlab.freedesktop.org/drm/kernel.git    TARGET_BRANCH: drm-next @@ -20,8 +20,10 @@ variables:            rm download-git-cache.sh            set +o xtrace    S3_JWT_FILE: /s3_jwt +  S3_JWT_HEADER_FILE: /s3_jwt_header    S3_JWT_FILE_SCRIPT: |-        echo -n '${S3_JWT}' > '${S3_JWT_FILE}' && +      echo -n "Authorization: Bearer ${S3_JWT}" > '${S3_JWT_HEADER_FILE}' &&        unset CI_JOB_JWT S3_JWT  # Unsetting vulnerable env variables    S3_HOST: s3.freedesktop.org    # This bucket is used to fetch the kernel image @@ -251,7 +253,7 @@ make git archive:      - tar -cvzf ../$CI_PROJECT_NAME.tar.gz .      # Use id_tokens for JWT auth -    - ci-fairy s3cp --token-file "${S3_JWT_FILE}" ../$CI_PROJECT_NAME.tar.gz https://$S3_HOST/${S3_GITCACHE_BUCKET}/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/$CI_PROJECT_NAME.tar.gz +    - s3_upload ../$CI_PROJECT_NAME.tar.gz https://$S3_HOST/${S3_GITCACHE_BUCKET}/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/  # Sanity checks of MR settings and commit logs diff --git a/drivers/gpu/drm/ci/image-tags.yml b/drivers/gpu/drm/ci/image-tags.yml index c04ba0e69935..53fe34b86578 100644 --- a/drivers/gpu/drm/ci/image-tags.yml +++ b/drivers/gpu/drm/ci/image-tags.yml @@ -1,5 +1,5 @@  variables: -   CONTAINER_TAG: "20250307-mesa-uprev" +   CONTAINER_TAG: "20250328-mesa-uprev"     DEBIAN_X86_64_BUILD_BASE_IMAGE: "debian/x86_64_build-base"     DEBIAN_BASE_TAG: "${CONTAINER_TAG}" diff --git a/drivers/gpu/drm/ci/lava-submit.sh b/drivers/gpu/drm/ci/lava-submit.sh index f22720359b33..a1e8b34fb2d4 100755 --- a/drivers/gpu/drm/ci/lava-submit.sh +++ b/drivers/gpu/drm/ci/lava-submit.sh @@ -54,7 +54,7 @@ cp artifacts/ci-common/init-*.sh results/job-rootfs-overlay/  cp "$SCRIPTS_DIR"/setup-test-env.sh results/job-rootfs-overlay/  tar zcf job-rootfs-overlay.tar.gz -C results/job-rootfs-overlay/ . -ci-fairy s3cp --token-file "${S3_JWT_FILE}" job-rootfs-overlay.tar.gz "https://${JOB_ROOTFS_OVERLAY_PATH}" +s3_upload job-rootfs-overlay.tar.gz "https://${JOB_ARTIFACTS_BASE}"  # Prepare env vars for upload.  section_switch variables "Environment variables passed through to device:" diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 974bc7c0ea76..7f127e2ae442 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -104,6 +104,7 @@ config DRM_MSM_DPU  config DRM_MSM_DP  	bool "Enable DisplayPort support in MSM DRM driver"  	depends on DRM_MSM +	select DRM_DISPLAY_HDMI_AUDIO_HELPER  	select RATIONAL  	default y  	help diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 5df20cbeafb8..7a2ada6e2d74 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -48,7 +48,6 @@ msm-display-$(CONFIG_DRM_MSM_MDP4) += \  	disp/mdp4/mdp4_dsi_encoder.o \  	disp/mdp4/mdp4_dtv_encoder.o \  	disp/mdp4/mdp4_lcdc_encoder.o \ -	disp/mdp4/mdp4_lvds_connector.o \  	disp/mdp4/mdp4_lvds_pll.o \  	disp/mdp4/mdp4_irq.o \  	disp/mdp4/mdp4_kms.o \ diff --git a/drivers/gpu/drm/msm/adreno/a2xx_catalog.c b/drivers/gpu/drm/msm/adreno/a2xx_catalog.c index 9ddb7b31fd98..5ddd015f930d 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_catalog.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_catalog.c @@ -45,8 +45,3 @@ static const struct adreno_info a2xx_gpus[] = {  	}  };  DECLARE_ADRENO_GPULIST(a2xx); - -MODULE_FIRMWARE("qcom/leia_pfp_470.fw"); -MODULE_FIRMWARE("qcom/leia_pm4_470.fw"); -MODULE_FIRMWARE("qcom/yamato_pfp.fw"); -MODULE_FIRMWARE("qcom/yamato_pm4.fw"); diff --git a/drivers/gpu/drm/msm/adreno/a3xx_catalog.c b/drivers/gpu/drm/msm/adreno/a3xx_catalog.c index 2eb6c3e93748..1498e6532f62 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_catalog.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_catalog.c @@ -85,8 +85,3 @@ static const struct adreno_info a3xx_gpus[] = {  	}  };  DECLARE_ADRENO_GPULIST(a3xx); - -MODULE_FIRMWARE("qcom/a300_pm4.fw"); -MODULE_FIRMWARE("qcom/a300_pfp.fw"); -MODULE_FIRMWARE("qcom/a330_pm4.fw"); -MODULE_FIRMWARE("qcom/a330_pfp.fw"); diff --git a/drivers/gpu/drm/msm/adreno/a4xx_catalog.c b/drivers/gpu/drm/msm/adreno/a4xx_catalog.c index 93519f807f87..09f9f228b75e 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_catalog.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_catalog.c @@ -45,6 +45,3 @@ static const struct adreno_info a4xx_gpus[] = {  	}  };  DECLARE_ADRENO_GPULIST(a4xx); - -MODULE_FIRMWARE("qcom/a420_pm4.fw"); -MODULE_FIRMWARE("qcom/a420_pfp.fw"); diff --git a/drivers/gpu/drm/msm/adreno/a5xx_catalog.c b/drivers/gpu/drm/msm/adreno/a5xx_catalog.c index 633f31539162..b48a636d8237 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_catalog.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_catalog.c @@ -150,12 +150,3 @@ static const struct adreno_info a5xx_gpus[] = {  	}  };  DECLARE_ADRENO_GPULIST(a5xx); - -MODULE_FIRMWARE("qcom/a530_pm4.fw"); -MODULE_FIRMWARE("qcom/a530_pfp.fw"); -MODULE_FIRMWARE("qcom/a530v3_gpmu.fw2"); -MODULE_FIRMWARE("qcom/a530_zap.mdt"); -MODULE_FIRMWARE("qcom/a530_zap.b00"); -MODULE_FIRMWARE("qcom/a530_zap.b01"); -MODULE_FIRMWARE("qcom/a530_zap.b02"); -MODULE_FIRMWARE("qcom/a540_gpmu.fw2"); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c index 53e2ff4406d8..70f7ad806c34 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c @@ -681,6 +681,7 @@ static const struct adreno_info a6xx_gpus[] = {  			[ADRENO_FW_SQE] = "a630_sqe.fw",  		},  		.gmem = (SZ_128K + SZ_4K), +		.quirks = ADRENO_QUIRK_4GB_VA,  		.inactive_period = DRM_MSM_INACTIVE_PERIOD,  		.init = a6xx_gpu_init,  		.zapfw = "a610_zap.mdt", @@ -713,6 +714,7 @@ static const struct adreno_info a6xx_gpus[] = {  			[ADRENO_FW_GMU] = "a630_gmu.bin",  		},  		.gmem = SZ_512K, +		.quirks = ADRENO_QUIRK_4GB_VA,  		.inactive_period = DRM_MSM_INACTIVE_PERIOD,  		.init = a6xx_gpu_init,  		.zapfw = "a615_zap.mdt", @@ -743,7 +745,8 @@ static const struct adreno_info a6xx_gpus[] = {  		},  		.gmem = SZ_512K,  		.inactive_period = DRM_MSM_INACTIVE_PERIOD, -		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT, +		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT | +			  ADRENO_QUIRK_4GB_VA,  		.init = a6xx_gpu_init,  		.zapfw = "a615_zap.mbn",  		.a6xx = &(const struct a6xx_info) { @@ -769,7 +772,8 @@ static const struct adreno_info a6xx_gpus[] = {  		},  		.gmem = SZ_512K,  		.inactive_period = DRM_MSM_INACTIVE_PERIOD, -		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT, +		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT | +			  ADRENO_QUIRK_4GB_VA,  		.init = a6xx_gpu_init,  		.a6xx = &(const struct a6xx_info) {  			.protect = &a630_protect, @@ -791,6 +795,7 @@ static const struct adreno_info a6xx_gpus[] = {  			[ADRENO_FW_GMU] = "a619_gmu.bin",  		},  		.gmem = SZ_512K, +		.quirks = ADRENO_QUIRK_4GB_VA,  		.inactive_period = DRM_MSM_INACTIVE_PERIOD,  		.init = a6xx_gpu_init,  		.zapfw = "a615_zap.mdt", @@ -815,6 +820,7 @@ static const struct adreno_info a6xx_gpus[] = {  			[ADRENO_FW_GMU] = "a619_gmu.bin",  		},  		.gmem = SZ_512K, +		.quirks = ADRENO_QUIRK_4GB_VA,  		.inactive_period = DRM_MSM_INACTIVE_PERIOD,  		.init = a6xx_gpu_init,  		.zapfw = "a615_zap.mdt", @@ -838,8 +844,9 @@ static const struct adreno_info a6xx_gpus[] = {  			[ADRENO_FW_GMU] = "a619_gmu.bin",  		},  		.gmem = SZ_512K, +		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT | +			  ADRENO_QUIRK_4GB_VA,  		.inactive_period = DRM_MSM_INACTIVE_PERIOD, -		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,  		.init = a6xx_gpu_init,  		.zapfw = "a615_zap.mdt",  		.a6xx = &(const struct a6xx_info) { @@ -874,7 +881,6 @@ static const struct adreno_info a6xx_gpus[] = {  			.gmu_cgc_mode = 0x00020200,  			.prim_fifo_threshold = 0x00010000,  		}, -		.address_space_size = SZ_16G,  		.speedbins = ADRENO_SPEEDBINS(  			{ 0, 0 },  			{ 137, 1 }, @@ -907,7 +913,6 @@ static const struct adreno_info a6xx_gpus[] = {  				{ /* sentinel */ },  			},  		}, -		.address_space_size = SZ_16G,  	}, {  		.chip_ids = ADRENO_CHIP_IDS(  			0x06030001, @@ -920,8 +925,9 @@ static const struct adreno_info a6xx_gpus[] = {  			[ADRENO_FW_GMU] = "a630_gmu.bin",  		},  		.gmem = SZ_1M, +		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT | +			  ADRENO_QUIRK_4GB_VA,  		.inactive_period = DRM_MSM_INACTIVE_PERIOD, -		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,  		.init = a6xx_gpu_init,  		.zapfw = "a630_zap.mdt",  		.a6xx = &(const struct a6xx_info) { @@ -939,8 +945,9 @@ static const struct adreno_info a6xx_gpus[] = {  			[ADRENO_FW_GMU] = "a640_gmu.bin",  		},  		.gmem = SZ_1M, +		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT | +			  ADRENO_QUIRK_4GB_VA,  		.inactive_period = DRM_MSM_INACTIVE_PERIOD, -		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,  		.init = a6xx_gpu_init,  		.zapfw = "a640_zap.mdt",  		.a6xx = &(const struct a6xx_info) { @@ -973,7 +980,6 @@ static const struct adreno_info a6xx_gpus[] = {  			.gmu_cgc_mode = 0x00020202,  			.prim_fifo_threshold = 0x00300200,  		}, -		.address_space_size = SZ_16G,  		.speedbins = ADRENO_SPEEDBINS(  			{ 0, 0 },  			{ 1, 1 }, @@ -1000,7 +1006,6 @@ static const struct adreno_info a6xx_gpus[] = {  			.gmu_cgc_mode = 0x00020000,  			.prim_fifo_threshold = 0x00300200,  		}, -		.address_space_size = SZ_16G,  	}, {  		.chip_ids = ADRENO_CHIP_IDS(0x06060300),  		.family = ADRENO_6XX_GEN4, @@ -1019,7 +1024,6 @@ static const struct adreno_info a6xx_gpus[] = {  			.gmu_cgc_mode = 0x00020200,  			.prim_fifo_threshold = 0x00300200,  		}, -		.address_space_size = SZ_16G,  	}, {  		.chip_ids = ADRENO_CHIP_IDS(0x06030500),  		.family = ADRENO_6XX_GEN4, @@ -1039,7 +1043,6 @@ static const struct adreno_info a6xx_gpus[] = {  			.gmu_cgc_mode = 0x00020202,  			.prim_fifo_threshold = 0x00200200,  		}, -		.address_space_size = SZ_16G,  		.speedbins = ADRENO_SPEEDBINS(  			{ 0,   0 },  			{ 117, 0 }, @@ -1056,8 +1059,9 @@ static const struct adreno_info a6xx_gpus[] = {  			[ADRENO_FW_GMU] = "a640_gmu.bin",  		},  		.gmem = SZ_2M, +		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT | +			  ADRENO_QUIRK_4GB_VA,  		.inactive_period = DRM_MSM_INACTIVE_PERIOD, -		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,  		.init = a6xx_gpu_init,  		.zapfw = "a640_zap.mdt",  		.a6xx = &(const struct a6xx_info) { @@ -1085,22 +1089,10 @@ static const struct adreno_info a6xx_gpus[] = {  			.gmu_cgc_mode = 0x00020200,  			.prim_fifo_threshold = 0x00800200,  		}, -		.address_space_size = SZ_16G,  	}  };  DECLARE_ADRENO_GPULIST(a6xx); -MODULE_FIRMWARE("qcom/a615_zap.mbn"); -MODULE_FIRMWARE("qcom/a619_gmu.bin"); -MODULE_FIRMWARE("qcom/a630_sqe.fw"); -MODULE_FIRMWARE("qcom/a630_gmu.bin"); -MODULE_FIRMWARE("qcom/a630_zap.mbn"); -MODULE_FIRMWARE("qcom/a640_gmu.bin"); -MODULE_FIRMWARE("qcom/a650_gmu.bin"); -MODULE_FIRMWARE("qcom/a650_sqe.fw"); -MODULE_FIRMWARE("qcom/a660_gmu.bin"); -MODULE_FIRMWARE("qcom/a660_sqe.fw"); -  static const struct adreno_reglist a702_hwcg[] = {  	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222 },  	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220 }, @@ -1395,7 +1387,6 @@ static const struct adreno_info a7xx_gpus[] = {  			.pwrup_reglist = &a7xx_pwrup_reglist,  			.gmu_cgc_mode = 0x00020000,  		}, -		.address_space_size = SZ_16G,  		.preempt_record_size = 2860 * SZ_1K,  	}, {  		.chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */ @@ -1429,7 +1420,6 @@ static const struct adreno_info a7xx_gpus[] = {  				{ /* sentinel */ },  			},  		}, -		.address_space_size = SZ_16G,  		.preempt_record_size = 4192 * SZ_1K,  	}, {  		.chip_ids = ADRENO_CHIP_IDS(0x43050c01), /* "C512v2" */ @@ -1451,7 +1441,6 @@ static const struct adreno_info a7xx_gpus[] = {  			.gmu_chipid = 0x7050001,  			.gmu_cgc_mode = 0x00020202,  		}, -		.address_space_size = SZ_256G,  		.preempt_record_size = 4192 * SZ_1K,  	}, {  		.chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */ @@ -1484,7 +1473,6 @@ static const struct adreno_info a7xx_gpus[] = {  				{ /* sentinel */ },  			},  		}, -		.address_space_size = SZ_16G,  		.preempt_record_size = 3572 * SZ_1K,  	}  }; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index c8711938a5f4..38c0f8ef85c3 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -1064,14 +1064,6 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)  	gmu->hung = false; -	/* Notify AOSS about the ACD state (unimplemented for now => disable it) */ -	if (!IS_ERR(gmu->qmp)) { -		ret = qmp_send(gmu->qmp, "{class: gpu, res: acd, val: %d}", -			       0 /* Hardcode ACD to be disabled for now */); -		if (ret) -			dev_err(gmu->dev, "failed to send GPU ACD state\n"); -	} -  	/* Turn on the resources */  	pm_runtime_get_sync(gmu->dev); @@ -1671,6 +1663,75 @@ static int a6xx_gmu_pwrlevels_probe(struct a6xx_gmu *gmu)  	return a6xx_gmu_rpmh_votes_init(gmu);  } +static int a6xx_gmu_acd_probe(struct a6xx_gmu *gmu) +{ +	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); +	struct a6xx_hfi_acd_table *cmd = &gmu->acd_table; +	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; +	struct msm_gpu *gpu = &adreno_gpu->base; +	int ret, i, cmd_idx = 0; +	extern bool disable_acd; + +	/* Skip ACD probe if requested via module param */ +	if (disable_acd) { +		DRM_DEV_ERROR(gmu->dev, "Skipping GPU ACD probe\n"); +		return 0; +	} + +	cmd->version = 1; +	cmd->stride = 1; +	cmd->enable_by_level = 0; + +	/* Skip freq = 0 and parse acd-level for rest of the OPPs */ +	for (i = 1; i < gmu->nr_gpu_freqs; i++) { +		struct dev_pm_opp *opp; +		struct device_node *np; +		unsigned long freq; +		u32 val; + +		freq = gmu->gpu_freqs[i]; +		opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, freq, true); +		np = dev_pm_opp_get_of_node(opp); + +		ret = of_property_read_u32(np, "qcom,opp-acd-level", &val); +		of_node_put(np); +		dev_pm_opp_put(opp); +		if (ret == -EINVAL) +			continue; +		else if (ret) { +			DRM_DEV_ERROR(gmu->dev, "Unable to read acd level for freq %lu\n", freq); +			return ret; +		} + +		cmd->enable_by_level |= BIT(i); +		cmd->data[cmd_idx++] = val; +	} + +	cmd->num_levels = cmd_idx; + +	/* It is a problem if qmp node is unavailable when ACD is required */ +	if (cmd->enable_by_level && IS_ERR_OR_NULL(gmu->qmp)) { +		DRM_DEV_ERROR(gmu->dev, "Unable to send ACD state to AOSS\n"); +		return -EINVAL; +	} + +	/* Otherwise, nothing to do if qmp is unavailable */ +	if (IS_ERR_OR_NULL(gmu->qmp)) +		return 0; + +	/* +	 * Notify AOSS about the ACD state. AOSS is supposed to assume that ACD is disabled on +	 * system reset. So it is harmless if we couldn't notify 'OFF' state +	 */ +	ret = qmp_send(gmu->qmp, "{class: gpu, res: acd, val: %d}", !!cmd->enable_by_level); +	if (ret && cmd->enable_by_level) { +		DRM_DEV_ERROR(gmu->dev, "Failed to send ACD state to AOSS\n"); +		return ret; +	} + +	return 0; +} +  static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu)  {  	int ret = devm_clk_bulk_get_all(gmu->dev, &gmu->clocks); @@ -1989,10 +2050,11 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)  		goto detach_cxpd;  	} +	/* Other errors are handled during GPU ACD probe */  	gmu->qmp = qmp_get(gmu->dev); -	if (IS_ERR(gmu->qmp) && adreno_is_a7xx(adreno_gpu)) { -		ret = PTR_ERR(gmu->qmp); -		goto remove_device_link; +	if (PTR_ERR_OR_ZERO(gmu->qmp) == -EPROBE_DEFER) { +		ret = -EPROBE_DEFER; +		goto detach_gxpd;  	}  	init_completion(&gmu->pd_gate); @@ -2008,6 +2070,10 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)  	/* Get the power levels for the GMU and GPU */  	a6xx_gmu_pwrlevels_probe(gmu); +	ret = a6xx_gmu_acd_probe(gmu); +	if (ret) +		goto detach_gxpd; +  	/* Set up the HFI queues */  	a6xx_hfi_init(gmu); @@ -2018,7 +2084,13 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)  	return 0; -remove_device_link: +detach_gxpd: +	if (!IS_ERR_OR_NULL(gmu->gxpd)) +		dev_pm_domain_detach(gmu->gxpd, false); + +	if (!IS_ERR_OR_NULL(gmu->qmp)) +		qmp_put(gmu->qmp); +  	device_link_del(link);  detach_cxpd: diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 0c888b326cfb..b2d4489b4024 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -93,6 +93,7 @@ struct a6xx_gmu {  	int nr_gpu_freqs;  	unsigned long gpu_freqs[GMU_MAX_GX_FREQS];  	u32 gx_arc_votes[GMU_MAX_GX_FREQS]; +	struct a6xx_hfi_acd_table acd_table;  	int nr_gpu_bws;  	unsigned long gpu_bw_table[GMU_MAX_GX_FREQS]; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 242d02d48c0c..bf3758f010f4 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -655,7 +655,6 @@ static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)  	if (adreno_is_7c3(gpu)) {  		gpu->ubwc_config.highest_bank_bit = 14;  		gpu->ubwc_config.amsbc = 1; -		gpu->ubwc_config.rgb565_predicator = 1;  		gpu->ubwc_config.uavflagprd_inv = 2;  		gpu->ubwc_config.macrotile_mode = 1;  	} @@ -2268,7 +2267,7 @@ a6xx_create_private_address_space(struct msm_gpu *gpu)  		return ERR_CAST(mmu);  	return msm_gem_address_space_create(mmu, -		"gpu", 0x100000000ULL, +		"gpu", ADRENO_VM_START,  		adreno_private_address_space_size(gpu));  } diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c index 0989aee3dd2c..8e69b1e84657 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c @@ -100,16 +100,14 @@ static int a6xx_hfi_queue_write(struct a6xx_gmu *gmu,  	return 0;  } -static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum, -		u32 *payload, u32 payload_size) +static int a6xx_hfi_wait_for_msg_interrupt(struct a6xx_gmu *gmu, u32 id, u32 seqnum)  { -	struct a6xx_hfi_queue *queue = &gmu->queues[HFI_RESPONSE_QUEUE]; -	u32 val;  	int ret; +	u32 val;  	/* Wait for a response */  	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO, val, -		val & A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ, 100, 5000); +		val & A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ, 100, 1000000);  	if (ret) {  		DRM_DEV_ERROR(gmu->dev, @@ -122,6 +120,19 @@ static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum,  	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR,  		A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ); +	return 0; +} + +static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum, +		u32 *payload, u32 payload_size) +{ +	struct a6xx_hfi_queue *queue = &gmu->queues[HFI_RESPONSE_QUEUE]; +	int ret; + +	ret = a6xx_hfi_wait_for_msg_interrupt(gmu, id, seqnum); +	if (ret) +		return ret; +  	for (;;) {  		struct a6xx_hfi_msg_response resp; @@ -129,12 +140,18 @@ static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum,  		ret = a6xx_hfi_queue_read(gmu, queue, (u32 *) &resp,  			sizeof(resp) >> 2); -		/* If the queue is empty our response never made it */ +		/* If the queue is empty, there may have been previous missed +		 * responses that preceded the response to our packet. Wait +		 * further before we give up. +		 */  		if (!ret) { -			DRM_DEV_ERROR(gmu->dev, -				"The HFI response queue is unexpectedly empty\n"); - -			return -ENOENT; +			ret = a6xx_hfi_wait_for_msg_interrupt(gmu, id, seqnum); +			if (ret) { +				DRM_DEV_ERROR(gmu->dev, +					"The HFI response queue is unexpectedly empty\n"); +				return ret; +			} +			continue;  		}  		if (HFI_HEADER_ID(resp.header) == HFI_F2H_MSG_ERROR) { @@ -748,6 +765,38 @@ send:  		NULL, 0);  } +#define HFI_FEATURE_ACD 12 + +static int a6xx_hfi_enable_acd(struct a6xx_gmu *gmu) +{ +	struct a6xx_hfi_acd_table *acd_table = &gmu->acd_table; +	struct a6xx_hfi_msg_feature_ctrl msg = { +		.feature = HFI_FEATURE_ACD, +		.enable = 1, +		.data = 0, +	}; +	int ret; + +	if (!acd_table->enable_by_level) +		return 0; + +	/* Enable ACD feature at GMU */ +	ret = a6xx_hfi_send_msg(gmu, HFI_H2F_FEATURE_CTRL, &msg, sizeof(msg), NULL, 0); +	if (ret) { +		DRM_DEV_ERROR(gmu->dev, "Unable to enable ACD (%d)\n", ret); +		return ret; +	} + +	/* Send ACD table to GMU */ +	ret = a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_ACD, acd_table, sizeof(*acd_table), NULL, 0); +	if (ret) { +		DRM_DEV_ERROR(gmu->dev, "Unable to ACD table (%d)\n", ret); +		return ret; +	} + +	return 0; +} +  static int a6xx_hfi_send_test(struct a6xx_gmu *gmu)  {  	struct a6xx_hfi_msg_test msg = { 0 }; @@ -845,6 +894,10 @@ int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)  	if (ret)  		return ret; +	ret = a6xx_hfi_enable_acd(gmu); +	if (ret) +		return ret; +  	ret = a6xx_hfi_send_core_fw_start(gmu);  	if (ret)  		return ret; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.h b/drivers/gpu/drm/msm/adreno/a6xx_hfi.h index 52ba4a07d7b9..653ef720e2da 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.h @@ -151,12 +151,33 @@ struct a6xx_hfi_msg_test {  	u32 header;  }; +#define HFI_H2F_MSG_ACD 7 +#define MAX_ACD_STRIDE 2 + +struct a6xx_hfi_acd_table { +	u32 header; +	u32 version; +	u32 enable_by_level; +	u32 stride; +	u32 num_levels; +	u32 data[16 * MAX_ACD_STRIDE]; +}; +  #define HFI_H2F_MSG_START 10  struct a6xx_hfi_msg_start {  	u32 header;  }; +#define HFI_H2F_FEATURE_CTRL 11 + +struct a6xx_hfi_msg_feature_ctrl { +	u32 header; +	u32 feature; +	u32 enable; +	u32 data; +}; +  #define HFI_H2F_MSG_CORE_FW_START 14  struct a6xx_hfi_msg_core_fw_start { diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 236b25c094cd..f5e1490d07c1 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -24,6 +24,10 @@ int enable_preemption = -1;  MODULE_PARM_DESC(enable_preemption, "Enable preemption (A7xx only) (1=on , 0=disable, -1=auto (default))");  module_param(enable_preemption, int, 0600); +bool disable_acd; +MODULE_PARM_DESC(disable_acd, "Forcefully disable GPU ACD"); +module_param_unsafe(disable_acd, bool, 0400); +  extern const struct adreno_gpulist a2xx_gpulist;  extern const struct adreno_gpulist a3xx_gpulist;  extern const struct adreno_gpulist a4xx_gpulist; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 26db1f4b5fb9..2348ffb35f7e 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -236,14 +236,27 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu,  u64 adreno_private_address_space_size(struct msm_gpu *gpu)  {  	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); +	struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(&gpu->pdev->dev); +	const struct io_pgtable_cfg *ttbr1_cfg;  	if (address_space_size)  		return address_space_size; -	if (adreno_gpu->info->address_space_size) -		return adreno_gpu->info->address_space_size; +	if (adreno_gpu->info->quirks & ADRENO_QUIRK_4GB_VA) +		return SZ_4G; -	return SZ_4G; +	if (!adreno_smmu || !adreno_smmu->get_ttbr1_cfg) +		return SZ_4G; + +	ttbr1_cfg = adreno_smmu->get_ttbr1_cfg(adreno_smmu->cookie); + +	/* +	 * Userspace VM is actually using TTBR0, but both are the same size, +	 * with b48 (sign bit) selecting which TTBRn to use.  So if IAS is +	 * 48, the total (kernel+user) address space size is effectively +	 * 49 bits.  But what userspace is control of is the lower 48. +	 */ +	return BIT(ttbr1_cfg->ias) - ADRENO_VM_START;  }  #define ARM_SMMU_FSR_TF                 BIT(1) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 92caba3584da..a8f4bf416e64 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -57,6 +57,7 @@ enum adreno_family {  #define ADRENO_QUIRK_HAS_HW_APRIV		BIT(3)  #define ADRENO_QUIRK_HAS_CACHED_COHERENT	BIT(4)  #define ADRENO_QUIRK_PREEMPTION			BIT(5) +#define ADRENO_QUIRK_4GB_VA			BIT(6)  /* Helper for formating the chip_id in the way that userspace tools like   * crashdec expect. @@ -104,7 +105,6 @@ struct adreno_info {  	union {  		const struct a6xx_info *a6xx;  	}; -	u64 address_space_size;  	/**  	 * @speedbins: Optional table of fuse to speedbin mappings  	 * @@ -578,6 +578,8 @@ static inline int adreno_is_a7xx(struct adreno_gpu *gpu)  	       adreno_is_a740_family(gpu);  } +/* Put vm_start above 32b to catch issues with not setting xyz_BASE_HI */ +#define ADRENO_VM_START 0x100000000ULL  u64 adreno_private_address_space_size(struct msm_gpu *gpu);  int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx,  		     uint32_t param, uint64_t *value, uint32_t *len); diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h index 6ac97c378056..ffc4d4257ae5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h @@ -27,17 +27,16 @@ static const struct dpu_mdp_cfg sm8650_mdp = {  	},  }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */  static const struct dpu_ctl_cfg sm8650_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x15000, .len = 0x1000, -		.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = CTL_SM8550_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),  	}, {  		.name = "ctl_1", .id = CTL_1,  		.base = 0x16000, .len = 0x1000, -		.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = CTL_SM8550_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h index ad60089f18ea..39027a21c6fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h @@ -100,14 +100,12 @@ static const struct dpu_pingpong_cfg msm8937_pp[] = {  	{  		.name = "pingpong_0", .id = PINGPONG_0,  		.base = 0x70000, .len = 0xd4, -		.features = PINGPONG_MSM8996_MASK,  		.sblk = &msm8996_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),  	}, {  		.name = "pingpong_1", .id = PINGPONG_1,  		.base = 0x70800, .len = 0xd4, -		.features = PINGPONG_MSM8996_MASK,  		.sblk = &msm8996_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h index a1cf89a0a42d..8d1b43ea1663 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h @@ -93,7 +93,6 @@ static const struct dpu_pingpong_cfg msm8917_pp[] = {  	{  		.name = "pingpong_0", .id = PINGPONG_0,  		.base = 0x70000, .len = 0xd4, -		.features = PINGPONG_MSM8996_MASK,  		.sblk = &msm8996_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h index eea9b80e2287..16c12499b24b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h @@ -100,14 +100,12 @@ static const struct dpu_pingpong_cfg msm8953_pp[] = {  	{  		.name = "pingpong_0", .id = PINGPONG_0,  		.base = 0x70000, .len = 0xd4, -		.features = PINGPONG_MSM8996_MASK,  		.sblk = &msm8996_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),  	}, {  		.name = "pingpong_1", .id = PINGPONG_1,  		.base = 0x70800, .len = 0xd4, -		.features = PINGPONG_MSM8996_MASK,  		.sblk = &msm8996_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h index ae18a354e5d2..91f514d28ac6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h @@ -181,15 +181,15 @@ static const struct dpu_pingpong_cfg msm8996_pp[] = {  	{  		.name = "pingpong_0", .id = PINGPONG_0,  		.base = 0x70000, .len = 0xd4, -		.features = PINGPONG_MSM8996_TE2_MASK, -		.sblk = &msm8996_pp_sblk_te, +		.features = PINGPONG_MSM8996_MASK, +		.sblk = &msm8996_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),  	}, {  		.name = "pingpong_1", .id = PINGPONG_1,  		.base = 0x70800, .len = 0xd4, -		.features = PINGPONG_MSM8996_TE2_MASK, -		.sblk = &msm8996_pp_sblk_te, +		.features = PINGPONG_MSM8996_MASK, +		.sblk = &msm8996_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),  	}, { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 746474679ef5..413cd59dc0c4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -170,15 +170,15 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = {  	{  		.name = "pingpong_0", .id = PINGPONG_0,  		.base = 0x70000, .len = 0xd4, -		.features = PINGPONG_SDM845_TE2_MASK, -		.sblk = &sdm845_pp_sblk_te, +		.features = PINGPONG_SDM845_MASK, +		.sblk = &sdm845_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),  	}, {  		.name = "pingpong_1", .id = PINGPONG_1,  		.base = 0x70800, .len = 0xd4, -		.features = PINGPONG_SDM845_TE2_MASK, -		.sblk = &sdm845_pp_sblk_te, +		.features = PINGPONG_SDM845_MASK, +		.sblk = &sdm845_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),  	}, { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h index bb89da0a481d..b2eb7ca699e3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h @@ -141,15 +141,15 @@ static const struct dpu_pingpong_cfg sdm660_pp[] = {  	{  		.name = "pingpong_0", .id = PINGPONG_0,  		.base = 0x70000, .len = 0xd4, -		.features = PINGPONG_SDM845_TE2_MASK, -		.sblk = &sdm845_pp_sblk_te, +		.features = PINGPONG_SDM845_MASK, +		.sblk = &sdm845_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),  	}, {  		.name = "pingpong_1", .id = PINGPONG_1,  		.base = 0x70800, .len = 0xd4, -		.features = PINGPONG_SDM845_TE2_MASK, -		.sblk = &sdm845_pp_sblk_te, +		.features = PINGPONG_SDM845_MASK, +		.sblk = &sdm845_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),  	}, { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h index 7caf876ca3e3..85e121ad84a0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h @@ -115,14 +115,14 @@ static const struct dpu_pingpong_cfg sdm630_pp[] = {  	{  		.name = "pingpong_0", .id = PINGPONG_0,  		.base = 0x70000, .len = 0xd4, -		.features = PINGPONG_SDM845_TE2_MASK, -		.sblk = &sdm845_pp_sblk_te, +		.features = BIT(DPU_PINGPONG_DITHER), +		.sblk = &sdm845_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),  	}, {  		.name = "pingpong_2", .id = PINGPONG_2,  		.base = 0x71000, .len = 0xd4, -		.features = PINGPONG_SDM845_MASK, +		.features = BIT(DPU_PINGPONG_DITHER),  		.sblk = &sdm845_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index ab7b4822ca63..49363d7d5b93 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -194,15 +194,15 @@ static const struct dpu_pingpong_cfg sdm845_pp[] = {  	{  		.name = "pingpong_0", .id = PINGPONG_0,  		.base = 0x70000, .len = 0xd4, -		.features = PINGPONG_SDM845_TE2_MASK, -		.sblk = &sdm845_pp_sblk_te, +		.features = PINGPONG_SDM845_MASK, +		.sblk = &sdm845_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),  	}, {  		.name = "pingpong_1", .id = PINGPONG_1,  		.base = 0x70800, .len = 0xd4, -		.features = PINGPONG_SDM845_TE2_MASK, -		.sblk = &sdm845_pp_sblk_te, +		.features = PINGPONG_SDM845_MASK, +		.sblk = &sdm845_pp_sblk,  		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),  		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),  	}, { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 979527d98fbc..08d38e1d420c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -37,17 +37,16 @@ static const struct dpu_mdp_cfg sm8150_mdp = {  	},  }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */  static const struct dpu_ctl_cfg sm8150_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x1000, .len = 0x1e0, -		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = BIT(DPU_CTL_ACTIVE_CFG),  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),  	}, {  		.name = "ctl_1", .id = CTL_1,  		.base = 0x1200, .len = 0x1e0, -		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = BIT(DPU_CTL_ACTIVE_CFG),  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, @@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {  	{  		.name = "sspp_0", .id = SSPP_VIG0,  		.base = 0x4000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_1_4,  		.xin_id = 0,  		.type = SSPP_TYPE_VIG, @@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {  	}, {  		.name = "sspp_1", .id = SSPP_VIG1,  		.base = 0x6000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_1_4,  		.xin_id = 4,  		.type = SSPP_TYPE_VIG, @@ -92,7 +91,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {  	}, {  		.name = "sspp_2", .id = SSPP_VIG2,  		.base = 0x8000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_1_4,  		.xin_id = 8,  		.type = SSPP_TYPE_VIG, @@ -100,7 +99,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {  	}, {  		.name = "sspp_3", .id = SSPP_VIG3,  		.base = 0xa000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_1_4,  		.xin_id = 12,  		.type = SSPP_TYPE_VIG, @@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {  	}, {  		.name = "sspp_8", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x1f0, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA, @@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {  	}, {  		.name = "sspp_9", .id = SSPP_DMA1,  		.base = 0x26000, .len = 0x1f0, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 5,  		.type = SSPP_TYPE_DMA, @@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {  	}, {  		.name = "sspp_10", .id = SSPP_DMA2,  		.base = 0x28000, .len = 0x1f0, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 9,  		.type = SSPP_TYPE_DMA, @@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {  	}, {  		.name = "sspp_11", .id = SSPP_DMA3,  		.base = 0x2a000, .len = 0x1f0, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 13,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index d76b8992a6c1..d6f8b1030c68 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -41,12 +41,12 @@ static const struct dpu_ctl_cfg sc8180x_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x1000, .len = 0x1e0, -		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = BIT(DPU_CTL_ACTIVE_CFG),  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),  	}, {  		.name = "ctl_1", .id = CTL_1,  		.base = 0x1200, .len = 0x1e0, -		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = BIT(DPU_CTL_ACTIVE_CFG),  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, @@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {  	{  		.name = "sspp_0", .id = SSPP_VIG0,  		.base = 0x4000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_1_4,  		.xin_id = 0,  		.type = SSPP_TYPE_VIG, @@ -83,7 +83,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {  	}, {  		.name = "sspp_1", .id = SSPP_VIG1,  		.base = 0x6000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_1_4,  		.xin_id = 4,  		.type = SSPP_TYPE_VIG, @@ -91,7 +91,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {  	}, {  		.name = "sspp_2", .id = SSPP_VIG2,  		.base = 0x8000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_1_4,  		.xin_id = 8,  		.type = SSPP_TYPE_VIG, @@ -99,7 +99,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {  	}, {  		.name = "sspp_3", .id = SSPP_VIG3,  		.base = 0xa000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_1_4,  		.xin_id = 12,  		.type = SSPP_TYPE_VIG, @@ -107,7 +107,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {  	}, {  		.name = "sspp_8", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x1f0, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA, @@ -115,7 +115,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {  	}, {  		.name = "sspp_9", .id = SSPP_DMA1,  		.base = 0x26000, .len = 0x1f0, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 5,  		.type = SSPP_TYPE_DMA, @@ -123,7 +123,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {  	}, {  		.name = "sspp_10", .id = SSPP_DMA2,  		.base = 0x28000, .len = 0x1f0, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 9,  		.type = SSPP_TYPE_DMA, @@ -131,7 +131,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {  	}, {  		.name = "sspp_11", .id = SSPP_DMA3,  		.base = 0x2a000, .len = 0x1f0, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 13,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h index 83db11339b29..71ba48b05656 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h @@ -38,12 +38,12 @@ static const struct dpu_ctl_cfg sm7150_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x1000, .len = 0x1e0, -		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = BIT(DPU_CTL_ACTIVE_CFG),  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),  	}, {  		.name = "ctl_1", .id = CTL_1,  		.base = 0x1200, .len = 0x1e0, -		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = BIT(DPU_CTL_ACTIVE_CFG),  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, @@ -72,7 +72,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = {  	{  		.name = "sspp_0", .id = SSPP_VIG0,  		.base = 0x4000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_2_4,  		.xin_id = 0,  		.type = SSPP_TYPE_VIG, @@ -80,7 +80,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = {  	}, {  		.name = "sspp_1", .id = SSPP_VIG1,  		.base = 0x6000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_2_4,  		.xin_id = 4,  		.type = SSPP_TYPE_VIG, @@ -88,7 +88,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = {  	}, {  		.name = "sspp_2", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x1f0, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA, @@ -96,7 +96,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = {  	}, {  		.name = "sspp_9", .id = SSPP_DMA1,  		.base = 0x26000, .len = 0x1f0, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 5,  		.type = SSPP_TYPE_DMA, @@ -104,7 +104,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = {  	}, {  		.name = "sspp_10", .id = SSPP_DMA2,  		.base = 0x28000, .len = 0x1f0, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 9,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h index d3d3a34d0b45..fcfb3774f7a1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h @@ -69,7 +69,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = {  	{  		.name = "sspp_0", .id = SSPP_VIG0,  		.base = 0x4000, .len = 0x1f0, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_2_4,  		.xin_id = 0,  		.type = SSPP_TYPE_VIG, @@ -77,7 +77,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = {  	}, {  		.name = "sspp_8", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x1f0, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA, @@ -85,7 +85,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = {  	}, {  		.name = "sspp_9", .id = SSPP_DMA1,  		.base = 0x26000, .len = 0x1f0, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 5,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index 47e01c3c242f..a86fdb33ebdd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sm8250_mdp = {  	},  }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */  static const struct dpu_ctl_cfg sm8250_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x1000, .len = 0x1e0, -		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = BIT(DPU_CTL_ACTIVE_CFG),  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),  	}, {  		.name = "ctl_1", .id = CTL_1,  		.base = 0x1200, .len = 0x1e0, -		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = BIT(DPU_CTL_ACTIVE_CFG),  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index 040c94c0bb66..842fcc5887fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -51,7 +51,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {  	{  		.name = "sspp_0", .id = SSPP_VIG0,  		.base = 0x4000, .len = 0x1f8, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_0,  		.xin_id = 0,  		.type = SSPP_TYPE_VIG, @@ -59,7 +59,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {  	}, {  		.name = "sspp_8", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x1f8, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA, @@ -67,7 +67,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {  	}, {  		.name = "sspp_9", .id = SSPP_DMA1,  		.base = 0x26000, .len = 0x1f8, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 5,  		.type = SSPP_TYPE_DMA, @@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {  	}, {  		.name = "sspp_10", .id = SSPP_DMA2,  		.base = 0x28000, .len = 0x1f8, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 9,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h index 43f64a005f5a..c5fd89dd7c89 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h @@ -38,7 +38,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = {  	{  		.name = "sspp_0", .id = SSPP_VIG0,  		.base = 0x4000, .len = 0x1f8, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_0,  		.xin_id = 0,  		.type = SSPP_TYPE_VIG, @@ -46,7 +46,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = {  	}, {  		.name = "sspp_8", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x1f8, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h index 397278ba999b..a234bb289d24 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h @@ -59,7 +59,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = {  	{  		.name = "sspp_0", .id = SSPP_VIG0,  		.base = 0x4000, .len = 0x1f8, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_0,  		.xin_id = 0,  		.type = SSPP_TYPE_VIG, @@ -67,7 +67,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = {  	}, {  		.name = "sspp_8", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x1f8, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA, @@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = {  	}, {  		.name = "sspp_9", .id = SSPP_DMA1,  		.base = 0x26000, .len = 0x1f8, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 5,  		.type = SSPP_TYPE_DMA, @@ -83,7 +83,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = {  	}, {  		.name = "sspp_10", .id = SSPP_DMA2,  		.base = 0x28000, .len = 0x1f8, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 9,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h index 3cbb2fe8aba2..53f3be28f6f6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h @@ -46,7 +46,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = {  	}, {  		.name = "sspp_8", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x1f8, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h index a06c8634d2d7..3a3bc8e429be 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h @@ -39,7 +39,7 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = {  	{  		.name = "sspp_0", .id = SSPP_VIG0,  		.base = 0x4000, .len = 0x1f8, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_0,  		.xin_id = 0,  		.type = SSPP_TYPE_VIG, @@ -47,7 +47,7 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = {  	}, {  		.name = "sspp_8", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x1f8, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_NO_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 0c860e804cab..90e86063a372 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sm8350_mdp = {  	},  }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */  static const struct dpu_ctl_cfg sm8350_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x15000, .len = 0x1e8, -		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, +		.features = CTL_SC7280_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),  	}, {  		.name = "ctl_1", .id = CTL_1,  		.base = 0x16000, .len = 0x1e8, -		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, +		.features = CTL_SC7280_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index fcee1c3665f8..139f11321fea 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sc8280xp_mdp = {  	},  }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */  static const struct dpu_ctl_cfg sc8280xp_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x15000, .len = 0x204, -		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, +		.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 = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, +		.features = CTL_SC7280_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, @@ -74,7 +73,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {  	{  		.name = "sspp_0", .id = SSPP_VIG0,  		.base = 0x4000, .len = 0x2ac, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_0,  		.xin_id = 0,  		.type = SSPP_TYPE_VIG, @@ -82,7 +81,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {  	}, {  		.name = "sspp_1", .id = SSPP_VIG1,  		.base = 0x6000, .len = 0x2ac, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_0,  		.xin_id = 4,  		.type = SSPP_TYPE_VIG, @@ -90,7 +89,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {  	}, {  		.name = "sspp_2", .id = SSPP_VIG2,  		.base = 0x8000, .len = 0x2ac, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_0,  		.xin_id = 8,  		.type = SSPP_TYPE_VIG, @@ -98,7 +97,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {  	}, {  		.name = "sspp_3", .id = SSPP_VIG3,  		.base = 0xa000, .len = 0x2ac, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_0,  		.xin_id = 12,  		.type = SSPP_TYPE_VIG, @@ -106,7 +105,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {  	}, {  		.name = "sspp_8", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x2ac, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA, @@ -114,7 +113,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {  	}, {  		.name = "sspp_9", .id = SSPP_DMA1,  		.base = 0x26000, .len = 0x2ac, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 5,  		.type = SSPP_TYPE_DMA, @@ -122,7 +121,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {  	}, {  		.name = "sspp_10", .id = SSPP_DMA2,  		.base = 0x28000, .len = 0x2ac, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 9,  		.type = SSPP_TYPE_DMA, @@ -130,7 +129,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {  	}, {  		.name = "sspp_11", .id = SSPP_DMA3,  		.base = 0x2a000, .len = 0x2ac, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 13,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 19b2ee8bbd5f..461294143a90 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -36,17 +36,16 @@ static const struct dpu_mdp_cfg sm8450_mdp = {  	},  }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */  static const struct dpu_ctl_cfg sm8450_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x15000, .len = 0x204, -		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, +		.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 = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, +		.features = CTL_SC7280_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h index 4d96ce71746f..c248b3b55c41 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h @@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sa8775p_mdp = {  	},  }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */  static const struct dpu_ctl_cfg sa8775p_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x15000, .len = 0x204, -		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, +		.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 = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, +		.features = CTL_SC7280_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h index 24f988465bf6..59c7fdf28e89 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -27,17 +27,16 @@ static const struct dpu_mdp_cfg sm8550_mdp = {  	},  }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */  static const struct dpu_ctl_cfg sm8550_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x15000, .len = 0x290, -		.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = CTL_SM8550_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),  	}, {  		.name = "ctl_1", .id = CTL_1,  		.base = 0x16000, .len = 0x290, -		.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = CTL_SM8550_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, @@ -66,70 +65,70 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {  	{  		.name = "sspp_0", .id = SSPP_VIG0,  		.base = 0x4000, .len = 0x344, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_2,  		.xin_id = 0,  		.type = SSPP_TYPE_VIG,  	}, {  		.name = "sspp_1", .id = SSPP_VIG1,  		.base = 0x6000, .len = 0x344, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_2,  		.xin_id = 4,  		.type = SSPP_TYPE_VIG,  	}, {  		.name = "sspp_2", .id = SSPP_VIG2,  		.base = 0x8000, .len = 0x344, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_2,  		.xin_id = 8,  		.type = SSPP_TYPE_VIG,  	}, {  		.name = "sspp_3", .id = SSPP_VIG3,  		.base = 0xa000, .len = 0x344, -		.features = VIG_SDM845_MASK, +		.features = VIG_SDM845_MASK_SDMA,  		.sblk = &dpu_vig_sblk_qseed3_3_2,  		.xin_id = 12,  		.type = SSPP_TYPE_VIG,  	}, {  		.name = "sspp_8", .id = SSPP_DMA0,  		.base = 0x24000, .len = 0x344, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 1,  		.type = SSPP_TYPE_DMA,  	}, {  		.name = "sspp_9", .id = SSPP_DMA1,  		.base = 0x26000, .len = 0x344, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 5,  		.type = SSPP_TYPE_DMA,  	}, {  		.name = "sspp_10", .id = SSPP_DMA2,  		.base = 0x28000, .len = 0x344, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 9,  		.type = SSPP_TYPE_DMA,  	}, {  		.name = "sspp_11", .id = SSPP_DMA3,  		.base = 0x2a000, .len = 0x344, -		.features = DMA_SDM845_MASK, +		.features = DMA_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 13,  		.type = SSPP_TYPE_DMA,  	}, {  		.name = "sspp_12", .id = SSPP_DMA4,  		.base = 0x2c000, .len = 0x344, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 14,  		.type = SSPP_TYPE_DMA,  	}, {  		.name = "sspp_13", .id = SSPP_DMA5,  		.base = 0x2e000, .len = 0x344, -		.features = DMA_CURSOR_SDM845_MASK, +		.features = DMA_CURSOR_SDM845_MASK_SDMA,  		.sblk = &dpu_dma_sblk,  		.xin_id = 15,  		.type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h new file mode 100644 index 000000000000..5667d055fbd1 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h @@ -0,0 +1,433 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_9_1_SAR2130P_H +#define _DPU_9_1_SAR2130P_H + +static const struct dpu_caps sar2130p_dpu_caps = { +	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, +	.max_mixer_blendstages = 0xb, +	.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_mdp_cfg sar2130p_mdp = { +	.name = "top_0", +	.base = 0, .len = 0x494, +	.features = BIT(DPU_MDP_PERIPH_0_REMOVED), +	.clk_ctrls = { +		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, +	}, +}; + +static const struct dpu_ctl_cfg sar2130p_ctl[] = { +	{ +		.name = "ctl_0", .id = CTL_0, +		.base = 0x15000, .len = 0x290, +		.features = CTL_SM8550_MASK, +		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), +	}, { +		.name = "ctl_1", .id = CTL_1, +		.base = 0x16000, .len = 0x290, +		.features = CTL_SM8550_MASK, +		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), +	}, { +		.name = "ctl_2", .id = CTL_2, +		.base = 0x17000, .len = 0x290, +		.features = CTL_SM8550_MASK, +		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), +	}, { +		.name = "ctl_3", .id = CTL_3, +		.base = 0x18000, .len = 0x290, +		.features = CTL_SM8550_MASK, +		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), +	}, { +		.name = "ctl_4", .id = CTL_4, +		.base = 0x19000, .len = 0x290, +		.features = CTL_SM8550_MASK, +		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), +	}, { +		.name = "ctl_5", .id = CTL_5, +		.base = 0x1a000, .len = 0x290, +		.features = CTL_SM8550_MASK, +		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), +	}, +}; + +static const struct dpu_sspp_cfg sar2130p_sspp[] = { +	{ +		.name = "sspp_0", .id = SSPP_VIG0, +		.base = 0x4000, .len = 0x344, +		.features = VIG_SDM845_MASK_SDMA, +		.sblk = &dpu_vig_sblk_qseed3_3_2, +		.xin_id = 0, +		.type = SSPP_TYPE_VIG, +	}, { +		.name = "sspp_1", .id = SSPP_VIG1, +		.base = 0x6000, .len = 0x344, +		.features = VIG_SDM845_MASK_SDMA, +		.sblk = &dpu_vig_sblk_qseed3_3_2, +		.xin_id = 4, +		.type = SSPP_TYPE_VIG, +	}, { +		.name = "sspp_2", .id = SSPP_VIG2, +		.base = 0x8000, .len = 0x344, +		.features = VIG_SDM845_MASK_SDMA, +		.sblk = &dpu_vig_sblk_qseed3_3_2, +		.xin_id = 8, +		.type = SSPP_TYPE_VIG, +	}, { +		.name = "sspp_3", .id = SSPP_VIG3, +		.base = 0xa000, .len = 0x344, +		.features = VIG_SDM845_MASK_SDMA, +		.sblk = &dpu_vig_sblk_qseed3_3_2, +		.xin_id = 12, +		.type = SSPP_TYPE_VIG, +	}, { +		.name = "sspp_8", .id = SSPP_DMA0, +		.base = 0x24000, .len = 0x344, +		.features = DMA_SDM845_MASK_SDMA, +		.sblk = &dpu_dma_sblk, +		.xin_id = 1, +		.type = SSPP_TYPE_DMA, +	}, { +		.name = "sspp_9", .id = SSPP_DMA1, +		.base = 0x26000, .len = 0x344, +		.features = DMA_SDM845_MASK_SDMA, +		.sblk = &dpu_dma_sblk, +		.xin_id = 5, +		.type = SSPP_TYPE_DMA, +	}, { +		.name = "sspp_10", .id = SSPP_DMA2, +		.base = 0x28000, .len = 0x344, +		.features = DMA_SDM845_MASK_SDMA, +		.sblk = &dpu_dma_sblk, +		.xin_id = 9, +		.type = SSPP_TYPE_DMA, +	}, { +		.name = "sspp_11", .id = SSPP_DMA3, +		.base = 0x2a000, .len = 0x344, +		.features = DMA_SDM845_MASK_SDMA, +		.sblk = &dpu_dma_sblk, +		.xin_id = 13, +		.type = SSPP_TYPE_DMA, +	}, { +		.name = "sspp_12", .id = SSPP_DMA4, +		.base = 0x2c000, .len = 0x344, +		.features = DMA_CURSOR_SDM845_MASK_SDMA, +		.sblk = &dpu_dma_sblk, +		.xin_id = 14, +		.type = SSPP_TYPE_DMA, +	}, { +		.name = "sspp_13", .id = SSPP_DMA5, +		.base = 0x2e000, .len = 0x344, +		.features = DMA_CURSOR_SDM845_MASK_SDMA, +		.sblk = &dpu_dma_sblk, +		.xin_id = 15, +		.type = SSPP_TYPE_DMA, +	}, +}; + +static const struct dpu_lm_cfg sar2130p_lm[] = { +	{ +		.name = "lm_0", .id = LM_0, +		.base = 0x44000, .len = 0x320, +		.features = MIXER_SDM845_MASK, +		.sblk = &sdm845_lm_sblk, +		.lm_pair = LM_1, +		.pingpong = PINGPONG_0, +		.dspp = DSPP_0, +	}, { +		.name = "lm_1", .id = LM_1, +		.base = 0x45000, .len = 0x320, +		.features = MIXER_SDM845_MASK, +		.sblk = &sdm845_lm_sblk, +		.lm_pair = LM_0, +		.pingpong = PINGPONG_1, +		.dspp = DSPP_1, +	}, { +		.name = "lm_2", .id = LM_2, +		.base = 0x46000, .len = 0x320, +		.features = MIXER_SDM845_MASK, +		.sblk = &sdm845_lm_sblk, +		.lm_pair = LM_3, +		.pingpong = PINGPONG_2, +		.dspp = DSPP_2, +	}, { +		.name = "lm_3", .id = LM_3, +		.base = 0x47000, .len = 0x320, +		.features = MIXER_SDM845_MASK, +		.sblk = &sdm845_lm_sblk, +		.lm_pair = LM_2, +		.pingpong = PINGPONG_3, +		.dspp = DSPP_3, +	}, { +		.name = "lm_4", .id = LM_4, +		.base = 0x48000, .len = 0x320, +		.features = MIXER_SDM845_MASK, +		.sblk = &sdm845_lm_sblk, +		.lm_pair = LM_5, +		.pingpong = PINGPONG_4, +	}, { +		.name = "lm_5", .id = LM_5, +		.base = 0x49000, .len = 0x320, +		.features = MIXER_SDM845_MASK, +		.sblk = &sdm845_lm_sblk, +		.lm_pair = LM_4, +		.pingpong = PINGPONG_5, +	}, +}; + +static const struct dpu_dspp_cfg sar2130p_dspp[] = { +	{ +		.name = "dspp_0", .id = DSPP_0, +		.base = 0x54000, .len = 0x1800, +		.features = DSPP_SC7180_MASK, +		.sblk = &sdm845_dspp_sblk, +	}, { +		.name = "dspp_1", .id = DSPP_1, +		.base = 0x56000, .len = 0x1800, +		.features = DSPP_SC7180_MASK, +		.sblk = &sdm845_dspp_sblk, +	}, { +		.name = "dspp_2", .id = DSPP_2, +		.base = 0x58000, .len = 0x1800, +		.features = DSPP_SC7180_MASK, +		.sblk = &sdm845_dspp_sblk, +	}, { +		.name = "dspp_3", .id = DSPP_3, +		.base = 0x5a000, .len = 0x1800, +		.features = DSPP_SC7180_MASK, +		.sblk = &sdm845_dspp_sblk, +	}, +}; +static const struct dpu_pingpong_cfg sar2130p_pp[] = { +	{ +		.name = "pingpong_0", .id = PINGPONG_0, +		.base = 0x69000, .len = 0, +		.features = BIT(DPU_PINGPONG_DITHER), +		.sblk = &sc7280_pp_sblk, +		.merge_3d = MERGE_3D_0, +		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), +	}, { +		.name = "pingpong_1", .id = PINGPONG_1, +		.base = 0x6a000, .len = 0, +		.features = BIT(DPU_PINGPONG_DITHER), +		.sblk = &sc7280_pp_sblk, +		.merge_3d = MERGE_3D_0, +		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), +	}, { +		.name = "pingpong_2", .id = PINGPONG_2, +		.base = 0x6b000, .len = 0, +		.features = BIT(DPU_PINGPONG_DITHER), +		.sblk = &sc7280_pp_sblk, +		.merge_3d = MERGE_3D_1, +		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), +	}, { +		.name = "pingpong_3", .id = PINGPONG_3, +		.base = 0x6c000, .len = 0, +		.features = BIT(DPU_PINGPONG_DITHER), +		.sblk = &sc7280_pp_sblk, +		.merge_3d = MERGE_3D_1, +		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), +	}, { +		.name = "pingpong_4", .id = PINGPONG_4, +		.base = 0x6d000, .len = 0, +		.features = BIT(DPU_PINGPONG_DITHER), +		.sblk = &sc7280_pp_sblk, +		.merge_3d = MERGE_3D_2, +		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), +	}, { +		.name = "pingpong_5", .id = PINGPONG_5, +		.base = 0x6e000, .len = 0, +		.features = BIT(DPU_PINGPONG_DITHER), +		.sblk = &sc7280_pp_sblk, +		.merge_3d = MERGE_3D_2, +		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), +	}, { +		.name = "pingpong_cwb_0", .id = PINGPONG_CWB_0, +		.base = 0x66000, .len = 0, +		.features = BIT(DPU_PINGPONG_DITHER), +		.sblk = &sc7280_pp_sblk, +		.merge_3d = MERGE_3D_3, +	}, { +		.name = "pingpong_cwb_1", .id = PINGPONG_CWB_1, +		.base = 0x66400, .len = 0, +		.features = BIT(DPU_PINGPONG_DITHER), +		.sblk = &sc7280_pp_sblk, +		.merge_3d = MERGE_3D_3, +	}, +}; + +static const struct dpu_merge_3d_cfg sar2130p_merge_3d[] = { +	{ +		.name = "merge_3d_0", .id = MERGE_3D_0, +		.base = 0x4e000, .len = 0x8, +	}, { +		.name = "merge_3d_1", .id = MERGE_3D_1, +		.base = 0x4f000, .len = 0x8, +	}, { +		.name = "merge_3d_2", .id = MERGE_3D_2, +		.base = 0x50000, .len = 0x8, +	}, { +		.name = "merge_3d_3", .id = MERGE_3D_3, +		.base = 0x66700, .len = 0x8, +	}, +}; + +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sar2130p_dsc[] = { +	{ +		.name = "dce_0_0", .id = DSC_0, +		.base = 0x80000, .len = 0x4, +		.features = BIT(DPU_DSC_HW_REV_1_2), +		.sblk = &dsc_sblk_0, +	}, { +		.name = "dce_0_1", .id = DSC_1, +		.base = 0x80000, .len = 0x4, +		.features = BIT(DPU_DSC_HW_REV_1_2), +		.sblk = &dsc_sblk_1, +	}, { +		.name = "dce_1_0", .id = DSC_2, +		.base = 0x81000, .len = 0x4, +		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN), +		.sblk = &dsc_sblk_0, +	}, { +		.name = "dce_1_1", .id = DSC_3, +		.base = 0x81000, .len = 0x4, +		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN), +		.sblk = &dsc_sblk_1, +	}, +}; + +static const struct dpu_wb_cfg sar2130p_wb[] = { +	{ +		.name = "wb_2", .id = WB_2, +		.base = 0x65000, .len = 0x2c8, +		.features = WB_SM8250_MASK, +		.format_list = wb2_formats_rgb_yuv, +		.num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), +		.xin_id = 6, +		.vbif_idx = VBIF_RT, +		.maxlinewidth = 4096, +		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), +	}, +}; + +static const struct dpu_intf_cfg sar2130p_intf[] = { +	{ +		.name = "intf_0", .id = INTF_0, +		.base = 0x34000, .len = 0x280, +		.features = INTF_SC7280_MASK, +		.type = INTF_DP, +		.controller_id = MSM_DP_CONTROLLER_0, +		.prog_fetch_lines_worst_case = 24, +		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), +		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25), +	}, { +		.name = "intf_1", .id = INTF_1, +		.base = 0x35000, .len = 0x300, +		.features = INTF_SC7280_MASK, +		.type = INTF_DSI, +		.controller_id = MSM_DSI_CONTROLLER_0, +		.prog_fetch_lines_worst_case = 24, +		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), +		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), +		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2), +	}, { +		.name = "intf_2", .id = INTF_2, +		.base = 0x36000, .len = 0x300, +		.features = INTF_SC7280_MASK, +		.type = INTF_DSI, +		.controller_id = MSM_DSI_CONTROLLER_1, +		.prog_fetch_lines_worst_case = 24, +		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), +		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), +		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2), +	}, { +		.name = "intf_3", .id = INTF_3, +		.base = 0x37000, .len = 0x280, +		.features = INTF_SC7280_MASK, +		.type = INTF_DP, +		.controller_id = MSM_DP_CONTROLLER_1, +		.prog_fetch_lines_worst_case = 24, +		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), +		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31), +	}, +}; + +static const struct dpu_perf_cfg sar2130p_perf_data = { +	.max_bw_low = 13600000, +	.max_bw_high = 18200000, +	.min_core_ib = 2500000, +	.min_llcc_ib = 0, +	.min_dram_ib = 800000, +	.min_prefill_lines = 35, +	/* FIXME: lut tables */ +	.danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0}, +	.safe_lut_tbl = {0xfe00, 0xfe00, 0xffff}, +	.qos_lut_tbl = { +		{.nentry = ARRAY_SIZE(sc7180_qos_linear), +		.entries = sc7180_qos_linear +		}, +		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile), +		.entries = sc7180_qos_macrotile +		}, +		{.nentry = ARRAY_SIZE(sc7180_qos_nrt), +		.entries = sc7180_qos_nrt +		}, +		/* TODO: macrotile-qseed is different from macrotile */ +	}, +	.cdp_cfg = { +		{.rd_enable = 0, .wr_enable = 0}, +		{.rd_enable = 0, .wr_enable = 0} +	}, +	.clk_inefficiency_factor = 105, +	.bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_version sar2130p_mdss_ver = { +	.core_major_ver = 9, +	.core_minor_ver = 1, +}; + +const struct dpu_mdss_cfg dpu_sar2130p_cfg = { +	.mdss_ver = &sar2130p_mdss_ver, +	.caps = &sar2130p_dpu_caps, +	.mdp = &sar2130p_mdp, +	.cdm = &dpu_cdm_5_x, +	.ctl_count = ARRAY_SIZE(sar2130p_ctl), +	.ctl = sar2130p_ctl, +	.sspp_count = ARRAY_SIZE(sar2130p_sspp), +	.sspp = sar2130p_sspp, +	.mixer_count = ARRAY_SIZE(sar2130p_lm), +	.mixer = sar2130p_lm, +	.dspp_count = ARRAY_SIZE(sar2130p_dspp), +	.dspp = sar2130p_dspp, +	.pingpong_count = ARRAY_SIZE(sar2130p_pp), +	.pingpong = sar2130p_pp, +	.dsc_count = ARRAY_SIZE(sar2130p_dsc), +	.dsc = sar2130p_dsc, +	.merge_3d_count = ARRAY_SIZE(sar2130p_merge_3d), +	.merge_3d = sar2130p_merge_3d, +	.wb_count = ARRAY_SIZE(sar2130p_wb), +	.wb = sar2130p_wb, +	.intf_count = ARRAY_SIZE(sar2130p_intf), +	.intf = sar2130p_intf, +	.vbif_count = ARRAY_SIZE(sm8550_vbif), +	.vbif = sm8550_vbif, +	.perf = &sar2130p_perf_data, +}; + +#endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h index 6417baa84f82..52cc10aec1f9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h @@ -26,17 +26,16 @@ static const struct dpu_mdp_cfg x1e80100_mdp = {  	},  }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */  static const struct dpu_ctl_cfg x1e80100_ctl[] = {  	{  		.name = "ctl_0", .id = CTL_0,  		.base = 0x15000, .len = 0x290, -		.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = CTL_SM8550_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),  	}, {  		.name = "ctl_1", .id = CTL_1,  		.base = 0x16000, .len = 0x290, -		.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), +		.features = CTL_SM8550_MASK,  		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),  	}, {  		.name = "ctl_2", .id = CTL_2, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 0714936d8835..a4b0fe0d9899 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -445,9 +445,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,  	uint32_t lm_idx;  	bool bg_alpha_enable = false; -	DECLARE_BITMAP(fetch_active, SSPP_MAX); +	DECLARE_BITMAP(active_fetch, SSPP_MAX); -	memset(fetch_active, 0, sizeof(fetch_active)); +	memset(active_fetch, 0, sizeof(active_fetch));  	drm_atomic_crtc_for_each_plane(plane, crtc) {  		state = plane->state;  		if (!state) @@ -464,7 +464,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,  		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)  			bg_alpha_enable = true; -		set_bit(pstate->pipe.sspp->idx, fetch_active); +		set_bit(pstate->pipe.sspp->idx, active_fetch);  		_dpu_crtc_blend_setup_pipe(crtc, plane,  					   mixer, cstate->num_mixers,  					   pstate->stage, @@ -472,7 +472,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,  					   &pstate->pipe, 0, stage_cfg);  		if (pstate->r_pipe.sspp) { -			set_bit(pstate->r_pipe.sspp->idx, fetch_active); +			set_bit(pstate->r_pipe.sspp->idx, active_fetch);  			_dpu_crtc_blend_setup_pipe(crtc, plane,  						   mixer, cstate->num_mixers,  						   pstate->stage, @@ -492,8 +492,8 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,  		}  	} -	if (ctl->ops.set_active_pipes) -		ctl->ops.set_active_pipes(ctl, fetch_active); +	if (ctl->ops.set_active_fetch_pipes) +		ctl->ops.set_active_fetch_pipes(ctl, active_fetch);  	_dpu_crtc_program_lm_output_roi(crtc);  } @@ -519,6 +519,8 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)  		if (mixer[i].lm_ctl->ops.clear_all_blendstages)  			mixer[i].lm_ctl->ops.clear_all_blendstages(  					mixer[i].lm_ctl); +		if (mixer[i].lm_ctl->ops.set_active_fetch_pipes) +			mixer[i].lm_ctl->ops.set_active_fetch_pipes(mixer[i].lm_ctl, NULL);  	}  	/* initialize stage cfg */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 862e9e6bf0a5..7020098360e4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1246,7 +1246,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,  			return;  		} -		phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL; +		/* Use first (and only) CTL if active CTLs are supported */ +		if (num_ctl == 1) +			phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[0]); +		else +			phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL;  		if (!phys->hw_ctl) {  			DPU_ERROR_ENC(dpu_enc,  				"no ctl block assigned at idx: %d\n", i); @@ -2190,6 +2194,9 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)  		/* clear all blendstages */  		if (ctl->ops.setup_blendstage)  			ctl->ops.setup_blendstage(ctl, hw_mixer[i]->idx, NULL); + +		if (ctl->ops.set_active_fetch_pipes) +			ctl->ops.set_active_fetch_pipes(ctl, NULL);  	}  } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index da9994a79ca2..a0ba55ab3c89 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -60,6 +60,8 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg(  		return;  	intf_cfg.intf = phys_enc->hw_intf->idx; +	if (phys_enc->split_role == ENC_ROLE_MASTER) +		intf_cfg.intf_master = phys_enc->hw_intf->idx;  	intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD;  	intf_cfg.stream_sel = cmd_enc->stream_sel;  	intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index abd6600046cb..8a618841e3ea 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -298,6 +298,8 @@ static void dpu_encoder_phys_vid_setup_timing_engine(  	if (phys_enc->hw_cdm)  		intf_cfg.cdm = phys_enc->hw_cdm->idx;  	intf_cfg.intf = phys_enc->hw_intf->idx; +	if (phys_enc->split_role == ENC_ROLE_MASTER) +		intf_cfg.intf_master = phys_enc->hw_intf->idx;  	intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID;  	intf_cfg.stream_sel = 0; /* Don't care value for video mode */  	intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); @@ -372,7 +374,8 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg)  static bool dpu_encoder_phys_vid_needs_single_flush(  		struct dpu_encoder_phys *phys_enc)  { -	return phys_enc->split_role != ENC_ROLE_SOLO; +	return !(phys_enc->hw_ctl->caps->features & BIT(DPU_CTL_ACTIVE_CFG)) && +		phys_enc->split_role != ENC_ROLE_SOLO;  }  static void dpu_encoder_phys_vid_atomic_mode_set( 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 64265ca4656a..c878fe196aeb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -34,11 +34,11 @@  #define VIG_MSM8998_MASK \  	(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE)) -#define VIG_SDM845_MASK \ +#define VIG_SDM845_MASK_NO_SDMA \  	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE))  #define VIG_SDM845_MASK_SDMA \ -	(VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) +	(VIG_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_SMART_DMA_V2))  #define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL)) @@ -54,24 +54,24 @@  	BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))  #define VIG_SC7280_MASK \ -	(VIG_SDM845_MASK | BIT(DPU_SSPP_INLINE_ROTATION)) +	(VIG_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_INLINE_ROTATION))  #define VIG_SC7280_MASK_SDMA \  	(VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) -#define DMA_SDM845_MASK \ +#define DMA_SDM845_MASK_NO_SDMA \  	(BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\  	BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\  	BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) -#define DMA_CURSOR_SDM845_MASK \ -	(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR)) +#define DMA_CURSOR_SDM845_MASK_NO_SDMA \ +	(DMA_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_CURSOR))  #define DMA_SDM845_MASK_SDMA \ -	(DMA_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) +	(DMA_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_SMART_DMA_V2))  #define DMA_CURSOR_SDM845_MASK_SDMA \ -	(DMA_CURSOR_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) +	(DMA_CURSOR_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_SMART_DMA_V2))  #define DMA_CURSOR_MSM8996_MASK \  	(DMA_MSM8996_MASK | BIT(DPU_SSPP_CURSOR)) @@ -98,15 +98,9 @@  #define PINGPONG_MSM8996_MASK \  	(BIT(DPU_PINGPONG_DSC)) -#define PINGPONG_MSM8996_TE2_MASK \ -	(PINGPONG_MSM8996_MASK | BIT(DPU_PINGPONG_TE2)) -  #define PINGPONG_SDM845_MASK \  	(BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC)) -#define PINGPONG_SDM845_TE2_MASK \ -	(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2)) -  #define PINGPONG_SM8150_MASK \  	(BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC)) @@ -376,8 +370,6 @@ static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK();   * MIXER sub blocks config   *************************************************************/ -/* MSM8998 */ -  static const struct dpu_lm_sub_blks msm8998_lm_sblk = {  	.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,  	.maxblendstages = 7, /* excluding base layer */ @@ -387,8 +379,6 @@ static const struct dpu_lm_sub_blks msm8998_lm_sblk = {  	},  }; -/* SDM845 */ -  static const struct dpu_lm_sub_blks sdm845_lm_sblk = {  	.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,  	.maxblendstages = 11, /* excluding base layer */ @@ -398,8 +388,6 @@ static const struct dpu_lm_sub_blks sdm845_lm_sblk = {  	},  }; -/* SC7180 */ -  static const struct dpu_lm_sub_blks sc7180_lm_sblk = {  	.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,  	.maxblendstages = 7, /* excluding base layer */ @@ -408,8 +396,6 @@ static const struct dpu_lm_sub_blks sc7180_lm_sblk = {  	},  }; -/* QCM2290 */ -  static const struct dpu_lm_sub_blks qcm2290_lm_sblk = {  	.maxwidth = DEFAULT_DPU_LINE_WIDTH,  	.maxblendstages = 4, /* excluding base layer */ @@ -434,22 +420,11 @@ static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = {  /*************************************************************   * PINGPONG sub blocks config   *************************************************************/ -static const struct dpu_pingpong_sub_blks msm8996_pp_sblk_te = { -	.te2 = {.name = "te2", .base = 0x2000, .len = 0x0, -		.version = 0x1}, -};  static const struct dpu_pingpong_sub_blks msm8996_pp_sblk = {  	/* No dither block */  }; -static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = { -	.te2 = {.name = "te2", .base = 0x2000, .len = 0x0, -		.version = 0x1}, -	.dither = {.name = "dither", .base = 0x30e0, -		.len = 0x20, .version = 0x10000}, -}; -  static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {  	.dither = {.name = "dither", .base = 0x30e0,  		.len = 0x20, .version = 0x10000}, @@ -759,7 +734,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = {  #include "catalog/dpu_8_4_sa8775p.h"  #include "catalog/dpu_9_0_sm8550.h" - +#include "catalog/dpu_9_1_sar2130p.h"  #include "catalog/dpu_9_2_x1e80100.h"  #include "catalog/dpu_10_0_sm8650.h" diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 4cea19e1a203..01dd6e65f777 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -115,7 +115,6 @@ enum {  /**   * PINGPONG sub-blocks - * @DPU_PINGPONG_TE2        Additional tear check block for split pipes   * @DPU_PINGPONG_SPLIT      PP block supports split fifo   * @DPU_PINGPONG_SLAVE      PP block is a suitable slave for split fifo   * @DPU_PINGPONG_DITHER     Dither blocks @@ -123,8 +122,7 @@ enum {   * @DPU_PINGPONG_MAX   */  enum { -	DPU_PINGPONG_TE2 = 0x1, -	DPU_PINGPONG_SPLIT, +	DPU_PINGPONG_SPLIT = 0x1,  	DPU_PINGPONG_SLAVE,  	DPU_PINGPONG_DITHER,  	DPU_PINGPONG_DSC, @@ -404,8 +402,6 @@ struct dpu_dspp_sub_blks {  };  struct dpu_pingpong_sub_blks { -	struct dpu_pp_blk te; -	struct dpu_pp_blk te2;  	struct dpu_pp_blk dither;  }; @@ -841,6 +837,7 @@ extern const struct dpu_mdss_cfg dpu_msm8937_cfg;  extern const struct dpu_mdss_cfg dpu_msm8953_cfg;  extern const struct dpu_mdss_cfg dpu_msm8996_cfg;  extern const struct dpu_mdss_cfg dpu_msm8998_cfg; +extern const struct dpu_mdss_cfg dpu_sar2130p_cfg;  extern const struct dpu_mdss_cfg dpu_sdm630_cfg;  extern const struct dpu_mdss_cfg dpu_sdm660_cfg;  extern const struct dpu_mdss_cfg dpu_sdm845_cfg; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 411a7cf088eb..573e42b06ad0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -261,6 +261,12 @@ static void dpu_hw_ctl_update_pending_flush_mixer(struct dpu_hw_ctl *ctx,  	case LM_5:  		ctx->pending_flush_mask |= BIT(20);  		break; +	case LM_6: +		ctx->pending_flush_mask |= BIT(21); +		break; +	case LM_7: +		ctx->pending_flush_mask |= BIT(27); +		break;  	default:  		break;  	} @@ -563,6 +569,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,  	u32 wb_active = 0;  	u32 cwb_active = 0;  	u32 mode_sel = 0; +	u32 merge_3d_active = 0;  	/* CTL_TOP[31:28] carries group_id to collate CTL paths  	 * per VM. Explicitly disable it until VM support is @@ -578,6 +585,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,  	wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);  	cwb_active = DPU_REG_READ(c, CTL_CWB_ACTIVE);  	dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE); +	merge_3d_active = DPU_REG_READ(c, CTL_MERGE_3D_ACTIVE);  	if (cfg->intf)  		intf_active |= BIT(cfg->intf - INTF_0); @@ -591,15 +599,18 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,  	if (cfg->dsc)  		dsc_active |= cfg->dsc; +	if (cfg->merge_3d) +		merge_3d_active |= BIT(cfg->merge_3d - MERGE_3D_0); +  	DPU_REG_WRITE(c, CTL_TOP, mode_sel);  	DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);  	DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);  	DPU_REG_WRITE(c, CTL_CWB_ACTIVE, cwb_active);  	DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active); +	DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, merge_3d_active); -	if (cfg->merge_3d) -		DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, -			      BIT(cfg->merge_3d - MERGE_3D_0)); +	if (cfg->intf_master) +		DPU_REG_WRITE(c, CTL_INTF_MASTER, BIT(cfg->intf_master - INTF_0));  	if (cfg->cdm)  		DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm); @@ -643,6 +654,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,  {  	struct dpu_hw_blk_reg_map *c = &ctx->hw;  	u32 intf_active = 0; +	u32 intf_master = 0;  	u32 wb_active = 0;  	u32 cwb_active = 0;  	u32 merge3d_active = 0; @@ -666,10 +678,21 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,  	dpu_hw_ctl_clear_all_blendstages(ctx); +	if (ctx->ops.set_active_fetch_pipes) +		ctx->ops.set_active_fetch_pipes(ctx, NULL); +  	if (cfg->intf) {  		intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);  		intf_active &= ~BIT(cfg->intf - INTF_0);  		DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); + +		intf_master = DPU_REG_READ(c, CTL_INTF_MASTER); + +		/* Unset this intf as master, if it is the current master */ +		if (intf_master == BIT(cfg->intf - INTF_0)) { +			DPU_DEBUG_DRIVER("Unsetting INTF_%d master\n", cfg->intf - INTF_0); +			DPU_REG_WRITE(c, CTL_INTF_MASTER, 0); +		}  	}  	if (cfg->cwb) { @@ -697,8 +720,8 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,  	}  } -static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx, -	unsigned long *fetch_active) +static void dpu_hw_ctl_set_active_fetch_pipes(struct dpu_hw_ctl *ctx, +					      unsigned long *fetch_active)  {  	int i;  	u32 val = 0; @@ -761,7 +784,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,  		ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp;  	if (cap & BIT(DPU_CTL_FETCH_ACTIVE)) -		ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active; +		ops->set_active_fetch_pipes = dpu_hw_ctl_set_active_fetch_pipes;  };  /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index 080a9550a0cc..feb09590bc8f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -36,6 +36,7 @@ struct dpu_hw_stage_cfg {  /**   * struct dpu_hw_intf_cfg :Describes how the DPU writes data to output interface   * @intf :                 Interface id + * @intf_master:           Master interface id in the dual pipe topology   * @mode_3d:               3d mux configuration   * @merge_3d:              3d merge block used   * @intf_mode_sel:         Interface mode, cmd / vid @@ -46,6 +47,7 @@ struct dpu_hw_stage_cfg {   */  struct dpu_hw_intf_cfg {  	enum dpu_intf intf; +	enum dpu_intf intf_master;  	enum dpu_wb wb;  	enum dpu_3d_blend_mode mode_3d;  	enum dpu_merge_3d merge_3d; @@ -254,7 +256,7 @@ struct dpu_hw_ctl_ops {  	void (*setup_blendstage)(struct dpu_hw_ctl *ctx,  		enum dpu_lm lm, struct dpu_hw_stage_cfg *cfg); -	void (*set_active_pipes)(struct dpu_hw_ctl *ctx, +	void (*set_active_fetch_pipes)(struct dpu_hw_ctl *ctx,  		unsigned long *fetch_active);  }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h index 8d820cd1b554..175639c8bfbb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -125,6 +125,7 @@ enum dpu_lm {  	LM_4,  	LM_5,  	LM_6, +	LM_7,  	LM_MAX  }; @@ -169,6 +170,8 @@ enum dpu_dsc {  	DSC_3,  	DSC_4,  	DSC_5, +	DSC_6, +	DSC_7,  	DSC_MAX  }; @@ -185,6 +188,8 @@ enum dpu_pingpong {  	PINGPONG_3,  	PINGPONG_4,  	PINGPONG_5, +	PINGPONG_6, +	PINGPONG_7,  	PINGPONG_CWB_0,  	PINGPONG_CWB_1,  	PINGPONG_CWB_2, @@ -199,6 +204,7 @@ enum dpu_merge_3d {  	MERGE_3D_2,  	MERGE_3D_3,  	MERGE_3D_4, +	MERGE_3D_5,  	MERGE_3D_MAX  }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 3305ad0623ca..1fd82b6747e9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1512,6 +1512,7 @@ static const struct of_device_id dpu_dt_match[] = {  	{ .compatible = "qcom,msm8998-dpu", .data = &dpu_msm8998_cfg, },  	{ .compatible = "qcom,qcm2290-dpu", .data = &dpu_qcm2290_cfg, },  	{ .compatible = "qcom,sa8775p-dpu", .data = &dpu_sa8775p_cfg, }, +	{ .compatible = "qcom,sar2130p-dpu", .data = &dpu_sar2130p_cfg, },  	{ .compatible = "qcom,sdm630-mdp5", .data = &dpu_sdm630_cfg, },  	{ .compatible = "qcom,sdm660-mdp5", .data = &dpu_sdm660_cfg, },  	{ .compatible = "qcom,sdm670-dpu", .data = &dpu_sdm670_cfg, }, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index e03d6091f736..421138bc3cb7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -915,10 +915,9 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,  	return 0;  } -static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp, -						   struct dpu_sw_pipe_cfg *pipe_cfg, -						   const struct msm_format *fmt, -						   uint32_t max_linewidth) +static int dpu_plane_is_multirect_capable(struct dpu_hw_sspp *sspp, +					  struct dpu_sw_pipe_cfg *pipe_cfg, +					  const struct msm_format *fmt)  {  	if (drm_rect_width(&pipe_cfg->src_rect) != drm_rect_width(&pipe_cfg->dst_rect) ||  	    drm_rect_height(&pipe_cfg->src_rect) != drm_rect_height(&pipe_cfg->dst_rect)) @@ -930,10 +929,6 @@ static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp,  	if (MSM_FORMAT_IS_YUV(fmt))  		return false; -	if (MSM_FORMAT_IS_UBWC(fmt) && -	    drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2) -		return false; -  	if (!test_bit(DPU_SSPP_SMART_DMA_V1, &sspp->cap->features) &&  	    !test_bit(DPU_SSPP_SMART_DMA_V2, &sspp->cap->features))  		return false; @@ -941,6 +936,27 @@ static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp,  	return true;  } +static int dpu_plane_is_parallel_capable(struct dpu_sw_pipe_cfg *pipe_cfg, +					 const struct msm_format *fmt, +					 uint32_t max_linewidth) +{ +	if (MSM_FORMAT_IS_UBWC(fmt) && +	    drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2) +		return false; + +	return true; +} + +static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp, +						   struct dpu_sw_pipe_cfg *pipe_cfg, +						   const struct msm_format *fmt, +						   uint32_t max_linewidth) +{ +	return dpu_plane_is_multirect_capable(sspp, pipe_cfg, fmt) && +		dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth); +} + +  static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,  				       struct drm_atomic_state *state,  				       const struct drm_crtc_state *crtc_state) @@ -1002,6 +1018,69 @@ static bool dpu_plane_try_multirect_parallel(struct dpu_sw_pipe *pipe, struct dp  	return true;  } +static int dpu_plane_try_multirect_shared(struct dpu_plane_state *pstate, +					  struct dpu_plane_state *prev_adjacent_pstate, +					  const struct msm_format *fmt, +					  uint32_t max_linewidth) +{ +	struct dpu_sw_pipe *pipe = &pstate->pipe; +	struct dpu_sw_pipe *r_pipe = &pstate->r_pipe; +	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg; +	struct dpu_sw_pipe *prev_pipe = &prev_adjacent_pstate->pipe; +	struct dpu_sw_pipe_cfg *prev_pipe_cfg = &prev_adjacent_pstate->pipe_cfg; +	const struct msm_format *prev_fmt = msm_framebuffer_format(prev_adjacent_pstate->base.fb); +	u16 max_tile_height = 1; + +	if (prev_adjacent_pstate->r_pipe.sspp != NULL || +	    prev_pipe->multirect_mode != DPU_SSPP_MULTIRECT_NONE) +		return false; + +	if (!dpu_plane_is_multirect_capable(pipe->sspp, pipe_cfg, fmt) || +	    !dpu_plane_is_multirect_capable(prev_pipe->sspp, prev_pipe_cfg, prev_fmt)) +		return false; + +	if (MSM_FORMAT_IS_UBWC(fmt)) +		max_tile_height = max(max_tile_height, fmt->tile_height); + +	if (MSM_FORMAT_IS_UBWC(prev_fmt)) +		max_tile_height = max(max_tile_height, prev_fmt->tile_height); + +	r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; +	r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; + +	r_pipe->sspp = NULL; + +	if (dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth) && +	    dpu_plane_is_parallel_capable(prev_pipe_cfg, prev_fmt, max_linewidth) && +	    (pipe_cfg->dst_rect.x1 >= prev_pipe_cfg->dst_rect.x2 || +	     prev_pipe_cfg->dst_rect.x1 >= pipe_cfg->dst_rect.x2)) { +		pipe->sspp = prev_pipe->sspp; + +		pipe->multirect_index = DPU_SSPP_RECT_1; +		pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL; + +		prev_pipe->multirect_index = DPU_SSPP_RECT_0; +		prev_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL; + +		return true; +	} + +	if (pipe_cfg->dst_rect.y1 >= prev_pipe_cfg->dst_rect.y2 + 2 * max_tile_height || +	    prev_pipe_cfg->dst_rect.y1 >= pipe_cfg->dst_rect.y2 + 2 * max_tile_height) { +		pipe->sspp = prev_pipe->sspp; + +		pipe->multirect_index = DPU_SSPP_RECT_1; +		pipe->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX; + +		prev_pipe->multirect_index = DPU_SSPP_RECT_0; +		prev_pipe->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX; + +		return true; +	} + +	return false; +} +  static int dpu_plane_atomic_check(struct drm_plane *plane,  				  struct drm_atomic_state *state)  { @@ -1102,13 +1181,14 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,  static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,  					      struct dpu_global_state *global_state,  					      struct drm_atomic_state *state, -					      struct drm_plane_state *plane_state) +					      struct drm_plane_state *plane_state, +					      struct drm_plane_state *prev_adjacent_plane_state)  {  	const struct drm_crtc_state *crtc_state = NULL;  	struct drm_plane *plane = plane_state->plane;  	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);  	struct dpu_rm_sspp_requirements reqs; -	struct dpu_plane_state *pstate; +	struct dpu_plane_state *pstate, *prev_adjacent_pstate;  	struct dpu_sw_pipe *pipe;  	struct dpu_sw_pipe *r_pipe;  	struct dpu_sw_pipe_cfg *pipe_cfg; @@ -1120,6 +1200,8 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,  							   plane_state->crtc);  	pstate = to_dpu_plane_state(plane_state); +	prev_adjacent_pstate = prev_adjacent_plane_state ? +		to_dpu_plane_state(prev_adjacent_plane_state) : NULL;  	pipe = &pstate->pipe;  	r_pipe = &pstate->r_pipe;  	pipe_cfg = &pstate->pipe_cfg; @@ -1138,24 +1220,42 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,  	reqs.rot90 = drm_rotation_90_or_270(plane_state->rotation); -	pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs); -	if (!pipe->sspp) -		return -ENODEV; +	if (drm_rect_width(&r_pipe_cfg->src_rect) == 0) { +		if (!prev_adjacent_pstate || +		    !dpu_plane_try_multirect_shared(pstate, prev_adjacent_pstate, fmt, +						    dpu_kms->catalog->caps->max_linewidth)) { +			pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs); +			if (!pipe->sspp) +				return -ENODEV; -	if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg, -					      pipe->sspp, -					      msm_framebuffer_format(plane_state->fb), -					      dpu_kms->catalog->caps->max_linewidth)) { -		/* multirect is not possible, use two SSPP blocks */ -		r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs); -		if (!r_pipe->sspp) +			r_pipe->sspp = NULL; + +			pipe->multirect_index = DPU_SSPP_RECT_SOLO; +			pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; + +			r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; +			r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; +		} +	} else { +		pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs); +		if (!pipe->sspp)  			return -ENODEV; -		pipe->multirect_index = DPU_SSPP_RECT_SOLO; -		pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; +		if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg, +						      pipe->sspp, +						      msm_framebuffer_format(plane_state->fb), +						      dpu_kms->catalog->caps->max_linewidth)) { +			/* multirect is not possible, use two SSPP blocks */ +			r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs); +			if (!r_pipe->sspp) +				return -ENODEV; -		r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; -		r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; +			pipe->multirect_index = DPU_SSPP_RECT_SOLO; +			pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; + +			r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; +			r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; +		}  	}  	return dpu_plane_atomic_check_sspp(plane, state, crtc_state); @@ -1168,6 +1268,7 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,  			       unsigned int num_planes)  {  	unsigned int i; +	struct drm_plane_state *prev_adjacent_plane_state = NULL;  	for (i = 0; i < num_planes; i++) {  		struct drm_plane_state *plane_state = states[i]; @@ -1177,9 +1278,12 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,  			continue;  		int ret = dpu_plane_virtual_assign_resources(crtc, global_state, -							 state, plane_state); +							     state, plane_state, +							     prev_adjacent_plane_state);  		if (ret) -			return ret; +			break; + +		prev_adjacent_plane_state = plane_state;  	}  	return 0; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 3efbba425ca6..2e296f79cba1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -53,6 +53,8 @@ int dpu_rm_init(struct drm_device *dev,  	/* Clear, setup lists */  	memset(rm, 0, sizeof(*rm)); +	rm->has_legacy_ctls = (cat->mdss_ver->core_major_ver < 5); +  	/* Interrogate HW catalog and create tracking items for hw blocks */  	for (i = 0; i < cat->mixer_count; i++) {  		struct dpu_hw_mixer *hw; @@ -434,20 +436,19 @@ static int _dpu_rm_reserve_ctls(  	int i = 0, j, num_ctls;  	bool needs_split_display; -	/* -	 * For non-CWB mode, each hw_intf needs its own hw_ctl to program its -	 * control path. -	 * -	 * Hardcode num_ctls to 1 if CWB is enabled because in CWB, both the -	 * writeback and real-time encoders must be driven by the same control -	 * path -	 */ -	if (top->cwb_enabled) -		num_ctls = 1; -	else +	if (rm->has_legacy_ctls) { +		/* +		 * TODO: check if there is a need for special handling if +		 * DPU < 5.0 get CWB support. +		 */  		num_ctls = top->num_intf; -	needs_split_display = _dpu_rm_needs_split_display(top); +		needs_split_display = _dpu_rm_needs_split_display(top); +	} else { +		/* use single CTL */ +		num_ctls = 1; +		needs_split_display = false; +	}  	for (j = 0; j < ARRAY_SIZE(rm->ctl_blks); j++) {  		const struct dpu_hw_ctl *ctl; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index a19dbdb1b6f4..aa62966056d4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -24,6 +24,7 @@ struct dpu_global_state;   * @dspp_blks: array of dspp hardware resources   * @hw_sspp: array of sspp hardware resources   * @cdm_blk: cdm hardware resource + * @has_legacy_ctls: DPU uses pre-ACTIVE CTL blocks.   */  struct dpu_rm {  	struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0]; @@ -37,6 +38,7 @@ struct dpu_rm {  	struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];  	struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];  	struct dpu_hw_blk *cdm_blk; +	bool has_legacy_ctls;  };  struct dpu_rm_sspp_requirements { diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index c469e66cfc11..7e942c1337b3 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -6,6 +6,8 @@  #include <linux/delay.h> +#include <drm/drm_bridge.h> +#include <drm/drm_bridge_connector.h>  #include <drm/drm_vblank.h>  #include "msm_drv.h" @@ -189,7 +191,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,  	struct msm_drm_private *priv = dev->dev_private;  	struct drm_encoder *encoder;  	struct drm_connector *connector; -	struct device_node *panel_node; +	struct drm_bridge *next_bridge;  	int dsi_id;  	int ret; @@ -199,27 +201,43 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,  		 * bail out early if there is no panel node (no need to  		 * initialize LCDC encoder and LVDS connector)  		 */ -		panel_node = of_graph_get_remote_node(dev->dev->of_node, 0, 0); -		if (!panel_node) -			return 0; +		next_bridge = devm_drm_of_get_bridge(dev->dev, dev->dev->of_node, 0, 0); +		if (IS_ERR(next_bridge)) { +			ret = PTR_ERR(next_bridge); +			if (ret == -ENODEV) +				return 0; +			return ret; +		} -		encoder = mdp4_lcdc_encoder_init(dev, panel_node); +		encoder = mdp4_lcdc_encoder_init(dev);  		if (IS_ERR(encoder)) {  			DRM_DEV_ERROR(dev->dev, "failed to construct LCDC encoder\n"); -			of_node_put(panel_node);  			return PTR_ERR(encoder);  		}  		/* LCDC can be hooked to DMA_P (TODO: Add DMA_S later?) */  		encoder->possible_crtcs = 1 << DMA_P; -		connector = mdp4_lvds_connector_init(dev, panel_node, encoder); +		ret = drm_bridge_attach(encoder, next_bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); +		if (ret) { +			DRM_DEV_ERROR(dev->dev, "failed to attach LVDS panel/bridge: %d\n", ret); + +			return ret; +		} + +		connector = drm_bridge_connector_init(dev, encoder);  		if (IS_ERR(connector)) {  			DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS connector\n"); -			of_node_put(panel_node);  			return PTR_ERR(connector);  		} +		ret = drm_connector_attach_encoder(connector, encoder); +		if (ret) { +			DRM_DEV_ERROR(dev->dev, "failed to attach LVDS connector: %d\n", ret); + +			return ret; +		} +  		break;  	case DRM_MODE_ENCODER_TMDS:  		encoder = mdp4_dtv_encoder_init(dev); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h index 94b1ba92785f..f9d988076337 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h @@ -191,12 +191,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,  long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate);  struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev); -long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate); -struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, -		struct device_node *panel_node); - -struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev, -		struct device_node *panel_node, struct drm_encoder *encoder); +struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev);  #ifdef CONFIG_DRM_MSM_DSI  struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev); @@ -207,13 +202,6 @@ static inline struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev)  }  #endif -#ifdef CONFIG_COMMON_CLK -struct clk *mpd4_lvds_pll_init(struct drm_device *dev); -#else -static inline struct clk *mpd4_lvds_pll_init(struct drm_device *dev) -{ -	return ERR_PTR(-ENODEV); -} -#endif +struct clk *mpd4_get_lcdc_clock(struct drm_device *dev);  #endif /* __MDP4_KMS_H__ */ diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c index 8bbc7fb881d5..06a307c1272d 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c @@ -14,7 +14,6 @@  struct mdp4_lcdc_encoder {  	struct drm_encoder base; -	struct device_node *panel_node;  	struct drm_panel *panel;  	struct clk *lcdc_clk;  	unsigned long int pixclock; @@ -262,19 +261,12 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder)  	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =  			to_mdp4_lcdc_encoder(encoder);  	struct mdp4_kms *mdp4_kms = get_kms(encoder); -	struct drm_panel *panel;  	if (WARN_ON(!mdp4_lcdc_encoder->enabled))  		return;  	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); -	panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); -	if (!IS_ERR(panel)) { -		drm_panel_disable(panel); -		drm_panel_unprepare(panel); -	} -  	/*  	 * Wait for a vsync so we know the ENABLE=0 latched before  	 * the (connector) source of the vsync's gets disabled, @@ -300,7 +292,6 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)  			to_mdp4_lcdc_encoder(encoder);  	unsigned long pc = mdp4_lcdc_encoder->pixclock;  	struct mdp4_kms *mdp4_kms = get_kms(encoder); -	struct drm_panel *panel;  	uint32_t config;  	int ret; @@ -335,12 +326,6 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)  	if (ret)  		DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret); -	panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); -	if (!IS_ERR(panel)) { -		drm_panel_prepare(panel); -		drm_panel_enable(panel); -	} -  	setup_phy(encoder);  	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1); @@ -348,22 +333,34 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)  	mdp4_lcdc_encoder->enabled = true;  } +static enum drm_mode_status +mdp4_lcdc_encoder_mode_valid(struct drm_encoder *encoder, +		const struct drm_display_mode *mode) +{ +	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = +			to_mdp4_lcdc_encoder(encoder); +	long actual, requested; + +	requested = 1000 * mode->clock; +	actual = clk_round_rate(mdp4_lcdc_encoder->lcdc_clk, requested); + +	DBG("requested=%ld, actual=%ld", requested, actual); + +	if (actual != requested) +		return MODE_CLOCK_RANGE; + +	return MODE_OK; +} +  static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = {  	.mode_set = mdp4_lcdc_encoder_mode_set,  	.disable = mdp4_lcdc_encoder_disable,  	.enable = mdp4_lcdc_encoder_enable, +	.mode_valid = mdp4_lcdc_encoder_mode_valid,  }; -long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate) -{ -	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = -			to_mdp4_lcdc_encoder(encoder); -	return clk_round_rate(mdp4_lcdc_encoder->lcdc_clk, rate); -} -  /* initialize encoder */ -struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, -		struct device_node *panel_node) +struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev)  {  	struct drm_encoder *encoder;  	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder; @@ -374,14 +371,11 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,  	if (IS_ERR(mdp4_lcdc_encoder))  		return ERR_CAST(mdp4_lcdc_encoder); -	mdp4_lcdc_encoder->panel_node = panel_node; -  	encoder = &mdp4_lcdc_encoder->base;  	drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs); -	/* TODO: do we need different pll in other cases? */ -	mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev); +	mdp4_lcdc_encoder->lcdc_clk = mpd4_get_lcdc_clock(dev);  	if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) {  		DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n");  		return ERR_CAST(mdp4_lcdc_encoder->lcdc_clk); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c deleted file mode 100644 index 52e728181b52..000000000000 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2014 Red Hat - * Author: Rob Clark <robdclark@gmail.com> - * Author: Vinay Simha <vinaysimha@inforcecomputing.com> - */ - -#include "mdp4_kms.h" - -struct mdp4_lvds_connector { -	struct drm_connector base; -	struct drm_encoder *encoder; -	struct device_node *panel_node; -	struct drm_panel *panel; -}; -#define to_mdp4_lvds_connector(x) container_of(x, struct mdp4_lvds_connector, base) - -static enum drm_connector_status mdp4_lvds_connector_detect( -		struct drm_connector *connector, bool force) -{ -	struct mdp4_lvds_connector *mdp4_lvds_connector = -			to_mdp4_lvds_connector(connector); - -	if (!mdp4_lvds_connector->panel) { -		mdp4_lvds_connector->panel = -			of_drm_find_panel(mdp4_lvds_connector->panel_node); -		if (IS_ERR(mdp4_lvds_connector->panel)) -			mdp4_lvds_connector->panel = NULL; -	} - -	return mdp4_lvds_connector->panel ? -			connector_status_connected : -			connector_status_disconnected; -} - -static void mdp4_lvds_connector_destroy(struct drm_connector *connector) -{ -	struct mdp4_lvds_connector *mdp4_lvds_connector = -			to_mdp4_lvds_connector(connector); - -	drm_connector_cleanup(connector); - -	kfree(mdp4_lvds_connector); -} - -static int mdp4_lvds_connector_get_modes(struct drm_connector *connector) -{ -	struct mdp4_lvds_connector *mdp4_lvds_connector = -			to_mdp4_lvds_connector(connector); -	struct drm_panel *panel = mdp4_lvds_connector->panel; -	int ret = 0; - -	if (panel) -		ret = drm_panel_get_modes(panel, connector); - -	return ret; -} - -static enum drm_mode_status -mdp4_lvds_connector_mode_valid(struct drm_connector *connector, -			       const struct drm_display_mode *mode) -{ -	struct mdp4_lvds_connector *mdp4_lvds_connector = -			to_mdp4_lvds_connector(connector); -	struct drm_encoder *encoder = mdp4_lvds_connector->encoder; -	long actual, requested; - -	requested = 1000 * mode->clock; -	actual = mdp4_lcdc_round_pixclk(encoder, requested); - -	DBG("requested=%ld, actual=%ld", requested, actual); - -	if (actual != requested) -		return MODE_CLOCK_RANGE; - -	return MODE_OK; -} - -static const struct drm_connector_funcs mdp4_lvds_connector_funcs = { -	.detect = mdp4_lvds_connector_detect, -	.fill_modes = drm_helper_probe_single_connector_modes, -	.destroy = mdp4_lvds_connector_destroy, -	.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 const struct drm_connector_helper_funcs mdp4_lvds_connector_helper_funcs = { -	.get_modes = mdp4_lvds_connector_get_modes, -	.mode_valid = mdp4_lvds_connector_mode_valid, -}; - -/* initialize connector */ -struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev, -		struct device_node *panel_node, struct drm_encoder *encoder) -{ -	struct drm_connector *connector = NULL; -	struct mdp4_lvds_connector *mdp4_lvds_connector; - -	mdp4_lvds_connector = kzalloc(sizeof(*mdp4_lvds_connector), GFP_KERNEL); -	if (!mdp4_lvds_connector) -		return ERR_PTR(-ENOMEM); - -	mdp4_lvds_connector->encoder = encoder; -	mdp4_lvds_connector->panel_node = panel_node; - -	connector = &mdp4_lvds_connector->base; - -	drm_connector_init(dev, connector, &mdp4_lvds_connector_funcs, -			DRM_MODE_CONNECTOR_LVDS); -	drm_connector_helper_add(connector, &mdp4_lvds_connector_helper_funcs); - -	connector->polled = 0; - -	connector->interlace_allowed = 0; -	connector->doublescan_allowed = 0; - -	drm_connector_attach_encoder(connector, encoder); - -	return connector; -} diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c index ab8c0c187fb2..fa2c29470510 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c @@ -122,40 +122,59 @@ static const struct clk_ops mpd4_lvds_pll_ops = {  	.set_rate = mpd4_lvds_pll_set_rate,  }; -static const char *mpd4_lvds_pll_parents[] = { -	"pxo", +static const struct clk_parent_data mpd4_lvds_pll_parents[] = { +	{ .fw_name = "pxo", .name = "pxo", },  };  static struct clk_init_data pll_init = {  	.name = "mpd4_lvds_pll",  	.ops = &mpd4_lvds_pll_ops, -	.parent_names = mpd4_lvds_pll_parents, +	.parent_data = mpd4_lvds_pll_parents,  	.num_parents = ARRAY_SIZE(mpd4_lvds_pll_parents),  }; -struct clk *mpd4_lvds_pll_init(struct drm_device *dev) +static struct clk_hw *mpd4_lvds_pll_init(struct drm_device *dev)  {  	struct mdp4_lvds_pll *lvds_pll; -	struct clk *clk;  	int ret;  	lvds_pll = devm_kzalloc(dev->dev, sizeof(*lvds_pll), GFP_KERNEL); -	if (!lvds_pll) { -		ret = -ENOMEM; -		goto fail; -	} +	if (!lvds_pll) +		return ERR_PTR(-ENOMEM);  	lvds_pll->dev = dev;  	lvds_pll->pll_hw.init = &pll_init; -	clk = devm_clk_register(dev->dev, &lvds_pll->pll_hw); -	if (IS_ERR(clk)) { -		ret = PTR_ERR(clk); -		goto fail; +	ret = devm_clk_hw_register(dev->dev, &lvds_pll->pll_hw); +	if (ret) +		return ERR_PTR(ret); + +	ret = devm_of_clk_add_hw_provider(dev->dev, of_clk_hw_simple_get, &lvds_pll->pll_hw); +	if (ret) +		return ERR_PTR(ret); + +	return &lvds_pll->pll_hw; +} + +struct clk *mpd4_get_lcdc_clock(struct drm_device *dev) +{ +	struct clk_hw *hw; +	struct clk *clk; + + +	/* TODO: do we need different pll in other cases? */ +	hw = mpd4_lvds_pll_init(dev); +	if (IS_ERR(hw)) { +		DRM_DEV_ERROR(dev->dev, "failed to register LVDS PLL\n"); +		return ERR_CAST(hw);  	} -	return clk; +	clk = devm_clk_get(dev->dev, "lcdc_clk"); +	if (clk == ERR_PTR(-ENOENT)) { +		drm_warn(dev, "can't get LCDC clock, using PLL directly\n"); -fail: -	return ERR_PTR(ret); +		return devm_clk_hw_get_clk(dev->dev, hw, "lcdc_clk"); +	} + +	return clk;  } diff --git a/drivers/gpu/drm/msm/dp/dp_audio.c b/drivers/gpu/drm/msm/dp/dp_audio.c index 70fdc9fe228a..f8bfb908f9b4 100644 --- a/drivers/gpu/drm/msm/dp/dp_audio.c +++ b/drivers/gpu/drm/msm/dp/dp_audio.c @@ -13,13 +13,13 @@  #include "dp_catalog.h"  #include "dp_audio.h" +#include "dp_drm.h"  #include "dp_panel.h"  #include "dp_reg.h"  #include "dp_display.h"  #include "dp_utils.h"  struct msm_dp_audio_private { -	struct platform_device *audio_pdev;  	struct platform_device *pdev;  	struct drm_device *drm_dev;  	struct msm_dp_catalog *catalog; @@ -160,24 +160,11 @@ static void msm_dp_audio_enable(struct msm_dp_audio_private *audio, bool enable)  	msm_dp_catalog_audio_enable(catalog, enable);  } -static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device *pdev) +static struct msm_dp_audio_private *msm_dp_audio_get_data(struct msm_dp *msm_dp_display)  {  	struct msm_dp_audio *msm_dp_audio; -	struct msm_dp *msm_dp_display; - -	if (!pdev) { -		DRM_ERROR("invalid input\n"); -		return ERR_PTR(-ENODEV); -	} - -	msm_dp_display = platform_get_drvdata(pdev); -	if (!msm_dp_display) { -		DRM_ERROR("invalid input\n"); -		return ERR_PTR(-ENODEV); -	}  	msm_dp_audio = msm_dp_display->msm_dp_audio; -  	if (!msm_dp_audio) {  		DRM_ERROR("invalid msm_dp_audio data\n");  		return ERR_PTR(-EINVAL); @@ -186,68 +173,16 @@ static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device  	return container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);  } -static int msm_dp_audio_hook_plugged_cb(struct device *dev, void *data, -		hdmi_codec_plugged_cb fn, -		struct device *codec_dev) -{ - -	struct platform_device *pdev; -	struct msm_dp *msm_dp_display; - -	pdev = to_platform_device(dev); -	if (!pdev) { -		pr_err("invalid input\n"); -		return -ENODEV; -	} - -	msm_dp_display = platform_get_drvdata(pdev); -	if (!msm_dp_display) { -		pr_err("invalid input\n"); -		return -ENODEV; -	} - -	return msm_dp_display_set_plugged_cb(msm_dp_display, fn, codec_dev); -} - -static int msm_dp_audio_get_eld(struct device *dev, -	void *data, uint8_t *buf, size_t len) -{ -	struct platform_device *pdev; -	struct msm_dp *msm_dp_display; - -	pdev = to_platform_device(dev); - -	if (!pdev) { -		DRM_ERROR("invalid input\n"); -		return -ENODEV; -	} - -	msm_dp_display = platform_get_drvdata(pdev); -	if (!msm_dp_display) { -		DRM_ERROR("invalid input\n"); -		return -ENODEV; -	} - -	mutex_lock(&msm_dp_display->connector->eld_mutex); -	memcpy(buf, msm_dp_display->connector->eld, -		min(sizeof(msm_dp_display->connector->eld), len)); -	mutex_unlock(&msm_dp_display->connector->eld_mutex); - -	return 0; -} - -int msm_dp_audio_hw_params(struct device *dev, -	void *data, -	struct hdmi_codec_daifmt *daifmt, -	struct hdmi_codec_params *params) +int msm_dp_audio_prepare(struct drm_connector *connector, +			 struct drm_bridge *bridge, +			 struct hdmi_codec_daifmt *daifmt, +			 struct hdmi_codec_params *params)  {  	int rc = 0;  	struct msm_dp_audio_private *audio; -	struct platform_device *pdev;  	struct msm_dp *msm_dp_display; -	pdev = to_platform_device(dev); -	msm_dp_display = platform_get_drvdata(pdev); +	msm_dp_display = to_dp_bridge(bridge)->msm_dp_display;  	/*  	 * there could be cases where sound card can be opened even @@ -262,7 +197,7 @@ int msm_dp_audio_hw_params(struct device *dev,  		goto end;  	} -	audio = msm_dp_audio_get_data(pdev); +	audio = msm_dp_audio_get_data(msm_dp_display);  	if (IS_ERR(audio)) {  		rc = PTR_ERR(audio);  		goto end; @@ -281,15 +216,14 @@ end:  	return rc;  } -static void msm_dp_audio_shutdown(struct device *dev, void *data) +void msm_dp_audio_shutdown(struct drm_connector *connector, +			   struct drm_bridge *bridge)  {  	struct msm_dp_audio_private *audio; -	struct platform_device *pdev;  	struct msm_dp *msm_dp_display; -	pdev = to_platform_device(dev); -	msm_dp_display = platform_get_drvdata(pdev); -	audio = msm_dp_audio_get_data(pdev); +	msm_dp_display = to_dp_bridge(bridge)->msm_dp_display; +	audio = msm_dp_audio_get_data(msm_dp_display);  	if (IS_ERR(audio)) {  		DRM_ERROR("failed to get audio data\n");  		return; @@ -311,47 +245,6 @@ static void msm_dp_audio_shutdown(struct device *dev, void *data)  	msm_dp_display_signal_audio_complete(msm_dp_display);  } -static const struct hdmi_codec_ops msm_dp_audio_codec_ops = { -	.hw_params = msm_dp_audio_hw_params, -	.audio_shutdown = msm_dp_audio_shutdown, -	.get_eld = msm_dp_audio_get_eld, -	.hook_plugged_cb = msm_dp_audio_hook_plugged_cb, -}; - -static struct hdmi_codec_pdata codec_data = { -	.ops = &msm_dp_audio_codec_ops, -	.max_i2s_channels = 8, -	.i2s = 1, -}; - -void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio) -{ -	struct msm_dp_audio_private *audio_priv; - -	audio_priv = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio); - -	if (audio_priv->audio_pdev) { -		platform_device_unregister(audio_priv->audio_pdev); -		audio_priv->audio_pdev = NULL; -	} -} - -int msm_dp_register_audio_driver(struct device *dev, -		struct msm_dp_audio *msm_dp_audio) -{ -	struct msm_dp_audio_private *audio_priv; - -	audio_priv = container_of(msm_dp_audio, -			struct msm_dp_audio_private, msm_dp_audio); - -	audio_priv->audio_pdev = platform_device_register_data(dev, -						HDMI_CODEC_DRV_NAME, -						PLATFORM_DEVID_AUTO, -						&codec_data, -						sizeof(codec_data)); -	return PTR_ERR_OR_ZERO(audio_priv->audio_pdev); -} -  struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,  			struct msm_dp_catalog *catalog)  { diff --git a/drivers/gpu/drm/msm/dp/dp_audio.h b/drivers/gpu/drm/msm/dp/dp_audio.h index beea34cbab77..58fc14693e48 100644 --- a/drivers/gpu/drm/msm/dp/dp_audio.h +++ b/drivers/gpu/drm/msm/dp/dp_audio.h @@ -36,23 +36,6 @@ struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,  			struct msm_dp_catalog *catalog);  /** - * msm_dp_register_audio_driver() - * - * Registers DP device with hdmi_codec interface. - * - * @dev: DP device instance. - * @msm_dp_audio: an instance of msm_dp_audio module. - * - * - * Returns the error code in case of failure, otherwise - * zero on success. - */ -int msm_dp_register_audio_driver(struct device *dev, -		struct msm_dp_audio *msm_dp_audio); - -void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio); - -/**   * msm_dp_audio_put()   *   * Cleans the msm_dp_audio instance. @@ -61,10 +44,12 @@ void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm   */  void msm_dp_audio_put(struct msm_dp_audio *msm_dp_audio); -int msm_dp_audio_hw_params(struct device *dev, -	void *data, -	struct hdmi_codec_daifmt *daifmt, -	struct hdmi_codec_params *params); +int msm_dp_audio_prepare(struct drm_connector *connector, +			 struct drm_bridge *bridge, +			 struct hdmi_codec_daifmt *daifmt, +			 struct hdmi_codec_params *params); +void msm_dp_audio_shutdown(struct drm_connector *connector, +			   struct drm_bridge *bridge);  #endif /* _DP_AUDIO_H_ */ diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 69a26bb5fabd..a50bfafbb4ea 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1034,10 +1034,12 @@ static int msm_dp_ctrl_set_vx_px(struct msm_dp_ctrl_private *ctrl,  	return 0;  } -static int msm_dp_ctrl_update_vx_px(struct msm_dp_ctrl_private *ctrl) +static int msm_dp_ctrl_update_phy_vx_px(struct msm_dp_ctrl_private *ctrl, +					enum drm_dp_phy dp_phy)  {  	struct msm_dp_link *link = ctrl->link; -	int ret = 0, lane, lane_cnt; +	int lane, lane_cnt, reg; +	int ret = 0;  	u8 buf[4];  	u32 max_level_reached = 0;  	u32 voltage_swing_level = link->phy_params.v_level; @@ -1075,8 +1077,13 @@ static int msm_dp_ctrl_update_vx_px(struct msm_dp_ctrl_private *ctrl)  	drm_dbg_dp(ctrl->drm_dev, "sink: p|v=0x%x\n",  			voltage_swing_level | pre_emphasis_level); -	ret = drm_dp_dpcd_write(ctrl->aux, DP_TRAINING_LANE0_SET, -					buf, lane_cnt); + +	if (dp_phy == DP_PHY_DPRX) +		reg = DP_TRAINING_LANE0_SET; +	else +		reg = DP_TRAINING_LANE0_SET_PHY_REPEATER(dp_phy); + +	ret = drm_dp_dpcd_write(ctrl->aux, reg, buf, lane_cnt);  	if (ret == lane_cnt)  		ret = 0; @@ -1084,9 +1091,10 @@ static int msm_dp_ctrl_update_vx_px(struct msm_dp_ctrl_private *ctrl)  }  static bool msm_dp_ctrl_train_pattern_set(struct msm_dp_ctrl_private *ctrl, -		u8 pattern) +		u8 pattern, enum drm_dp_phy dp_phy)  {  	u8 buf; +	int reg;  	int ret = 0;  	drm_dbg_dp(ctrl->drm_dev, "sink: pattern=%x\n", pattern); @@ -1096,17 +1104,26 @@ static bool msm_dp_ctrl_train_pattern_set(struct msm_dp_ctrl_private *ctrl,  	if (pattern && pattern != DP_TRAINING_PATTERN_4)  		buf |= DP_LINK_SCRAMBLING_DISABLE; -	ret = drm_dp_dpcd_writeb(ctrl->aux, DP_TRAINING_PATTERN_SET, buf); +	if (dp_phy == DP_PHY_DPRX) +		reg = DP_TRAINING_PATTERN_SET; +	else +		reg = DP_TRAINING_PATTERN_SET_PHY_REPEATER(dp_phy); + +	ret = drm_dp_dpcd_writeb(ctrl->aux, reg, buf);  	return ret == 1;  }  static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl, -			int *training_step) +			int *training_step, enum drm_dp_phy dp_phy)  { +	int delay_us;  	int tries, old_v_level, ret = 0;  	u8 link_status[DP_LINK_STATUS_SIZE];  	int const maximum_retries = 4; +	delay_us = drm_dp_read_clock_recovery_delay(ctrl->aux, +						    ctrl->panel->dpcd, dp_phy, false); +  	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);  	*training_step = DP_TRAINING_1; @@ -1115,18 +1132,19 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,  	if (ret)  		return ret;  	msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 | -		DP_LINK_SCRAMBLING_DISABLE); +		DP_LINK_SCRAMBLING_DISABLE, dp_phy); -	ret = msm_dp_ctrl_update_vx_px(ctrl); +	msm_dp_link_reset_phy_params_vx_px(ctrl->link); +	ret = msm_dp_ctrl_update_phy_vx_px(ctrl, dp_phy);  	if (ret)  		return ret;  	tries = 0;  	old_v_level = ctrl->link->phy_params.v_level;  	for (tries = 0; tries < maximum_retries; tries++) { -		drm_dp_link_train_clock_recovery_delay(ctrl->aux, ctrl->panel->dpcd); +		fsleep(delay_us); -		ret = drm_dp_dpcd_read_link_status(ctrl->aux, link_status); +		ret = drm_dp_dpcd_read_phy_link_status(ctrl->aux, dp_phy, link_status);  		if (ret)  			return ret; @@ -1147,7 +1165,7 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,  		}  		msm_dp_link_adjust_levels(ctrl->link, link_status); -		ret = msm_dp_ctrl_update_vx_px(ctrl); +		ret = msm_dp_ctrl_update_phy_vx_px(ctrl, dp_phy);  		if (ret)  			return ret;  	} @@ -1199,21 +1217,31 @@ static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl)  	return 0;  } -static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl) +static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl, +					       enum drm_dp_phy dp_phy)  { -	msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE); -	drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd); +	int delay_us; + +	msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE, dp_phy); + +	delay_us = drm_dp_read_channel_eq_delay(ctrl->aux, +						ctrl->panel->dpcd, dp_phy, false); +	fsleep(delay_us);  }  static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl, -			int *training_step) +			int *training_step, enum drm_dp_phy dp_phy)  { +	int delay_us;  	int tries = 0, ret = 0;  	u8 pattern;  	u32 state_ctrl_bit;  	int const maximum_retries = 5;  	u8 link_status[DP_LINK_STATUS_SIZE]; +	delay_us = drm_dp_read_channel_eq_delay(ctrl->aux, +						ctrl->panel->dpcd, dp_phy, false); +  	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);  	*training_step = DP_TRAINING_2; @@ -1233,12 +1261,12 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,  	if (ret)  		return ret; -	msm_dp_ctrl_train_pattern_set(ctrl, pattern); +	msm_dp_ctrl_train_pattern_set(ctrl, pattern, dp_phy);  	for (tries = 0; tries <= maximum_retries; tries++) { -		drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd); +		fsleep(delay_us); -		ret = drm_dp_dpcd_read_link_status(ctrl->aux, link_status); +		ret = drm_dp_dpcd_read_phy_link_status(ctrl->aux, dp_phy, link_status);  		if (ret)  			return ret; @@ -1248,7 +1276,7 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,  		}  		msm_dp_link_adjust_levels(ctrl->link, link_status); -		ret = msm_dp_ctrl_update_vx_px(ctrl); +		ret = msm_dp_ctrl_update_phy_vx_px(ctrl, dp_phy);  		if (ret)  			return ret; @@ -1257,9 +1285,32 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,  	return -ETIMEDOUT;  } +static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl, +				      int *training_step, enum drm_dp_phy dp_phy) +{ +	int ret; + +	ret = msm_dp_ctrl_link_train_1(ctrl, training_step, dp_phy); +	if (ret) { +		DRM_ERROR("link training #1 on phy %d failed. ret=%d\n", dp_phy, ret); +		return ret; +	} +	drm_dbg_dp(ctrl->drm_dev, "link training #1 on phy %d successful\n", dp_phy); + +	ret = msm_dp_ctrl_link_train_2(ctrl, training_step, dp_phy); +	if (ret) { +		DRM_ERROR("link training #2 on phy %d failed. ret=%d\n", dp_phy, ret); +		return ret; +	} +	drm_dbg_dp(ctrl->drm_dev, "link training #2 on phy %d successful\n", dp_phy); + +	return 0; +} +  static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,  			int *training_step)  { +	int i;  	int ret = 0;  	const u8 *dpcd = ctrl->panel->dpcd;  	u8 encoding[] = { 0, DP_SET_ANSI_8B10B }; @@ -1272,8 +1323,6 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,  	link_info.rate = ctrl->link->link_params.rate;  	link_info.capabilities = DP_LINK_CAP_ENHANCED_FRAMING; -	msm_dp_link_reset_phy_params_vx_px(ctrl->link); -  	msm_dp_aux_link_configure(ctrl->aux, &link_info);  	if (drm_dp_max_downspread(dpcd)) @@ -1288,24 +1337,27 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,  				&assr, 1);  	} -	ret = msm_dp_ctrl_link_train_1(ctrl, training_step); +	for (i = ctrl->link->lttpr_count - 1; i >= 0; i--) { +		enum drm_dp_phy dp_phy = DP_PHY_LTTPR(i); + +		ret = msm_dp_ctrl_link_train_1_2(ctrl, training_step, dp_phy); +		msm_dp_ctrl_clear_training_pattern(ctrl, dp_phy); + +		if (ret) +			break; +	} +  	if (ret) { -		DRM_ERROR("link training #1 failed. ret=%d\n", ret); +		DRM_ERROR("link training of LTTPR(s) failed. ret=%d\n", ret);  		goto end;  	} -	/* print success info as this is a result of user initiated action */ -	drm_dbg_dp(ctrl->drm_dev, "link training #1 successful\n"); - -	ret = msm_dp_ctrl_link_train_2(ctrl, training_step); +	ret = msm_dp_ctrl_link_train_1_2(ctrl, training_step, DP_PHY_DPRX);  	if (ret) { -		DRM_ERROR("link training #2 failed. ret=%d\n", ret); +		DRM_ERROR("link training on sink failed. ret=%d\n", ret);  		goto end;  	} -	/* print success info as this is a result of user initiated action */ -	drm_dbg_dp(ctrl->drm_dev, "link training #2 successful\n"); -  end:  	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0); @@ -1622,7 +1674,7 @@ static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl)  	if (ret)  		goto end; -	msm_dp_ctrl_clear_training_pattern(ctrl); +	msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);  	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO); @@ -1646,7 +1698,7 @@ static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl)  		return false;  	}  	msm_dp_catalog_ctrl_send_phy_pattern(ctrl->catalog, pattern_requested); -	msm_dp_ctrl_update_vx_px(ctrl); +	msm_dp_ctrl_update_phy_vx_px(ctrl, DP_PHY_DPRX);  	msm_dp_link_send_test_response(ctrl->link);  	pattern_sent = msm_dp_catalog_ctrl_read_phy_pattern(ctrl->catalog); @@ -1888,7 +1940,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)  			}  			/* stop link training before start re training  */ -			msm_dp_ctrl_clear_training_pattern(ctrl); +			msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);  		}  		rc = msm_dp_ctrl_reinitialize_mainlink(ctrl); @@ -1912,7 +1964,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)  		 * link training failed  		 * end txing train pattern here  		 */ -		msm_dp_ctrl_clear_training_pattern(ctrl); +		msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);  		msm_dp_ctrl_deinitialize_mainlink(ctrl);  		rc = -ECONNRESET; @@ -1983,7 +2035,7 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train  		msm_dp_ctrl_link_retrain(ctrl);  	/* stop txing train pattern to end link training */ -	msm_dp_ctrl_clear_training_pattern(ctrl); +	msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);  	/*  	 * Set up transfer unit values and set controller state to send diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index bbc47d86ae9e..386c4669c831 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -13,6 +13,7 @@  #include <linux/delay.h>  #include <linux/string_choices.h>  #include <drm/display/drm_dp_aux_bus.h> +#include <drm/display/drm_hdmi_audio_helper.h>  #include <drm/drm_edid.h>  #include "msm_drv.h" @@ -288,13 +289,6 @@ static int msm_dp_display_bind(struct device *dev, struct device *master,  		goto end;  	} - -	rc = msm_dp_register_audio_driver(dev, dp->audio); -	if (rc) { -		DRM_ERROR("Audio registration Dp failed\n"); -		goto end; -	} -  	rc = msm_dp_hpd_event_thread_start(dp);  	if (rc) {  		DRM_ERROR("Event thread create failed\n"); @@ -316,7 +310,6 @@ static void msm_dp_display_unbind(struct device *dev, struct device *master,  	of_dp_aux_depopulate_bus(dp->aux); -	msm_dp_unregister_audio_driver(dev, dp->audio);  	msm_dp_aux_unregister(dp->aux);  	dp->drm_dev = NULL;  	dp->aux->drm_dev = NULL; @@ -367,17 +360,21 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d  	return 0;  } -static void msm_dp_display_lttpr_init(struct msm_dp_display_private *dp) +static int msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 *dpcd)  { -	u8 lttpr_caps[DP_LTTPR_COMMON_CAP_SIZE]; -	int rc; +	int rc, lttpr_count; -	if (drm_dp_read_lttpr_common_caps(dp->aux, dp->panel->dpcd, lttpr_caps)) -		return; +	if (drm_dp_read_lttpr_common_caps(dp->aux, dpcd, dp->link->lttpr_common_caps)) +		return 0; -	rc = drm_dp_lttpr_init(dp->aux, drm_dp_lttpr_count(lttpr_caps)); -	if (rc) +	lttpr_count = drm_dp_lttpr_count(dp->link->lttpr_common_caps); +	rc = drm_dp_lttpr_init(dp->aux, lttpr_count); +	if (rc) {  		DRM_ERROR("failed to set LTTPRs transparency mode, rc=%d\n", rc); +		return 0; +	} + +	return lttpr_count;  }  static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) @@ -385,12 +382,17 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)  	struct drm_connector *connector = dp->msm_dp_display.connector;  	const struct drm_display_info *info = &connector->display_info;  	int rc = 0; +	u8 dpcd[DP_RECEIVER_CAP_SIZE]; -	rc = msm_dp_panel_read_sink_caps(dp->panel, connector); +	rc = drm_dp_read_dpcd_caps(dp->aux, dpcd);  	if (rc)  		goto end; -	msm_dp_display_lttpr_init(dp); +	dp->link->lttpr_count = msm_dp_display_lttpr_init(dp, dpcd); + +	rc = msm_dp_panel_read_sink_caps(dp->panel, connector); +	if (rc) +		goto end;  	msm_dp_link_process_request(dp->link); @@ -626,9 +628,9 @@ static void msm_dp_display_handle_plugged_change(struct msm_dp *msm_dp_display,  			struct msm_dp_display_private, msm_dp_display);  	/* notify audio subsystem only if sink supports audio */ -	if (msm_dp_display->plugged_cb && msm_dp_display->codec_dev && -			dp->audio_supported) -		msm_dp_display->plugged_cb(msm_dp_display->codec_dev, plugged); +	if (dp->audio_supported) +		drm_connector_hdmi_audio_plugged_notify(msm_dp_display->connector, +							plugged);  }  static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp, u32 data) @@ -907,19 +909,6 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp)  	return 0;  } -int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display, -		hdmi_codec_plugged_cb fn, struct device *codec_dev) -{ -	bool plugged; - -	msm_dp_display->plugged_cb = fn; -	msm_dp_display->codec_dev = codec_dev; -	plugged = msm_dp_display->link_ready; -	msm_dp_display_handle_plugged_change(msm_dp_display, plugged); - -	return 0; -} -  /**   * msm_dp_bridge_mode_valid - callback to determine if specified mode is valid   * @bridge: Pointer to drm bridge structure diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h index ecbc2d92f546..cc6e2cab36e9 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.h +++ b/drivers/gpu/drm/msm/dp/dp_display.h @@ -7,7 +7,6 @@  #define _DP_DISPLAY_H_  #include "dp_panel.h" -#include <sound/hdmi-codec.h>  #include "disp/msm_disp_snapshot.h"  #define DP_MAX_PIXEL_CLK_KHZ	675000 @@ -15,7 +14,6 @@  struct msm_dp {  	struct drm_device *drm_dev;  	struct platform_device *pdev; -	struct device *codec_dev;  	struct drm_connector *connector;  	struct drm_bridge *next_bridge;  	bool link_ready; @@ -25,14 +23,10 @@ struct msm_dp {  	bool is_edp;  	bool internal_hpd; -	hdmi_codec_plugged_cb plugged_cb; -  	struct msm_dp_audio *msm_dp_audio;  	bool psr_supported;  }; -int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display, -		hdmi_codec_plugged_cb fn, struct device *codec_dev);  int msm_dp_display_get_modes(struct msm_dp *msm_dp_display);  bool msm_dp_display_check_video_test(struct msm_dp *msm_dp_display);  int msm_dp_display_get_test_bpp(struct msm_dp *msm_dp_display); diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index 293f4745f1e2..f222d7ccaa88 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.c +++ b/drivers/gpu/drm/msm/dp/dp_drm.c @@ -12,6 +12,7 @@  #include "msm_drv.h"  #include "msm_kms.h" +#include "dp_audio.h"  #include "dp_drm.h"  /** @@ -114,6 +115,9 @@ static const struct drm_bridge_funcs msm_dp_bridge_ops = {  	.hpd_disable  = msm_dp_bridge_hpd_disable,  	.hpd_notify   = msm_dp_bridge_hpd_notify,  	.debugfs_init = msm_dp_bridge_debugfs_init, + +	.dp_audio_prepare = msm_dp_audio_prepare, +	.dp_audio_shutdown = msm_dp_audio_shutdown,  };  static int msm_edp_bridge_atomic_check(struct drm_bridge *drm_bridge, @@ -321,9 +325,13 @@ int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev,  	 */  	if (!msm_dp_display->is_edp) {  		bridge->ops = +			DRM_BRIDGE_OP_DP_AUDIO |  			DRM_BRIDGE_OP_DETECT |  			DRM_BRIDGE_OP_HPD |  			DRM_BRIDGE_OP_MODES; +		bridge->hdmi_audio_dev = &msm_dp_display->pdev->dev; +		bridge->hdmi_audio_max_i2s_playback_channels = 8; +		bridge->hdmi_audio_dai_port = -1;  	}  	rc = devm_drm_bridge_add(dev->dev, bridge); diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h index 8db5d5698a97..ba47c6d19fbf 100644 --- a/drivers/gpu/drm/msm/dp/dp_link.h +++ b/drivers/gpu/drm/msm/dp/dp_link.h @@ -7,6 +7,7 @@  #define _DP_LINK_H_  #include "dp_aux.h" +#include <drm/display/drm_dp_helper.h>  #define DS_PORT_STATUS_CHANGED 0x200  #define DP_TEST_BIT_DEPTH_UNKNOWN 0xFFFFFFFF @@ -60,6 +61,9 @@ struct msm_dp_link_phy_params {  };  struct msm_dp_link { +	u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE]; +	int lttpr_count; +  	u32 sink_request;  	u32 test_response; diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c index 92415bf8aa16..4e8ab75c771b 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.c +++ b/drivers/gpu/drm/msm/dp/dp_panel.c @@ -47,7 +47,7 @@ static void msm_dp_panel_read_psr_cap(struct msm_dp_panel_private *panel)  static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)  { -	int rc; +	int rc, max_lttpr_lanes, max_lttpr_rate;  	struct msm_dp_panel_private *panel;  	struct msm_dp_link_info *link_info;  	u8 *dpcd, major, minor; @@ -75,6 +75,16 @@ static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)  	if (link_info->rate > msm_dp_panel->max_dp_link_rate)  		link_info->rate = msm_dp_panel->max_dp_link_rate; +	/* Limit data lanes from LTTPR capabilities, if any */ +	max_lttpr_lanes = drm_dp_lttpr_max_lane_count(panel->link->lttpr_common_caps); +	if (max_lttpr_lanes && max_lttpr_lanes < link_info->num_lanes) +		link_info->num_lanes = max_lttpr_lanes; + +	/* Limit link rate from LTTPR capabilities, if any */ +	max_lttpr_rate = drm_dp_lttpr_max_link_rate(panel->link->lttpr_common_caps); +	if (max_lttpr_rate && max_lttpr_rate < link_info->rate) +		link_info->rate = max_lttpr_rate; +  	drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);  	drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);  	drm_dbg_dp(panel->drm_dev, "lane_count=%d\n", link_info->num_lanes); diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c index 7754dcec33d0..7675558ae2e5 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c @@ -221,6 +221,22 @@ static const struct msm_dsi_config sc7280_dsi_cfg = {  	},  }; +static const struct regulator_bulk_data sa8775p_dsi_regulators[] = { +	{ .supply = "vdda", .init_load_uA = 8300 },    /* 1.2 V */ +	{ .supply = "refgen" }, +}; + +static const struct msm_dsi_config sa8775p_dsi_cfg = { +	.io_offset = DSI_6G_REG_SHIFT, +	.regulator_data = sa8775p_dsi_regulators, +	.num_regulators = ARRAY_SIZE(sa8775p_dsi_regulators), +	.bus_clk_names = dsi_v2_4_clk_names, +	.num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names), +	.io_start = { +		{ 0xae94000, 0xae96000 }, +	}, +}; +  static const struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {  	.link_clk_set_rate = dsi_link_clk_set_rate_v2,  	.link_clk_enable = dsi_link_clk_enable_v2, @@ -294,6 +310,8 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {  		&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},  	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_0,  		&sc7280_dsi_cfg, &msm_dsi_6g_v2_host_ops}, +	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_1, +		&sa8775p_dsi_cfg, &msm_dsi_6g_v2_host_ops},  	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_6_0,  		&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},  	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_7_0, diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h index 120cb65164c1..65b0705fac0e 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h @@ -27,6 +27,7 @@  #define MSM_DSI_6G_VER_MINOR_V2_4_0	0x20040000  #define MSM_DSI_6G_VER_MINOR_V2_4_1	0x20040001  #define MSM_DSI_6G_VER_MINOR_V2_5_0	0x20050000 +#define MSM_DSI_6G_VER_MINOR_V2_5_1	0x20050001  #define MSM_DSI_6G_VER_MINOR_V2_6_0	0x20060000  #define MSM_DSI_6G_VER_MINOR_V2_7_0	0x20070000  #define MSM_DSI_6G_VER_MINOR_V2_8_0	0x20080000 diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index c0bcc6828963..5973d7325699 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -581,6 +581,10 @@ static const struct of_device_id dsi_phy_dt_match[] = {  	  .data = &dsi_phy_7nm_cfgs },  	{ .compatible = "qcom,dsi-phy-7nm-8150",  	  .data = &dsi_phy_7nm_8150_cfgs }, +	{ .compatible = "qcom,sa8775p-dsi-phy-5nm", +	  .data = &dsi_phy_5nm_8775p_cfgs }, +	{ .compatible = "qcom,sar2130p-dsi-phy-5nm", +	  .data = &dsi_phy_5nm_sar2130p_cfgs },  	{ .compatible = "qcom,sc7280-dsi-phy-7nm",  	  .data = &dsi_phy_7nm_7280_cfgs },  	{ .compatible = "qcom,sm6375-dsi-phy-7nm", diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 1925418d9999..7ea608f620fe 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -59,6 +59,8 @@ extern const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs;  extern const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs;  extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs;  extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs; +extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8775p_cfgs; +extern const struct msm_dsi_phy_cfg dsi_phy_5nm_sar2130p_cfgs;  extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs;  extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8650_cfgs; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index a92decbee5b5..c19890358b74 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -1147,6 +1147,10 @@ static const struct regulator_bulk_data dsi_phy_7nm_37750uA_regulators[] = {  	{ .supply = "vdds", .init_load_uA = 37550 },  }; +static const struct regulator_bulk_data dsi_phy_7nm_48000uA_regulators[] = { +	{ .supply = "vdds", .init_load_uA = 48000 }, +}; +  static const struct regulator_bulk_data dsi_phy_7nm_98000uA_regulators[] = {  	{ .supply = "vdds", .init_load_uA = 98000 },  }; @@ -1289,6 +1293,52 @@ const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs = {  	.quirks = DSI_PHY_7NM_QUIRK_V4_3,  }; +const struct msm_dsi_phy_cfg dsi_phy_5nm_8775p_cfgs = { +	.has_phy_lane = true, +	.regulator_data = dsi_phy_7nm_48000uA_regulators, +	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_48000uA_regulators), +	.ops = { +		.enable = dsi_7nm_phy_enable, +		.disable = dsi_7nm_phy_disable, +		.pll_init = dsi_pll_7nm_init, +		.save_pll_state = dsi_7nm_pll_save_state, +		.restore_pll_state = dsi_7nm_pll_restore_state, +		.set_continuous_clock = dsi_7nm_set_continuous_clock, +		}, +	.min_pll_rate = 600000000UL, +#ifdef CONFIG_64BIT +	.max_pll_rate = 5000000000UL, +#else +	.max_pll_rate = ULONG_MAX, +#endif +	.io_start = { 0xae94400, 0xae96400 }, +	.num_dsi_phy = 2, +	.quirks = DSI_PHY_7NM_QUIRK_V4_2, +}; + +const struct msm_dsi_phy_cfg dsi_phy_5nm_sar2130p_cfgs = { +	.has_phy_lane = true, +	.regulator_data = dsi_phy_7nm_97800uA_regulators, +	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_97800uA_regulators), +	.ops = { +		.enable = dsi_7nm_phy_enable, +		.disable = dsi_7nm_phy_disable, +		.pll_init = dsi_pll_7nm_init, +		.save_pll_state = dsi_7nm_pll_save_state, +		.restore_pll_state = dsi_7nm_pll_restore_state, +		.set_continuous_clock = dsi_7nm_set_continuous_clock, +	}, +	.min_pll_rate = 600000000UL, +#ifdef CONFIG_64BIT +	.max_pll_rate = 5000000000UL, +#else +	.max_pll_rate = ULONG_MAX, +#endif +	.io_start = { 0xae95000, 0xae97000 }, +	.num_dsi_phy = 2, +	.quirks = DSI_PHY_7NM_QUIRK_V5_2, +}; +  const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs = {  	.has_phy_lane = true,  	.regulator_data = dsi_phy_7nm_98400uA_regulators, diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 248541ff4492..2fd388b892dc 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -8,6 +8,7 @@  #include <linux/gpio/consumer.h>  #include <linux/of_irq.h>  #include <linux/of_platform.h> +#include <linux/pinctrl/consumer.h>  #include <linux/platform_device.h>  #include <drm/drm_bridge_connector.h> @@ -199,12 +200,6 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,  		goto fail;  	} -	ret = msm_hdmi_hpd_enable(hdmi->bridge); -	if (ret < 0) { -		DRM_DEV_ERROR(&hdmi->pdev->dev, "failed to enable HPD: %d\n", ret); -		goto fail; -	} -  	return 0;  fail: @@ -220,28 +215,24 @@ fail:   * The hdmi device:   */ -#define HDMI_CFG(item, entry) \ -	.item ## _names = item ##_names_ ## entry, \ -	.item ## _cnt   = ARRAY_SIZE(item ## _names_ ## entry) - -static const char *hpd_reg_names_8960[] = {"core-vdda"}; -static const char *hpd_clk_names_8960[] = {"core", "master_iface", "slave_iface"}; +static const char * const pwr_reg_names_8960[] = {"core-vdda"}; +static const char * const pwr_clk_names_8960[] = {"core", "master_iface", "slave_iface"};  static const struct hdmi_platform_config hdmi_tx_8960_config = { -		HDMI_CFG(hpd_reg, 8960), -		HDMI_CFG(hpd_clk, 8960), +	.pwr_reg_names = pwr_reg_names_8960, +	.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names_8960), +	.pwr_clk_names = pwr_clk_names_8960, +	.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names_8960),  }; -static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"}; -static const char *pwr_clk_names_8x74[] = {"extp", "alt_iface"}; -static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core"}; -static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0}; +static const char * const pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"}; +static const char * const pwr_clk_names_8x74[] = {"iface", "core", "mdp_core", "alt_iface"};  static const struct hdmi_platform_config hdmi_tx_8974_config = { -		HDMI_CFG(pwr_reg, 8x74), -		HDMI_CFG(pwr_clk, 8x74), -		HDMI_CFG(hpd_clk, 8x74), -		.hpd_freq      = hpd_clk_freq_8x74, +	.pwr_reg_names = pwr_reg_names_8x74, +	.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names_8x74), +	.pwr_clk_names = pwr_clk_names_8x74, +	.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names_8x74),  };  static int msm_hdmi_bind(struct device *dev, struct device *master, void *data) @@ -264,9 +255,6 @@ static void msm_hdmi_unbind(struct device *dev, struct device *master,  	struct msm_drm_private *priv = dev_get_drvdata(master);  	if (priv->hdmi) { -		if (priv->hdmi->bridge) -			msm_hdmi_hpd_disable(priv->hdmi); -  		msm_hdmi_destroy(priv->hdmi);  		priv->hdmi = NULL;  	} @@ -296,6 +284,7 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)  	hdmi->pdev = pdev;  	hdmi->config = config;  	spin_lock_init(&hdmi->reg_lock); +	mutex_init(&hdmi->state_mutex);  	ret = drm_of_find_panel_or_bridge(pdev->dev.of_node, 1, 0, NULL, &hdmi->next_bridge);  	if (ret && ret != -ENODEV) @@ -322,20 +311,6 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)  	if (hdmi->irq < 0)  		return hdmi->irq; -	hdmi->hpd_regs = devm_kcalloc(&pdev->dev, -				      config->hpd_reg_cnt, -				      sizeof(hdmi->hpd_regs[0]), -				      GFP_KERNEL); -	if (!hdmi->hpd_regs) -		return -ENOMEM; - -	for (i = 0; i < config->hpd_reg_cnt; i++) -		hdmi->hpd_regs[i].supply = config->hpd_reg_names[i]; - -	ret = devm_regulator_bulk_get(&pdev->dev, config->hpd_reg_cnt, hdmi->hpd_regs); -	if (ret) -		return dev_err_probe(dev, ret, "failed to get hpd regulators\n"); -  	hdmi->pwr_regs = devm_kcalloc(&pdev->dev,  				      config->pwr_reg_cnt,  				      sizeof(hdmi->pwr_regs[0]), @@ -350,25 +325,6 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)  	if (ret)  		return dev_err_probe(dev, ret, "failed to get pwr regulators\n"); -	hdmi->hpd_clks = devm_kcalloc(&pdev->dev, -				      config->hpd_clk_cnt, -				      sizeof(hdmi->hpd_clks[0]), -				      GFP_KERNEL); -	if (!hdmi->hpd_clks) -		return -ENOMEM; - -	for (i = 0; i < config->hpd_clk_cnt; i++) { -		struct clk *clk; - -		clk = msm_clk_get(pdev, config->hpd_clk_names[i]); -		if (IS_ERR(clk)) -			return dev_err_probe(dev, PTR_ERR(clk), -					     "failed to get hpd clk: %s\n", -					     config->hpd_clk_names[i]); - -		hdmi->hpd_clks[i] = clk; -	} -  	hdmi->pwr_clks = devm_kcalloc(&pdev->dev,  				      config->pwr_clk_cnt,  				      sizeof(hdmi->pwr_clks[0]), @@ -376,17 +332,17 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)  	if (!hdmi->pwr_clks)  		return -ENOMEM; -	for (i = 0; i < config->pwr_clk_cnt; i++) { -		struct clk *clk; +	for (i = 0; i < config->pwr_clk_cnt; i++) +		hdmi->pwr_clks[i].id = config->pwr_clk_names[i]; -		clk = msm_clk_get(pdev, config->pwr_clk_names[i]); -		if (IS_ERR(clk)) -			return dev_err_probe(dev, PTR_ERR(clk), -					     "failed to get pwr clk: %s\n", -					     config->pwr_clk_names[i]); +	ret = devm_clk_bulk_get(&pdev->dev, config->pwr_clk_cnt, hdmi->pwr_clks); +	if (ret) +		return ret; -		hdmi->pwr_clks[i] = clk; -	} +	hdmi->extp_clk = devm_clk_get_optional(&pdev->dev, "extp"); +	if (IS_ERR(hdmi->extp_clk)) +		return dev_err_probe(dev, PTR_ERR(hdmi->extp_clk), +				     "failed to get extp clock\n");  	hdmi->hpd_gpiod = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN);  	/* This will catch e.g. -EPROBE_DEFER */ @@ -432,6 +388,48 @@ static void msm_hdmi_dev_remove(struct platform_device *pdev)  	msm_hdmi_put_phy(hdmi);  } +static int msm_hdmi_runtime_suspend(struct device *dev) +{ +	struct hdmi *hdmi = dev_get_drvdata(dev); +	const struct hdmi_platform_config *config = hdmi->config; + +	clk_bulk_disable_unprepare(config->pwr_clk_cnt, hdmi->pwr_clks); + +	pinctrl_pm_select_sleep_state(dev); + +	regulator_bulk_disable(config->pwr_reg_cnt, hdmi->pwr_regs); + +	return 0; +} + +static int msm_hdmi_runtime_resume(struct device *dev) +{ +	struct hdmi *hdmi = dev_get_drvdata(dev); +	const struct hdmi_platform_config *config = hdmi->config; +	int ret; + +	ret = regulator_bulk_enable(config->pwr_reg_cnt, hdmi->pwr_regs); +	if (ret) +		return ret; + +	ret = pinctrl_pm_select_default_state(dev); +	if (ret) +		goto fail; + +	ret = clk_bulk_prepare_enable(config->pwr_clk_cnt, hdmi->pwr_clks); +	if (ret) +		goto fail; + +	return 0; + +fail: +	pinctrl_pm_select_sleep_state(dev); + +	return ret; +} + +DEFINE_RUNTIME_DEV_PM_OPS(msm_hdmi_pm_ops, msm_hdmi_runtime_suspend, msm_hdmi_runtime_resume, NULL); +  static const struct of_device_id msm_hdmi_dt_match[] = {  	{ .compatible = "qcom,hdmi-tx-8998", .data = &hdmi_tx_8974_config },  	{ .compatible = "qcom,hdmi-tx-8996", .data = &hdmi_tx_8974_config }, @@ -449,6 +447,7 @@ static struct platform_driver msm_hdmi_driver = {  	.driver = {  		.name = "hdmi_msm",  		.of_match_table = msm_hdmi_dt_match, +		.pm = &msm_hdmi_pm_ops,  	},  }; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index a5f481c39277..d5e572d10d6a 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -41,16 +41,17 @@ struct hdmi {  	/* video state: */  	bool power_on; +	bool hpd_enabled; +	struct mutex state_mutex; /* protects two booleans */  	unsigned long int pixclock;  	void __iomem *mmio;  	void __iomem *qfprom_mmio;  	phys_addr_t mmio_phy_addr; -	struct regulator_bulk_data *hpd_regs;  	struct regulator_bulk_data *pwr_regs; -	struct clk **hpd_clks; -	struct clk **pwr_clks; +	struct clk_bulk_data *pwr_clks; +	struct clk *extp_clk;  	struct gpio_desc *hpd_gpiod; @@ -83,21 +84,12 @@ struct hdmi {  /* platform config data (ie. from DT, or pdata) */  struct hdmi_platform_config { -	/* regulators that need to be on for hpd: */ -	const char **hpd_reg_names; -	int hpd_reg_cnt; -  	/* regulators that need to be on for screen pwr: */ -	const char **pwr_reg_names; +	const char * const *pwr_reg_names;  	int pwr_reg_cnt; -	/* clks that need to be on for hpd: */ -	const char **hpd_clk_names; -	const long unsigned *hpd_freq; -	int hpd_clk_cnt; - -	/* clks that need to be on for screen pwr (ie pixel clk): */ -	const char **pwr_clk_names; +	/* clks that need to be on: */ +	const char * const *pwr_clk_names;  	int pwr_clk_cnt;  }; @@ -224,8 +216,8 @@ int msm_hdmi_bridge_init(struct hdmi *hdmi);  void msm_hdmi_hpd_irq(struct drm_bridge *bridge);  enum drm_connector_status msm_hdmi_bridge_detect(  		struct drm_bridge *bridge); -int msm_hdmi_hpd_enable(struct drm_bridge *bridge); -void msm_hdmi_hpd_disable(struct hdmi *hdmi); +void msm_hdmi_hpd_enable(struct drm_bridge *bridge); +void msm_hdmi_hpd_disable(struct drm_bridge *bridge);  /*   * i2c adapter for ddc: diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c index 8bb975e82c17..b9ec14ef2c20 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c @@ -4,6 +4,7 @@   * Author: Rob Clark <robdclark@gmail.com>   */ +#include <drm/display/drm_hdmi_helper.h>  #include <drm/display/drm_hdmi_state_helper.h>  #include <linux/hdmi.h> @@ -12,71 +13,9 @@  #include "hdmi.h" -/* Supported HDMI Audio sample rates */ -#define MSM_HDMI_SAMPLE_RATE_32KHZ		0 -#define MSM_HDMI_SAMPLE_RATE_44_1KHZ		1 -#define MSM_HDMI_SAMPLE_RATE_48KHZ		2 -#define MSM_HDMI_SAMPLE_RATE_88_2KHZ		3 -#define MSM_HDMI_SAMPLE_RATE_96KHZ		4 -#define MSM_HDMI_SAMPLE_RATE_176_4KHZ		5 -#define MSM_HDMI_SAMPLE_RATE_192KHZ		6 -#define MSM_HDMI_SAMPLE_RATE_MAX		7 - - -struct hdmi_msm_audio_acr { -	uint32_t n;	/* N parameter for clock regeneration */ -	uint32_t cts;	/* CTS parameter for clock regeneration */ -}; - -struct hdmi_msm_audio_arcs { -	unsigned long int pixclock; -	struct hdmi_msm_audio_acr lut[MSM_HDMI_SAMPLE_RATE_MAX]; -}; - -#define HDMI_MSM_AUDIO_ARCS(pclk, ...) { (1000 * (pclk)), __VA_ARGS__ } - -/* Audio constants lookup table for hdmi_msm_audio_acr_setup */ -/* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */ -static const struct hdmi_msm_audio_arcs acr_lut[] = { -	/*  25.200MHz  */ -	HDMI_MSM_AUDIO_ARCS(25200, { -		{4096, 25200}, {6272, 28000}, {6144, 25200}, {12544, 28000}, -		{12288, 25200}, {25088, 28000}, {24576, 25200} }), -	/*  27.000MHz  */ -	HDMI_MSM_AUDIO_ARCS(27000, { -		{4096, 27000}, {6272, 30000}, {6144, 27000}, {12544, 30000}, -		{12288, 27000}, {25088, 30000}, {24576, 27000} }), -	/*  27.027MHz */ -	HDMI_MSM_AUDIO_ARCS(27030, { -		{4096, 27027}, {6272, 30030}, {6144, 27027}, {12544, 30030}, -		{12288, 27027}, {25088, 30030}, {24576, 27027} }), -	/*  74.250MHz */ -	HDMI_MSM_AUDIO_ARCS(74250, { -		{4096, 74250}, {6272, 82500}, {6144, 74250}, {12544, 82500}, -		{12288, 74250}, {25088, 82500}, {24576, 74250} }), -	/* 148.500MHz */ -	HDMI_MSM_AUDIO_ARCS(148500, { -		{4096, 148500}, {6272, 165000}, {6144, 148500}, {12544, 165000}, -		{12288, 148500}, {25088, 165000}, {24576, 148500} }), -}; - -static const struct hdmi_msm_audio_arcs *get_arcs(unsigned long int pixclock) -{ -	int i; - -	for (i = 0; i < ARRAY_SIZE(acr_lut); i++) { -		const struct hdmi_msm_audio_arcs *arcs = &acr_lut[i]; -		if (arcs->pixclock == pixclock) -			return arcs; -	} - -	return NULL; -} -  int msm_hdmi_audio_update(struct hdmi *hdmi)  {  	struct hdmi_audio *audio = &hdmi->audio; -	const struct hdmi_msm_audio_arcs *arcs = NULL;  	bool enabled = audio->enabled;  	uint32_t acr_pkt_ctrl, vbi_pkt_ctrl, aud_pkt_ctrl;  	uint32_t audio_config; @@ -94,15 +33,6 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)  		enabled = false;  	} -	if (enabled) { -		arcs = get_arcs(hdmi->pixclock); -		if (!arcs) { -			DBG("disabling audio: unsupported pixclock: %lu", -					hdmi->pixclock); -			enabled = false; -		} -	} -  	/* Read first before writing */  	acr_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_ACR_PKT_CTRL);  	vbi_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_VBI_PKT_CTRL); @@ -116,15 +46,12 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)  		uint32_t n, cts, multiplier;  		enum hdmi_acr_cts select; -		n   = arcs->lut[audio->rate].n; -		cts = arcs->lut[audio->rate].cts; +		drm_hdmi_acr_get_n_cts(hdmi->pixclock, audio->rate, &n, &cts); -		if ((MSM_HDMI_SAMPLE_RATE_192KHZ == audio->rate) || -				(MSM_HDMI_SAMPLE_RATE_176_4KHZ == audio->rate)) { +		if (audio->rate == 192000 || audio->rate == 176400) {  			multiplier = 4;  			n >>= 2; /* divide N by 4 and use multiplier */ -		} else if ((MSM_HDMI_SAMPLE_RATE_96KHZ == audio->rate) || -				(MSM_HDMI_SAMPLE_RATE_88_2KHZ == audio->rate)) { +		} else if (audio->rate == 96000 || audio->rate == 88200) {  			multiplier = 2;  			n >>= 1; /* divide N by 2 and use multiplier */  		} else { @@ -137,13 +64,11 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)  		acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_AUDIO_PRIORITY;  		acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_N_MULTIPLIER(multiplier); -		if ((MSM_HDMI_SAMPLE_RATE_48KHZ == audio->rate) || -				(MSM_HDMI_SAMPLE_RATE_96KHZ == audio->rate) || -				(MSM_HDMI_SAMPLE_RATE_192KHZ == audio->rate)) +		if (audio->rate == 48000 || audio->rate == 96000 || +		    audio->rate == 192000)  			select = ACR_48; -		else if ((MSM_HDMI_SAMPLE_RATE_44_1KHZ == audio->rate) || -				(MSM_HDMI_SAMPLE_RATE_88_2KHZ == audio->rate) || -				(MSM_HDMI_SAMPLE_RATE_176_4KHZ == audio->rate)) +		else if (audio->rate == 44100 || audio->rate == 88200 || +			 audio->rate == 176400)  			select = ACR_44;  		else /* default to 32k */  			select = ACR_32; @@ -204,7 +129,6 @@ int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,  {  	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);  	struct hdmi *hdmi = hdmi_bridge->hdmi; -	unsigned int rate;  	int ret;  	drm_dbg_driver(bridge->dev, "%u Hz, %d bit, %d channels\n", @@ -214,25 +138,12 @@ int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,  	switch (params->sample_rate) {  	case 32000: -		rate = MSM_HDMI_SAMPLE_RATE_32KHZ; -		break;  	case 44100: -		rate = MSM_HDMI_SAMPLE_RATE_44_1KHZ; -		break;  	case 48000: -		rate = MSM_HDMI_SAMPLE_RATE_48KHZ; -		break;  	case 88200: -		rate = MSM_HDMI_SAMPLE_RATE_88_2KHZ; -		break;  	case 96000: -		rate = MSM_HDMI_SAMPLE_RATE_96KHZ; -		break;  	case 176400: -		rate = MSM_HDMI_SAMPLE_RATE_176_4KHZ; -		break;  	case 192000: -		rate = MSM_HDMI_SAMPLE_RATE_192KHZ;  		break;  	default:  		drm_err(bridge->dev, "rate[%d] not supported!\n", @@ -245,7 +156,7 @@ int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,  	if (ret)  		return ret; -	hdmi->audio.rate = rate; +	hdmi->audio.rate = params->sample_rate;  	hdmi->audio.channels = params->cea.channels;  	hdmi->audio.enabled = true; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 7f71956806a2..53a7ce8cc7bc 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -18,52 +18,34 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge)  	struct drm_device *dev = bridge->dev;  	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);  	struct hdmi *hdmi = hdmi_bridge->hdmi; -	const struct hdmi_platform_config *config = hdmi->config; -	int i, ret; - -	pm_runtime_get_sync(&hdmi->pdev->dev); +	int ret; -	ret = regulator_bulk_enable(config->pwr_reg_cnt, hdmi->pwr_regs); -	if (ret) -		DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %d\n", ret); +	pm_runtime_resume_and_get(&hdmi->pdev->dev); -	if (config->pwr_clk_cnt > 0) { +	if (hdmi->extp_clk) {  		DBG("pixclock: %lu", hdmi->pixclock); -		ret = clk_set_rate(hdmi->pwr_clks[0], hdmi->pixclock); -		if (ret) { -			DRM_DEV_ERROR(dev->dev, "failed to set pixel clk: %s (%d)\n", -					config->pwr_clk_names[0], ret); -		} -	} +		ret = clk_set_rate(hdmi->extp_clk, hdmi->pixclock); +		if (ret) +			DRM_DEV_ERROR(dev->dev, "failed to set extp clk rate: %d\n", ret); -	for (i = 0; i < config->pwr_clk_cnt; i++) { -		ret = clk_prepare_enable(hdmi->pwr_clks[i]); -		if (ret) { -			DRM_DEV_ERROR(dev->dev, "failed to enable pwr clk: %s (%d)\n", -					config->pwr_clk_names[i], ret); -		} +		ret = clk_prepare_enable(hdmi->extp_clk); +		if (ret) +			DRM_DEV_ERROR(dev->dev, "failed to enable extp clk: %d\n", ret);  	}  }  static void power_off(struct drm_bridge *bridge)  { -	struct drm_device *dev = bridge->dev;  	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);  	struct hdmi *hdmi = hdmi_bridge->hdmi; -	const struct hdmi_platform_config *config = hdmi->config; -	int i, ret;  	/* TODO do we need to wait for final vblank somewhere before  	 * cutting the clocks?  	 */  	mdelay(16 + 4); -	for (i = 0; i < config->pwr_clk_cnt; i++) -		clk_disable_unprepare(hdmi->pwr_clks[i]); - -	ret = regulator_bulk_disable(config->pwr_reg_cnt, hdmi->pwr_regs); -	if (ret) -		DRM_DEV_ERROR(dev->dev, "failed to disable pwr regulator: %d\n", ret); +	if (hdmi->extp_clk) +		clk_disable_unprepare(hdmi->extp_clk);  	pm_runtime_put(&hdmi->pdev->dev);  } @@ -320,13 +302,16 @@ static void msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,  	msm_hdmi_set_timings(hdmi, &crtc_state->adjusted_mode); +	mutex_lock(&hdmi->state_mutex);  	if (!hdmi->power_on) {  		msm_hdmi_phy_resource_enable(phy);  		msm_hdmi_power_on(bridge);  		hdmi->power_on = true; -		if (connector->display_info.is_hdmi) -			msm_hdmi_audio_update(hdmi);  	} +	mutex_unlock(&hdmi->state_mutex); + +	if (connector->display_info.is_hdmi) +		msm_hdmi_audio_update(hdmi);  	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state); @@ -349,7 +334,10 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,  		msm_hdmi_hdcp_off(hdmi->hdcp_ctrl);  	DBG("power down"); -	msm_hdmi_set_mode(hdmi, false); + +	/* Keep the HDMI enabled if the HPD is enabled */ +	mutex_lock(&hdmi->state_mutex); +	msm_hdmi_set_mode(hdmi, hdmi->hpd_enabled);  	msm_hdmi_phy_powerdown(phy); @@ -360,6 +348,7 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,  			msm_hdmi_audio_update(hdmi);  		msm_hdmi_phy_resource_disable(phy);  	} +	mutex_unlock(&hdmi->state_mutex);  }  static void msm_hdmi_set_timings(struct hdmi *hdmi, @@ -411,9 +400,6 @@ static void msm_hdmi_set_timings(struct hdmi *hdmi,  		frame_ctrl |= HDMI_FRAME_CTRL_INTERLACED_EN;  	DBG("frame_ctrl=%08x", frame_ctrl);  	hdmi_write(hdmi, REG_HDMI_FRAME_CTRL, frame_ctrl); - -	if (hdmi->connector->display_info.is_hdmi) -		msm_hdmi_audio_update(hdmi);  }  static const struct drm_edid *msm_hdmi_bridge_edid_read(struct drm_bridge *bridge, @@ -440,7 +426,6 @@ static enum drm_mode_status msm_hdmi_bridge_tmds_char_rate_valid(const struct dr  {  	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);  	struct hdmi *hdmi = hdmi_bridge->hdmi; -	const struct hdmi_platform_config *config = hdmi->config;  	struct msm_drm_private *priv = bridge->dev->dev_private;  	struct msm_kms *kms = priv->kms;  	long actual; @@ -453,8 +438,8 @@ static enum drm_mode_status msm_hdmi_bridge_tmds_char_rate_valid(const struct dr  		actual = kms->funcs->round_pixclk(kms,  						  tmds_rate,  						  hdmi_bridge->hdmi->encoder); -	else if (config->pwr_clk_cnt > 0) -		actual = clk_round_rate(hdmi->pwr_clks[0], tmds_rate); +	else if (hdmi->extp_clk) +		actual = clk_round_rate(hdmi->extp_clk, tmds_rate);  	else  		actual = tmds_rate; @@ -474,6 +459,8 @@ static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {  	.atomic_post_disable = msm_hdmi_bridge_atomic_post_disable,  	.edid_read = msm_hdmi_bridge_edid_read,  	.detect = msm_hdmi_bridge_detect, +	.hpd_enable = msm_hdmi_hpd_enable, +	.hpd_disable = msm_hdmi_hpd_disable,  	.hdmi_tmds_char_rate_valid = msm_hdmi_bridge_tmds_char_rate_valid,  	.hdmi_clear_infoframe = msm_hdmi_bridge_clear_infoframe,  	.hdmi_write_infoframe = msm_hdmi_bridge_write_infoframe, diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c index 9ce0ffa35417..407e6c449ee0 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c @@ -60,68 +60,30 @@ static void msm_hdmi_phy_reset(struct hdmi *hdmi)  	}  } -static void enable_hpd_clocks(struct hdmi *hdmi, bool enable) -{ -	const struct hdmi_platform_config *config = hdmi->config; -	struct device *dev = &hdmi->pdev->dev; -	int i, ret; - -	if (enable) { -		for (i = 0; i < config->hpd_clk_cnt; i++) { -			if (config->hpd_freq && config->hpd_freq[i]) { -				ret = clk_set_rate(hdmi->hpd_clks[i], -						   config->hpd_freq[i]); -				if (ret) -					dev_warn(dev, -						 "failed to set clk %s (%d)\n", -						 config->hpd_clk_names[i], ret); -			} - -			ret = clk_prepare_enable(hdmi->hpd_clks[i]); -			if (ret) { -				DRM_DEV_ERROR(dev, -					"failed to enable hpd clk: %s (%d)\n", -					config->hpd_clk_names[i], ret); -			} -		} -	} else { -		for (i = config->hpd_clk_cnt - 1; i >= 0; i--) -			clk_disable_unprepare(hdmi->hpd_clks[i]); -	} -} - -int msm_hdmi_hpd_enable(struct drm_bridge *bridge) +void msm_hdmi_hpd_enable(struct drm_bridge *bridge)  {  	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);  	struct hdmi *hdmi = hdmi_bridge->hdmi; -	const struct hdmi_platform_config *config = hdmi->config;  	struct device *dev = &hdmi->pdev->dev;  	uint32_t hpd_ctrl;  	int ret;  	unsigned long flags; -	ret = regulator_bulk_enable(config->hpd_reg_cnt, hdmi->hpd_regs); -	if (ret) { -		DRM_DEV_ERROR(dev, "failed to enable hpd regulators: %d\n", ret); -		goto fail; -	} - -	ret = pinctrl_pm_select_default_state(dev); -	if (ret) { -		DRM_DEV_ERROR(dev, "pinctrl state chg failed: %d\n", ret); -		goto fail; -	} -  	if (hdmi->hpd_gpiod)  		gpiod_set_value_cansleep(hdmi->hpd_gpiod, 1); -	pm_runtime_get_sync(dev); -	enable_hpd_clocks(hdmi, true); +	ret = pm_runtime_resume_and_get(dev); +	if (WARN_ON(ret)) +		return; +	mutex_lock(&hdmi->state_mutex);  	msm_hdmi_set_mode(hdmi, false);  	msm_hdmi_phy_reset(hdmi);  	msm_hdmi_set_mode(hdmi, true); +	hdmi->hpd_enabled = true; +	mutex_unlock(&hdmi->state_mutex); +  	hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);  	/* enable HPD events: */ @@ -140,34 +102,23 @@ int msm_hdmi_hpd_enable(struct drm_bridge *bridge)  	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,  			HDMI_HPD_CTRL_ENABLE | hpd_ctrl);  	spin_unlock_irqrestore(&hdmi->reg_lock, flags); - -	return 0; - -fail: -	return ret;  } -void msm_hdmi_hpd_disable(struct hdmi *hdmi) +void msm_hdmi_hpd_disable(struct drm_bridge *bridge)  { -	const struct hdmi_platform_config *config = hdmi->config; +	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); +	struct hdmi *hdmi = hdmi_bridge->hdmi;  	struct device *dev = &hdmi->pdev->dev; -	int ret;  	/* Disable HPD interrupt */  	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0); -	msm_hdmi_set_mode(hdmi, false); +	mutex_lock(&hdmi->state_mutex); +	hdmi->hpd_enabled = false; +	msm_hdmi_set_mode(hdmi, hdmi->power_on); +	mutex_unlock(&hdmi->state_mutex); -	enable_hpd_clocks(hdmi, false);  	pm_runtime_put(dev); - -	ret = pinctrl_pm_select_sleep_state(dev); -	if (ret) -		dev_warn(dev, "pinctrl state chg failed: %d\n", ret); - -	ret = regulator_bulk_disable(config->hpd_reg_cnt, hdmi->hpd_regs); -	if (ret) -		dev_warn(dev, "failed to disable hpd regulator: %d\n", ret);  }  void msm_hdmi_hpd_irq(struct drm_bridge *bridge) @@ -202,14 +153,16 @@ void msm_hdmi_hpd_irq(struct drm_bridge *bridge)  static enum drm_connector_status detect_reg(struct hdmi *hdmi)  { -	uint32_t hpd_int_status; +	u32 hpd_int_status = 0; +	int ret; -	pm_runtime_get_sync(&hdmi->pdev->dev); -	enable_hpd_clocks(hdmi, true); +	ret = pm_runtime_resume_and_get(&hdmi->pdev->dev); +	if (ret) +		goto out;  	hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS); -	enable_hpd_clocks(hdmi, false); +out:  	pm_runtime_put(&hdmi->pdev->dev);  	return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ? diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c index 7aa500d24240..ebefea4fb408 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c @@ -107,11 +107,15 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c,  	if (num == 0)  		return num; +	ret = pm_runtime_resume_and_get(&hdmi->pdev->dev); +	if (ret) +		return ret; +  	init_ddc(hdmi_i2c);  	ret = ddc_clear_irq(hdmi_i2c);  	if (ret) -		return ret; +		goto fail;  	for (i = 0; i < num; i++) {  		struct i2c_msg *p = &msgs[i]; @@ -169,7 +173,7 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c,  				hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS),  				hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS),  				hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL)); -		return ret; +		goto fail;  	}  	ddc_status = hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS); @@ -202,7 +206,13 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c,  		}  	} +	pm_runtime_put(&hdmi->pdev->dev); +  	return i; + +fail: +	pm_runtime_put(&hdmi->pdev->dev); +	return ret;  }  static u32 msm_hdmi_i2c_func(struct i2c_adapter *adapter) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c index 03120c54ced6..667573f1db7c 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -58,7 +58,11 @@ int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy)  	struct device *dev = &phy->pdev->dev;  	int i, ret = 0; -	pm_runtime_get_sync(dev); +	ret = pm_runtime_resume_and_get(dev); +	if (ret) { +		DRM_DEV_ERROR(dev, "runtime resume failed: %d\n", ret); +		return ret; +	}  	ret = regulator_bulk_enable(cfg->num_regs, phy->regs);  	if (ret) { diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 6970b0f7f457..2e1d5c343272 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -156,6 +156,7 @@ void msm_devfreq_init(struct msm_gpu *gpu)  	priv->gpu_devfreq_config.downdifferential = 10;  	mutex_init(&df->lock); +	df->suspended = true;  	ret = dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq,  				     DEV_PM_QOS_MIN_FREQUENCY, 0); diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index dcb49fd30402..f706e44231a9 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -592,6 +592,16 @@ static const struct msm_mdss_data sa8775p_data = {  	.reg_bus_bw = 74000,  }; +static const struct msm_mdss_data sar2130p_data = { +	.ubwc_enc_version = UBWC_3_0, /* 4.0.2 in hw */ +	.ubwc_dec_version = UBWC_4_3, +	.ubwc_swizzle = 6, +	.ubwc_bank_spread = true, +	.highest_bank_bit = 0, +	.macrotile_mode = 1, +	.reg_bus_bw = 74000, +}; +  static const struct msm_mdss_data sc7180_data = {  	.ubwc_enc_version = UBWC_2_0,  	.ubwc_dec_version = UBWC_2_0, @@ -738,6 +748,7 @@ static const struct of_device_id mdss_dt_match[] = {  	{ .compatible = "qcom,msm8998-mdss", .data = &msm8998_data },  	{ .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data },  	{ .compatible = "qcom,sa8775p-mdss", .data = &sa8775p_data }, +	{ .compatible = "qcom,sar2130p-mdss", .data = &sar2130p_data },  	{ .compatible = "qcom,sdm670-mdss", .data = &sdm670_data },  	{ .compatible = "qcom,sdm845-mdss", .data = &sdm845_data },  	{ .compatible = "qcom,sc7180-mdss", .data = &sc7180_data }, diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index c5651c39ac2a..89dce15eed3b 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -93,7 +93,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,  	}  	msm_gem_object_set_name(ring->bo, "ring%d", id); -	args.name = to_msm_bo(ring->bo)->name, +	args.name = to_msm_bo(ring->bo)->name;  	ring->end   = ring->start + (MSM_GPU_RINGBUFFER_SZ >> 2);  	ring->next  = ring->start; | 
