diff options
651 files changed, 22943 insertions, 10965 deletions
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml new file mode 100644 index 000000000000..bde4dc556d4f --- /dev/null +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek HDMI MT8195 series HDMI Display Data Channel (DDC) + +maintainers: + - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> + - CK Hu <ck.hu@mediatek.com> + +properties: + compatible: + oneOf: + - const: mediatek,mt8195-hdmi-ddc + - items: + - const: mediatek,mt8188-hdmi-ddc + - const: mediatek,mt8195-hdmi-ddc + + clocks: + maxItems: 1 + + power-domains: + maxItems: 1 + +required: + - compatible + - clocks + +additionalProperties: false + +examples: + - | + hdmi { + hdmi_ddc: i2c { + compatible = "mediatek,mt8195-hdmi-ddc"; + clocks = <&clk26m>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml new file mode 100644 index 000000000000..1b382f99d3ce --- /dev/null +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mt8195-hdmi.yaml @@ -0,0 +1,151 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT8195 series HDMI-TX Encoder + +maintainers: + - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> + - CK Hu <ck.hu@mediatek.com> + +description: + The MediaTek HDMI-TX v2 encoder can generate HDMI format data based on + the HDMI Specification 2.0b. + +properties: + compatible: + enum: + - mediatek,mt8188-hdmi-tx + - mediatek,mt8195-hdmi-tx + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: HDMI Peripheral Bus (APB) clock + - description: HDCP and HDMI_TOP clock + - description: HDCP, HDMI_TOP and HDMI Audio reference clock + - description: VPP HDMI Split clock + + clock-names: + items: + - const: bus + - const: hdcp + - const: hdcp24m + - const: hdmi-split + + i2c: + type: object + $ref: /schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml + unevaluatedProperties: false + description: HDMI DDC I2C controller + + phys: + maxItems: 1 + description: PHY providing clocking TMDS and pixel to controller + + phy-names: + items: + - const: hdmi + + power-domains: + maxItems: 1 + + '#sound-dai-cells': + const: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: + Input port, usually connected to the output port of a DPI + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: + Output port that must be connected either to the input port of + a HDMI connector node containing a ddc-i2c-bus, or to the input + port of an attached bridge chip, such as a SlimPort transmitter. + + required: + - port@0 + - port@1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - power-domains + - phys + - phy-names + - ports + +allOf: + - $ref: /schemas/sound/dai-common.yaml# + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/mt8195-clk.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/power/mt8195-power.h> + + soc { + #address-cells = <2>; + #size-cells = <2>; + + hdmi@1c300000 { + compatible = "mediatek,mt8195-hdmi-tx"; + reg = <0 0x1c300000 0 0x1000>; + clocks = <&topckgen CLK_TOP_HDMI_APB>, + <&topckgen CLK_TOP_HDCP>, + <&topckgen CLK_TOP_HDCP_24M>, + <&vppsys1 CLK_VPP1_VPP_SPLIT_HDMI>; + clock-names = "bus", "hdcp", "hdcp24m", "hdmi-split"; + interrupts = <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH 0>; + phys = <&hdmi_phy>; + phy-names = "hdmi"; + power-domains = <&spm MT8195_POWER_DOMAIN_HDMI_TX>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_pins>; + #sound-dai-cells = <1>; + + hdmitx_ddc: i2c { + compatible = "mediatek,mt8195-hdmi-ddc"; + clocks = <&clk26m>; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + hdmi_in: endpoint { + remote-endpoint = <&dpi1_out>; + }; + }; + + port@1 { + reg = <1>; + + hdmi_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; + }; + }; + }; + }; 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/display/panel/novatek,nt37801.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt37801.yaml new file mode 100644 index 000000000000..1b38c1d0af68 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt37801.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/novatek,nt37801.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT37801 AMOLED DSI Panel + +maintainers: + - Krzysztof Kozlowski <krzk@kernel.org> + +description: + Naming is inconclusive and different sources claim this is either Novatek + NT37801 or NT37810 AMOLED DSI Panel. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + const: novatek,nt37801 + + reg: + maxItems: 1 + description: DSI virtual channel + + vci-supply: true + vdd-supply: true + vddio-supply: true + port: true + reset-gpios: true + +required: + - compatible + - reg + - vci-supply + - vdd-supply + - vddio-supply + - port + - reset-gpios + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "novatek,nt37801"; + reg = <0>; + + vci-supply = <&vreg_l13b_3p0>; + vdd-supply = <&vreg_l11b_1p2>; + vddio-supply = <&vreg_l12b_1p8>; + + reset-gpios = <&tlmm 98 GPIO_ACTIVE_LOW>; + + port { + endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/panel/truly,nt35597-2K-display.yaml b/Documentation/devicetree/bindings/display/panel/truly,nt35597-2K-display.yaml new file mode 100644 index 000000000000..36be09c900f2 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/truly,nt35597-2K-display.yaml @@ -0,0 +1,97 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/truly,nt35597-2K-display.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Truly NT35597 DSI 2K display + +maintainers: + - Neil Armstrong <neil.armstrong@linaro.org> + +description: | + Truly NT35597 DSI 2K display is used on the Qualcomm SDM845 MTP board. + +allOf: + - $ref: panel-common-dual.yaml# + +properties: + compatible: + const: truly,nt35597-2K-display + + reg: + maxItems: 1 + + vdda-supply: + description: regulator that provides the supply voltage Power IC supply + + vdispp-supply: + description: regulator that provides the supply voltage for positive LCD bias + + vdispn-supply: + description: regulator that provides the supply voltage for negative LCD bias + + reset-gpios: true + + mode-gpios: + description: + Gpio for choosing the mode of the display for single DSI or Dual DSI. + This should be low for dual DSI and high for single DSI mode. + + ports: + required: + - port@0 + - port@1 + +required: + - compatible + - reg + - vdda-supply + - reset-gpios + - mode-gpios + - ports + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "truly,nt35597-2K-display"; + reg = <0>; + + vdda-supply = <&pm8998_l14>; + vdispp-supply = <&lab_regulator>; + vdispn-supply = <&ibb_regulator>; + + reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>; + mode-gpios = <&tlmm 52 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + panel0_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + + panel1_in: endpoint { + remote-endpoint = <&dsi1_out>; + }; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/truly,nt35597.txt b/Documentation/devicetree/bindings/display/truly,nt35597.txt deleted file mode 100644 index f39c77ee36ea..000000000000 --- a/Documentation/devicetree/bindings/display/truly,nt35597.txt +++ /dev/null @@ -1,59 +0,0 @@ -Truly model NT35597 DSI display driver - -The Truly NT35597 is a generic display driver, currently only configured -for use in the 2K display on the Qualcomm SDM845 MTP board. - -Required properties: -- compatible: should be "truly,nt35597-2K-display" -- vdda-supply: phandle of the regulator that provides the supply voltage - Power IC supply -- vdispp-supply: phandle of the regulator that provides the supply voltage - for positive LCD bias -- vdispn-supply: phandle of the regulator that provides the supply voltage - for negative LCD bias -- reset-gpios: phandle of gpio for reset line - This should be 8mA, gpio can be configured using mux, pinctrl, pinctrl-names - (active low) -- mode-gpios: phandle of the gpio for choosing the mode of the display - for single DSI or Dual DSI - This should be low for dual DSI and high for single DSI mode -- ports: This device has two video ports driven by two DSIs. Their connections - are modeled using the OF graph bindings specified in - Documentation/devicetree/bindings/graph.txt. - - port@0: DSI input port driven by master DSI - - port@1: DSI input port driven by secondary DSI - -Example: - - dsi@ae94000 { - panel@0 { - compatible = "truly,nt35597-2K-display"; - reg = <0>; - vdda-supply = <&pm8998_l14>; - vdispp-supply = <&lab_regulator>; - vdispn-supply = <&ibb_regulator>; - pinctrl-names = "default", "suspend"; - pinctrl-0 = <&dpu_dsi_active>; - pinctrl-1 = <&dpu_dsi_suspend>; - - reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>; - mode-gpios = <&tlmm 52 GPIO_ACTIVE_HIGH>; - ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - panel0_in: endpoint { - remote-endpoint = <&dsi0_out>; - }; - }; - - port@1 { - reg = <1>; - panel1_in: endpoint { - remote-endpoint = <&dsi1_out>; - }; - }; - }; - }; - }; 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/Documentation/gpu/amdgpu/amdgpu-glossary.rst b/Documentation/gpu/amdgpu/amdgpu-glossary.rst index 2040da593b14..30812d9d53c6 100644 --- a/Documentation/gpu/amdgpu/amdgpu-glossary.rst +++ b/Documentation/gpu/amdgpu/amdgpu-glossary.rst @@ -182,7 +182,7 @@ we have a dedicated glossary for Display Core at SMU/SMC System Management Unit / System Management Controller - SPI + SPI (AMDGPU) Shader Processor Input SRLC diff --git a/Documentation/gpu/nova/core/todo.rst b/Documentation/gpu/nova/core/todo.rst index ca08377d3b73..8a459fc08812 100644 --- a/Documentation/gpu/nova/core/todo.rst +++ b/Documentation/gpu/nova/core/todo.rst @@ -102,7 +102,13 @@ Usage: let boot0 = Boot0::read(&bar); pr_info!("Revision: {}\n", boot0.revision()); +Note: a work-in-progress implementation currently resides in +`drivers/gpu/nova-core/regs/macros.rs` and is used in nova-core. It would be +nice to improve it (possibly using proc macros) and move it to the `kernel` +crate so it can be used by other components as well. + | Complexity: Advanced +| Contact: Alexandre Courbot Delay / Sleep abstractions -------------------------- @@ -190,16 +196,6 @@ Rust abstraction for debugfs APIs. | Reference: Export GSP log buffers | Complexity: Intermediate -Vec extensions --------------- - -Implement ``Vec::truncate`` and ``Vec::resize``. - -Currently this is used for some experimental code to parse the vBIOS. - -| Reference vBIOS support -| Complexity: Beginner - GPU (general) ============= diff --git a/MAINTAINERS b/MAINTAINERS index 38df6b159a3b..d063d711e092 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3880,6 +3880,9 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git F: Documentation/driver-api/auxiliary_bus.rst F: drivers/base/auxiliary.c F: include/linux/auxiliary_bus.h +F: rust/helpers/auxiliary.c +F: rust/kernel/auxiliary.rs +F: samples/rust/rust_driver_auxiliary.rs AUXILIARY DISPLAY DRIVERS M: Andy Shevchenko <andy@kernel.org> @@ -7521,6 +7524,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.* @@ -7574,6 +7578,12 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c +DRM DRIVER FOR NOVATEK NT37801 PANELS +M: Krzysztof Kozlowski <krzk@kernel.org> +S: Maintained +F: Documentation/devicetree/bindings/display/panel/novatek,nt37801.yaml +F: drivers/gpu/drm/panel/panel-novatek-nt37801.c + DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS M: Lyude Paul <lyude@redhat.com> M: Danilo Krummrich <dakr@kernel.org> @@ -7600,6 +7610,18 @@ T: git https://gitlab.freedesktop.org/drm/nova.git nova-next F: Documentation/gpu/nova/ F: drivers/gpu/nova-core/ +DRM DRIVER FOR NVIDIA GPUS [RUST] +M: Danilo Krummrich <dakr@kernel.org> +L: nouveau@lists.freedesktop.org +S: Supported +Q: https://patchwork.freedesktop.org/project/nouveau/ +B: https://gitlab.freedesktop.org/drm/nova/-/issues +C: irc://irc.oftc.net/nouveau +T: git https://gitlab.freedesktop.org/drm/nova.git nova-next +F: Documentation/gpu/nova/ +F: drivers/gpu/drm/nova/ +F: include/uapi/drm/nova_drm.h + DRM DRIVER FOR OLIMEX LCD-OLINUXINO PANELS M: Stefan Mavrodiev <stefan@olimex.com> S: Maintained @@ -7689,13 +7711,13 @@ M: David Lechner <david@lechnology.com> S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/sitronix,st7586.txt -F: drivers/gpu/drm/tiny/st7586.c +F: drivers/gpu/drm/sitronix/st7586.c DRM DRIVER FOR SITRONIX ST7571 PANELS M: Marcus Folkesson <marcus.folkesson@gmail.com> S: Maintained F: Documentation/devicetree/bindings/display/sitronix,st7571.yaml -F: drivers/gpu/drm/tiny/st7571-i2c.c +F: drivers/gpu/drm/sitronix/st7571-i2c.c DRM DRIVER FOR SITRONIX ST7701 PANELS M: Jagan Teki <jagan@amarulasolutions.com> @@ -7716,7 +7738,7 @@ M: David Lechner <david@lechnology.com> S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/sitronix,st7735r.yaml -F: drivers/gpu/drm/tiny/st7735r.c +F: drivers/gpu/drm/sitronix/st7735r.c DRM DRIVER FOR SOLOMON SSD130X OLED DISPLAYS M: Javier Martinez Canillas <javierm@redhat.com> @@ -7813,6 +7835,7 @@ F: Documentation/devicetree/bindings/display/ F: Documentation/devicetree/bindings/gpu/ F: Documentation/gpu/ F: drivers/gpu/ +F: rust/kernel/drm/ F: include/drm/ F: include/linux/vga* F: include/uapi/drm/ @@ -7829,6 +7852,7 @@ F: Documentation/devicetree/bindings/gpu/ F: Documentation/gpu/ F: drivers/gpu/drm/ F: drivers/gpu/vga/ +F: rust/kernel/drm/ F: include/drm/drm F: include/linux/vga* F: include/uapi/drm/ 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/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c index 43442b9e273b..be073224bd69 100644 --- a/drivers/accel/amdxdna/amdxdna_ctx.c +++ b/drivers/accel/amdxdna/amdxdna_ctx.c @@ -496,11 +496,11 @@ static int amdxdna_drm_submit_execbuf(struct amdxdna_client *client, struct amdxdna_drm_exec_cmd *args) { struct amdxdna_dev *xdna = client->xdna; - u32 *arg_bo_hdls; + u32 *arg_bo_hdls = NULL; u32 cmd_bo_hdl; int ret; - if (!args->arg_count || args->arg_count > MAX_ARG_COUNT) { + if (args->arg_count > MAX_ARG_COUNT) { XDNA_ERR(xdna, "Invalid arg bo count %d", args->arg_count); return -EINVAL; } @@ -512,14 +512,16 @@ static int amdxdna_drm_submit_execbuf(struct amdxdna_client *client, } cmd_bo_hdl = (u32)args->cmd_handles; - arg_bo_hdls = kcalloc(args->arg_count, sizeof(u32), GFP_KERNEL); - if (!arg_bo_hdls) - return -ENOMEM; - ret = copy_from_user(arg_bo_hdls, u64_to_user_ptr(args->args), - args->arg_count * sizeof(u32)); - if (ret) { - ret = -EFAULT; - goto free_cmd_bo_hdls; + if (args->arg_count) { + arg_bo_hdls = kcalloc(args->arg_count, sizeof(u32), GFP_KERNEL); + if (!arg_bo_hdls) + return -ENOMEM; + ret = copy_from_user(arg_bo_hdls, u64_to_user_ptr(args->args), + args->arg_count * sizeof(u32)); + if (ret) { + ret = -EFAULT; + goto free_cmd_bo_hdls; + } } ret = amdxdna_cmd_submit(client, cmd_bo_hdl, arg_bo_hdls, diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c index 270daae7d89a..67cd69551e42 100644 --- a/drivers/dma-buf/sync_debug.c +++ b/drivers/dma-buf/sync_debug.c @@ -12,8 +12,6 @@ static struct dentry *dbgfs; static LIST_HEAD(sync_timeline_list_head); static DEFINE_SPINLOCK(sync_timeline_list_lock); -static LIST_HEAD(sync_file_list_head); -static DEFINE_SPINLOCK(sync_file_list_lock); void sync_timeline_debug_add(struct sync_timeline *obj) { @@ -33,24 +31,6 @@ void sync_timeline_debug_remove(struct sync_timeline *obj) spin_unlock_irqrestore(&sync_timeline_list_lock, flags); } -void sync_file_debug_add(struct sync_file *sync_file) -{ - unsigned long flags; - - spin_lock_irqsave(&sync_file_list_lock, flags); - list_add_tail(&sync_file->sync_file_list, &sync_file_list_head); - spin_unlock_irqrestore(&sync_file_list_lock, flags); -} - -void sync_file_debug_remove(struct sync_file *sync_file) -{ - unsigned long flags; - - spin_lock_irqsave(&sync_file_list_lock, flags); - list_del(&sync_file->sync_file_list); - spin_unlock_irqrestore(&sync_file_list_lock, flags); -} - static const char *sync_status_str(int status) { if (status < 0) @@ -101,26 +81,6 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) spin_unlock(&obj->lock); } -static void sync_print_sync_file(struct seq_file *s, - struct sync_file *sync_file) -{ - char buf[128]; - int i; - - seq_printf(s, "[%p] %s: %s\n", sync_file, - sync_file_get_name(sync_file, buf, sizeof(buf)), - sync_status_str(dma_fence_get_status(sync_file->fence))); - - if (dma_fence_is_array(sync_file->fence)) { - struct dma_fence_array *array = to_dma_fence_array(sync_file->fence); - - for (i = 0; i < array->num_fences; ++i) - sync_print_fence(s, array->fences[i], true); - } else { - sync_print_fence(s, sync_file->fence, true); - } -} - static int sync_info_debugfs_show(struct seq_file *s, void *unused) { struct list_head *pos; @@ -140,15 +100,6 @@ static int sync_info_debugfs_show(struct seq_file *s, void *unused) seq_puts(s, "fences:\n--------------\n"); - spin_lock_irq(&sync_file_list_lock); - list_for_each(pos, &sync_file_list_head) { - struct sync_file *sync_file = - container_of(pos, struct sync_file, sync_file_list); - - sync_print_sync_file(s, sync_file); - seq_putc(s, '\n'); - } - spin_unlock_irq(&sync_file_list_lock); return 0; } diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h index a1bdd62efccd..02af347293d0 100644 --- a/drivers/dma-buf/sync_debug.h +++ b/drivers/dma-buf/sync_debug.h @@ -68,7 +68,5 @@ extern const struct file_operations sw_sync_debugfs_fops; void sync_timeline_debug_add(struct sync_timeline *obj); void sync_timeline_debug_remove(struct sync_timeline *obj); -void sync_file_debug_add(struct sync_file *fence); -void sync_file_debug_remove(struct sync_file *fence); #endif /* _LINUX_SYNC_H */ diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 5088698182d3..f094797f3b2b 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -274,6 +274,8 @@ source "drivers/gpu/drm/amd/amdgpu/Kconfig" source "drivers/gpu/drm/nouveau/Kconfig" +source "drivers/gpu/drm/nova/Kconfig" + source "drivers/gpu/drm/i915/Kconfig" source "drivers/gpu/drm/xe/Kconfig" @@ -385,6 +387,8 @@ source "drivers/gpu/drm/xlnx/Kconfig" source "drivers/gpu/drm/gud/Kconfig" +source "drivers/gpu/drm/sitronix/Kconfig" + source "drivers/gpu/drm/solomon/Kconfig" source "drivers/gpu/drm/sprd/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index b5d5561bbe5f..4199715670b1 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -177,6 +177,7 @@ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/ obj-$(CONFIG_DRM_VGEM) += vgem/ obj-$(CONFIG_DRM_VKMS) += vkms/ obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/ +obj-$(CONFIG_DRM_NOVA) += nova/ obj-$(CONFIG_DRM_EXYNOS) +=exynos/ obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/ obj-$(CONFIG_DRM_GMA500) += gma500/ @@ -221,6 +222,7 @@ obj-$(CONFIG_DRM_TIDSS) += tidss/ obj-y += xlnx/ obj-y += gud/ obj-$(CONFIG_DRM_HYPERV) += hyperv/ +obj-y += sitronix/ obj-y += solomon/ obj-$(CONFIG_DRM_SPRD) += sprd/ obj-$(CONFIG_DRM_LOONGSON) += loongson/ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index eb015bdda8a7..c7d32fb216e4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -281,6 +281,9 @@ static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev, case ATOM_DGPU_VRAM_TYPE_GDDR6: vram_type = AMDGPU_VRAM_TYPE_GDDR6; break; + case ATOM_DGPU_VRAM_TYPE_HBM3E: + vram_type = AMDGPU_VRAM_TYPE_HBM3E; + break; default: vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; break; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c index cfdf558b48b6..02138aa55793 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c @@ -109,7 +109,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct drm_exec exec; int r; - drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); + drm_exec_init(&exec, 0, 0); drm_exec_until_all_locked(&exec) { r = amdgpu_vm_lock_pd(vm, &exec, 0); if (likely(!r)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index a1450f13d963..8e626f50b362 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -2105,6 +2105,7 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev) amdgpu_rap_debugfs_init(adev); amdgpu_securedisplay_debugfs_init(adev); amdgpu_fw_attestation_debugfs_init(adev); + amdgpu_psp_debugfs_init(adev); debugfs_create_file("amdgpu_evict_vram", 0400, root, adev, &amdgpu_evict_vram_fops); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c index 1a7469543db5..73b629b5f56f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c @@ -183,7 +183,7 @@ void amdgpu_eviction_fence_destroy(struct amdgpu_eviction_fence_mgr *evf_mgr) dma_fence_wait(&ev_fence->base, false); /* Last unref of ev_fence */ - dma_fence_put(&evf_mgr->ev_fence->base); + dma_fence_put(&ev_fence->base); } int amdgpu_eviction_fence_attach(struct amdgpu_eviction_fence_mgr *evf_mgr, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h index bd7fc123b8f9..80fa29c26e9e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h @@ -62,6 +62,9 @@ */ #define AMDGPU_GMC_FAULT_TIMEOUT 5000ULL +/* XNACK flags */ +#define AMDGPU_GMC_XNACK_FLAG_CHAIN BIT(0) + struct firmware; enum amdgpu_memory_partition { @@ -301,6 +304,7 @@ struct amdgpu_gmc { struct amdgpu_xgmi xgmi; struct amdgpu_irq_src ecc_irq; int noretry; + uint32_t xnack_flags; uint32_t vmid0_page_table_block_size; uint32_t vmid0_page_table_depth; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 19ce4da285e8..5517451fc75d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -619,6 +619,10 @@ int amdgpu_irq_get(struct amdgpu_device *adev, struct amdgpu_irq_src *src, int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src, unsigned int type) { + /* When the threshold is reached,the interrupt source may not be enabled.return -EINVAL */ + if (amdgpu_ras_is_rma(adev)) + return -EINVAL; + if (!adev->irq.installed) return -ENOENT; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 8d4a2aed7231..9fbb04aee97b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1425,16 +1425,16 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) mutex_init(&fpriv->bo_list_lock); idr_init_base(&fpriv->bo_list_handles, 1); + r = amdgpu_userq_mgr_init(&fpriv->userq_mgr, file_priv, adev); + if (r) + DRM_WARN("Can't setup usermode queues, use legacy workload submission only\n"); + r = amdgpu_eviction_fence_init(&fpriv->evf_mgr); if (r) goto error_vm; amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev); - r = amdgpu_userq_mgr_init(&fpriv->userq_mgr, file_priv, adev); - if (r) - DRM_WARN("Can't setup usermode queues, use legacy workload submission only\n"); - file_priv->driver_priv = fpriv; goto out_suspend; @@ -1502,10 +1502,11 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, amdgpu_bo_unreserve(pd); } - fpriv->evf_mgr.fd_closing = true; - amdgpu_userq_mgr_fini(&fpriv->userq_mgr); - amdgpu_eviction_fence_destroy(&fpriv->evf_mgr); - + if (!fpriv->evf_mgr.fd_closing) { + fpriv->evf_mgr.fd_closing = true; + amdgpu_userq_mgr_fini(&fpriv->userq_mgr); + amdgpu_eviction_fence_destroy(&fpriv->evf_mgr); + } amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr); amdgpu_vm_fini(adev, &fpriv->vm); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index dbe57996a481..73403744331a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -1044,7 +1044,8 @@ static const char * const amdgpu_vram_names[] = { "GDDR6", "DDR5", "LPDDR4", - "LPDDR5" + "LPDDR5", + "HBM3E" }; /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index bb67d2bbd7f0..e6f0b035e20b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -4186,6 +4186,110 @@ const struct attribute_group amdgpu_flash_attr_group = { .is_visible = amdgpu_flash_attr_is_visible, }; +#if defined(CONFIG_DEBUG_FS) +static int psp_read_spirom_debugfs_open(struct inode *inode, struct file *filp) +{ + struct amdgpu_device *adev = filp->f_inode->i_private; + struct spirom_bo *bo_triplet; + int ret; + + /* serialize the open() file calling */ + if (!mutex_trylock(&adev->psp.mutex)) + return -EBUSY; + + /* + * make sure only one userpace process is alive for dumping so that + * only one memory buffer of AMD_VBIOS_FILE_MAX_SIZE * 2 is consumed. + * let's say the case where one process try opening the file while + * another one has proceeded to read or release. In this way, eliminate + * the use of mutex for read() or release() callback as well. + */ + if (adev->psp.spirom_dump_trip) { + mutex_unlock(&adev->psp.mutex); + return -EBUSY; + } + + bo_triplet = kzalloc(sizeof(struct spirom_bo), GFP_KERNEL); + if (!bo_triplet) { + mutex_unlock(&adev->psp.mutex); + return -ENOMEM; + } + + ret = amdgpu_bo_create_kernel(adev, AMD_VBIOS_FILE_MAX_SIZE_B * 2, + AMDGPU_GPU_PAGE_SIZE, + AMDGPU_GEM_DOMAIN_GTT, + &bo_triplet->bo, + &bo_triplet->mc_addr, + &bo_triplet->cpu_addr); + if (ret) + goto rel_trip; + + ret = psp_dump_spirom(&adev->psp, bo_triplet->mc_addr); + if (ret) + goto rel_bo; + + adev->psp.spirom_dump_trip = bo_triplet; + mutex_unlock(&adev->psp.mutex); + return 0; +rel_bo: + amdgpu_bo_free_kernel(&bo_triplet->bo, &bo_triplet->mc_addr, + &bo_triplet->cpu_addr); +rel_trip: + kfree(bo_triplet); + mutex_unlock(&adev->psp.mutex); + dev_err(adev->dev, "Trying IFWI dump fails, err = %d\n", ret); + return ret; +} + +static ssize_t psp_read_spirom_debugfs_read(struct file *filp, char __user *buf, size_t size, + loff_t *pos) +{ + struct amdgpu_device *adev = filp->f_inode->i_private; + struct spirom_bo *bo_triplet = adev->psp.spirom_dump_trip; + + if (!bo_triplet) + return -EINVAL; + + return simple_read_from_buffer(buf, + size, + pos, bo_triplet->cpu_addr, + AMD_VBIOS_FILE_MAX_SIZE_B * 2); +} + +static int psp_read_spirom_debugfs_release(struct inode *inode, struct file *filp) +{ + struct amdgpu_device *adev = filp->f_inode->i_private; + struct spirom_bo *bo_triplet = adev->psp.spirom_dump_trip; + + if (bo_triplet) { + amdgpu_bo_free_kernel(&bo_triplet->bo, &bo_triplet->mc_addr, + &bo_triplet->cpu_addr); + kfree(bo_triplet); + } + + adev->psp.spirom_dump_trip = NULL; + return 0; +} + +static const struct file_operations psp_dump_spirom_debugfs_ops = { + .owner = THIS_MODULE, + .open = psp_read_spirom_debugfs_open, + .read = psp_read_spirom_debugfs_read, + .release = psp_read_spirom_debugfs_release, + .llseek = default_llseek, +}; +#endif + +void amdgpu_psp_debugfs_init(struct amdgpu_device *adev) +{ +#if defined(CONFIG_DEBUG_FS) + struct drm_minor *minor = adev_to_drm(adev)->primary; + + debugfs_create_file_size("psp_spirom_dump", 0444, minor->debugfs_root, + adev, &psp_dump_spirom_debugfs_ops, AMD_VBIOS_FILE_MAX_SIZE_B * 2); +#endif +} + const struct amd_ip_funcs psp_ip_funcs = { .name = "psp", .early_init = psp_early_init, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index dcf5e8e0b9e3..428adc7f741d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -39,6 +39,18 @@ #define PSP_TMR_ALIGNMENT 0x100000 #define PSP_FW_NAME_LEN 0x24 +/* VBIOS gfl defines */ +#define MBOX_READY_MASK 0x80000000 +#define MBOX_STATUS_MASK 0x0000FFFF +#define MBOX_COMMAND_MASK 0x00FF0000 +#define MBOX_READY_FLAG 0x80000000 +#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_LO 0x2 +#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_HI 0x3 +#define C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE 0x4 +#define C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_LO 0xf +#define C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_HI 0x10 +#define C2PMSG_CMD_SPI_GET_FLASH_IMAGE 0x11 + extern const struct attribute_group amdgpu_flash_attr_group; enum psp_shared_mem_size { @@ -138,6 +150,7 @@ struct psp_funcs { int (*load_usbc_pd_fw)(struct psp_context *psp, uint64_t fw_pri_mc_addr); int (*read_usbc_pd_fw)(struct psp_context *psp, uint32_t *fw_ver); int (*update_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr); + int (*dump_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr); int (*vbflash_stat)(struct psp_context *psp); int (*fatal_error_recovery_quirk)(struct psp_context *psp); bool (*get_ras_capability)(struct psp_context *psp); @@ -322,6 +335,14 @@ struct psp_runtime_scpm_entry { enum psp_runtime_scpm_authentication scpm_status; }; +#if defined(CONFIG_DEBUG_FS) +struct spirom_bo { + struct amdgpu_bo *bo; + uint64_t mc_addr; + void *cpu_addr; +}; +#endif + struct psp_context { struct amdgpu_device *adev; struct psp_ring km_ring; @@ -409,6 +430,9 @@ struct psp_context { char *vbflash_tmp_buf; size_t vbflash_image_size; bool vbflash_done; +#if defined(CONFIG_DEBUG_FS) + struct spirom_bo *spirom_dump_trip; +#endif }; struct amdgpu_psp_funcs { @@ -467,6 +491,10 @@ struct amdgpu_psp_funcs { ((psp)->funcs->update_spirom ? \ (psp)->funcs->update_spirom((psp), fw_pri_mc_addr) : -EINVAL) +#define psp_dump_spirom(psp, fw_pri_mc_addr) \ + ((psp)->funcs->dump_spirom ? \ + (psp)->funcs->dump_spirom((psp), fw_pri_mc_addr) : -EINVAL) + #define psp_vbflash_status(psp) \ ((psp)->funcs->vbflash_stat ? \ (psp)->funcs->vbflash_stat((psp)) : -EINVAL) @@ -578,6 +606,7 @@ int psp_config_sq_perfmon(struct psp_context *psp, uint32_t xcp_id, bool amdgpu_psp_tos_reload_needed(struct amdgpu_device *adev); int amdgpu_psp_reg_program_no_ring(struct psp_context *psp, uint32_t val, enum psp_reg_prog_id id); +void amdgpu_psp_debugfs_init(struct amdgpu_device *adev); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index f40b35f7f679..dc07936d2fcb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -2889,6 +2889,7 @@ static int __amdgpu_ras_convert_rec_from_rom(struct amdgpu_device *adev, if (amdgpu_ras_mca2pa_by_idx(adev, bps, err_data)) return -EINVAL; } + return __amdgpu_ras_restore_bad_pages(adev, err_data->err_addr, adev->umc.retire_unit); } @@ -2903,7 +2904,7 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, &adev->psp.ras_context.ras->eeprom_control; enum amdgpu_memory_partition nps = AMDGPU_NPS1_PARTITION_MODE; int ret = 0; - uint32_t i; + uint32_t i = 0; if (!con || !con->eh_data || !bps || pages <= 0) return 0; @@ -2924,34 +2925,36 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, mutex_lock(&con->recovery_lock); if (from_rom) { - for (i = 0; i < pages; i++) { - if (control->ras_num_recs - i >= adev->umc.retire_unit) { - if ((bps[i].address == bps[i + 1].address) && - (bps[i].mem_channel == bps[i + 1].mem_channel)) { - //deal with retire_unit records a time - ret = __amdgpu_ras_convert_rec_array_from_rom(adev, - &bps[i], &err_data, nps); - if (ret) - goto free; - i += (adev->umc.retire_unit - 1); + /* there is no pa recs in V3, so skip pa recs processing */ + if (control->tbl_hdr.version < RAS_TABLE_VER_V3) { + for (i = 0; i < pages; i++) { + if (control->ras_num_recs - i >= adev->umc.retire_unit) { + if ((bps[i].address == bps[i + 1].address) && + (bps[i].mem_channel == bps[i + 1].mem_channel)) { + /* deal with retire_unit records a time */ + ret = __amdgpu_ras_convert_rec_array_from_rom(adev, + &bps[i], &err_data, nps); + if (ret) + control->ras_num_bad_pages -= adev->umc.retire_unit; + i += (adev->umc.retire_unit - 1); + } else { + break; + } } else { break; } - } else { - break; } } for (; i < pages; i++) { ret = __amdgpu_ras_convert_rec_from_rom(adev, &bps[i], &err_data, nps); if (ret) - goto free; + control->ras_num_bad_pages -= adev->umc.retire_unit; } } else { ret = __amdgpu_ras_restore_bad_pages(adev, bps, pages); } -free: if (from_rom) kfree(err_data.err_addr); mutex_unlock(&con->recovery_lock); @@ -3040,21 +3043,28 @@ static int amdgpu_ras_load_bad_pages(struct amdgpu_device *adev) dev_err(adev->dev, "Failed to load EEPROM table records!"); } else { if (adev->umc.ras && adev->umc.ras->convert_ras_err_addr) { - for (i = 0; i < control->ras_num_recs; i++) { - if ((control->ras_num_recs - i) >= adev->umc.retire_unit) { - if ((bps[i].address == bps[i + 1].address) && - (bps[i].mem_channel == bps[i + 1].mem_channel)) { - control->ras_num_pa_recs += adev->umc.retire_unit; - i += (adev->umc.retire_unit - 1); + /*In V3, there is no pa recs, and some cases(when address==0) may be parsed + as pa recs, so add verion check to avoid it. + */ + if (control->tbl_hdr.version < RAS_TABLE_VER_V3) { + for (i = 0; i < control->ras_num_recs; i++) { + if ((control->ras_num_recs - i) >= adev->umc.retire_unit) { + if ((bps[i].address == bps[i + 1].address) && + (bps[i].mem_channel == bps[i + 1].mem_channel)) { + control->ras_num_pa_recs += adev->umc.retire_unit; + i += (adev->umc.retire_unit - 1); + } else { + control->ras_num_mca_recs += + (control->ras_num_recs - i); + break; + } } else { - control->ras_num_mca_recs += - (control->ras_num_recs - i); + control->ras_num_mca_recs += (control->ras_num_recs - i); break; } - } else { - control->ras_num_mca_recs += (control->ras_num_recs - i); - break; } + } else { + control->ras_num_mca_recs = control->ras_num_recs; } } @@ -3463,6 +3473,10 @@ int amdgpu_ras_init_badpage_info(struct amdgpu_device *adev) if (!adev->umc.ras || !adev->umc.ras->convert_ras_err_addr) control->ras_num_pa_recs = control->ras_num_recs; + if (adev->umc.ras && + adev->umc.ras->get_retire_flip_bits) + adev->umc.ras->get_retire_flip_bits(adev); + if (control->ras_num_recs) { ret = amdgpu_ras_load_bad_pages(adev); if (ret) @@ -4484,8 +4498,11 @@ void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev) enum ras_event_type type = RAS_EVENT_TYPE_FATAL; u64 event_id; - if (amdgpu_ras_mark_ras_event(adev, type)) + if (amdgpu_ras_mark_ras_event(adev, type)) { + dev_err(adev->dev, + "uncorrectable hardware error (ERREVENT_ATHUB_INTERRUPT) detected!\n"); return; + } event_id = amdgpu_ras_acquire_event_id(adev, type); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 53b71e9d8076..9c5df35f05b7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -2081,6 +2081,8 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) amdgpu_vram_mgr_fini(adev); amdgpu_gtt_mgr_fini(adev); amdgpu_preempt_mgr_fini(adev); + amdgpu_doorbell_fini(adev); + ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_GDS); ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_GWS); ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_OA); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 3d9e9fdc10b4..4a72c2bbd49e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -767,6 +767,7 @@ FW_VERSION_ATTR(vcn_fw_version, 0444, vcn.fw_version); FW_VERSION_ATTR(dmcu_fw_version, 0444, dm.dmcu_fw_version); FW_VERSION_ATTR(mes_fw_version, 0444, mes.sched_version & AMDGPU_MES_VERSION_MASK); FW_VERSION_ATTR(mes_kiq_fw_version, 0444, mes.kiq_version & AMDGPU_MES_VERSION_MASK); +FW_VERSION_ATTR(pldm_fw_version, 0444, firmware.pldm_version); static struct attribute *fw_attrs[] = { &dev_attr_vce_fw_version.attr, &dev_attr_uvd_fw_version.attr, @@ -781,7 +782,7 @@ static struct attribute *fw_attrs[] = { &dev_attr_sdma2_fw_version.attr, &dev_attr_vcn_fw_version.attr, &dev_attr_dmcu_fw_version.attr, &dev_attr_imu_fw_version.attr, &dev_attr_mes_fw_version.attr, &dev_attr_mes_kiq_fw_version.attr, - NULL + &dev_attr_pldm_fw_version.attr, NULL }; #define to_dev_attr(x) container_of(x, struct device_attribute, attr) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h index 06fe21e15ed6..9e89c3487be5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h @@ -602,6 +602,7 @@ struct amdgpu_firmware { void *fw_buf_ptr; uint64_t fw_buf_mc; + uint32_t pldm_version; }; void amdgpu_ucode_print_mc_hdr(const struct common_firmware_header *hdr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c index 0a1ef95b2866..8c6e55b5b967 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c @@ -529,6 +529,7 @@ int amdgpu_umc_lookup_bad_pages_in_a_row(struct amdgpu_device *adev, pfns[i] = err_data.err_addr[i].retired_page; } ret = i; + adev->umc.err_addr_cnt = err_data.err_addr_cnt; out: kfree(err_data.err_addr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h index 857693bcd8d4..29ce6b1d214a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h @@ -78,6 +78,18 @@ #define UMC_NPS_SHIFT 40 #define UMC_NPS_MASK 0xffULL +/* three column bits and one row bit in MCA address flip + * in bad page retirement + */ +#define RETIRE_FLIP_BITS_NUM 4 + +struct amdgpu_umc_flip_bits { + uint32_t flip_bits_in_pa[RETIRE_FLIP_BITS_NUM]; + uint32_t flip_row_bit; + uint32_t r13_in_pa; + uint32_t bit_num; +}; + typedef int (*umc_func)(struct amdgpu_device *adev, uint32_t node_inst, uint32_t umc_inst, uint32_t ch_inst, void *data); @@ -100,6 +112,7 @@ struct amdgpu_umc_ras { bool dump_addr); uint32_t (*get_die_id_from_pa)(struct amdgpu_device *adev, uint64_t mca_addr, uint64_t retired_page); + void (*get_retire_flip_bits)(struct amdgpu_device *adev); }; struct amdgpu_umc_funcs { @@ -130,6 +143,10 @@ struct amdgpu_umc { /* active mask for umc node instance */ unsigned long active_mask; + + struct amdgpu_umc_flip_bits flip_bits; + + unsigned long err_addr_cnt; }; int amdgpu_umc_ras_sw_init(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 394b036be1d9..295e7186e156 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -240,17 +240,17 @@ amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr, db_obj->obj = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); drm_gem_object_put(gobj); - /* Pin the BO before generating the index, unpin in queue destroy */ - r = amdgpu_bo_pin(db_obj->obj, AMDGPU_GEM_DOMAIN_DOORBELL); + r = amdgpu_bo_reserve(db_obj->obj, true); if (r) { drm_file_err(uq_mgr->file, "[Usermode queues] Failed to pin doorbell object\n"); goto unref_bo; } - r = amdgpu_bo_reserve(db_obj->obj, true); + /* Pin the BO before generating the index, unpin in queue destroy */ + r = amdgpu_bo_pin(db_obj->obj, AMDGPU_GEM_DOMAIN_DOORBELL); if (r) { drm_file_err(uq_mgr->file, "[Usermode queues] Failed to pin doorbell object\n"); - goto unpin_bo; + goto unresv_bo; } switch (db_info->queue_type) { @@ -286,7 +286,8 @@ amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr, unpin_bo: amdgpu_bo_unpin(db_obj->obj); - +unresv_bo: + amdgpu_bo_unreserve(db_obj->obj); unref_bo: amdgpu_bo_unref(&db_obj->obj); return r; @@ -301,7 +302,7 @@ amdgpu_userq_destroy(struct drm_file *filp, int queue_id) struct amdgpu_usermode_queue *queue; int r = 0; - cancel_delayed_work(&uq_mgr->resume_work); + cancel_delayed_work_sync(&uq_mgr->resume_work); mutex_lock(&uq_mgr->userq_mutex); queue = amdgpu_userq_find(uq_mgr, queue_id); @@ -311,9 +312,13 @@ amdgpu_userq_destroy(struct drm_file *filp, int queue_id) return -EINVAL; } amdgpu_userq_wait_for_last_fence(uq_mgr, queue); - r = amdgpu_userq_unmap_helper(uq_mgr, queue); - amdgpu_bo_unpin(queue->db_obj.obj); + r = amdgpu_bo_reserve(queue->db_obj.obj, true); + if (!r) { + amdgpu_bo_unpin(queue->db_obj.obj); + amdgpu_bo_unreserve(queue->db_obj.obj); + } amdgpu_bo_unref(&queue->db_obj.obj); + r = amdgpu_userq_unmap_helper(uq_mgr, queue); amdgpu_userq_cleanup(uq_mgr, queue, queue_id); mutex_unlock(&uq_mgr->userq_mutex); @@ -389,6 +394,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) * * This will also make sure we have a valid eviction fence ready to be used. */ + mutex_lock(&adev->userq_mutex); amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr); uq_funcs = adev->userq_funcs[args->in.ip_type]; @@ -451,7 +457,6 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) } /* don't map the queue if scheduling is halted */ - mutex_lock(&adev->userq_mutex); if (adev->userq_halt_for_enforce_isolation && ((queue->queue_type == AMDGPU_HW_IP_GFX) || (queue->queue_type == AMDGPU_HW_IP_COMPUTE))) @@ -461,7 +466,6 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) if (!skip_map_queue) { r = amdgpu_userq_map_helper(uq_mgr, queue); if (r) { - mutex_unlock(&adev->userq_mutex); drm_file_err(uq_mgr->file, "Failed to map Queue\n"); idr_remove(&uq_mgr->userq_idr, qid); amdgpu_userq_fence_driver_free(queue); @@ -470,13 +474,13 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) goto unlock; } } - mutex_unlock(&adev->userq_mutex); args->out.queue_id = qid; unlock: mutex_unlock(&uq_mgr->userq_mutex); + mutex_unlock(&adev->userq_mutex); return r; } @@ -746,7 +750,7 @@ amdgpu_userq_evict(struct amdgpu_userq_mgr *uq_mgr, amdgpu_eviction_fence_signal(evf_mgr, ev_fence); if (evf_mgr->fd_closing) { - cancel_delayed_work(&uq_mgr->resume_work); + cancel_delayed_work_sync(&uq_mgr->resume_work); return; } @@ -777,24 +781,25 @@ void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr) struct amdgpu_userq_mgr *uqm, *tmp; uint32_t queue_id; - cancel_delayed_work(&userq_mgr->resume_work); + cancel_delayed_work_sync(&userq_mgr->resume_work); + mutex_lock(&adev->userq_mutex); mutex_lock(&userq_mgr->userq_mutex); idr_for_each_entry(&userq_mgr->userq_idr, queue, queue_id) { amdgpu_userq_wait_for_last_fence(userq_mgr, queue); amdgpu_userq_unmap_helper(userq_mgr, queue); amdgpu_userq_cleanup(userq_mgr, queue, queue_id); } - mutex_lock(&adev->userq_mutex); + list_for_each_entry_safe(uqm, tmp, &adev->userq_mgr_list, list) { if (uqm == userq_mgr) { list_del(&uqm->list); break; } } - mutex_unlock(&adev->userq_mutex); idr_destroy(&userq_mgr->userq_idr); mutex_unlock(&userq_mgr->userq_mutex); + mutex_unlock(&adev->userq_mutex); mutex_destroy(&userq_mgr->userq_mutex); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index 029cb24c28b3..fc4d0d42e223 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -181,7 +181,7 @@ void amdgpu_userq_fence_driver_destroy(struct kref *ref) unsigned long index, flags; struct dma_fence *f; - spin_lock(&fence_drv->fence_list_lock); + spin_lock_irqsave(&fence_drv->fence_list_lock, flags); list_for_each_entry_safe(fence, tmp, &fence_drv->fences, link) { f = &fence->base; @@ -193,7 +193,7 @@ void amdgpu_userq_fence_driver_destroy(struct kref *ref) list_del(&fence->link); dma_fence_put(f); } - spin_unlock(&fence_drv->fence_list_lock); + spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags); xa_lock_irqsave(xa, flags); xa_for_each(xa, index, xa_fence_drv) @@ -859,8 +859,10 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, num_fences = dma_fence_dedup_array(fences, num_fences); waitq = idr_find(&userq_mgr->userq_idr, wait_info->waitq_id); - if (!waitq) + if (!waitq) { + r = -EINVAL; goto free_fences; + } for (i = 0, cnt = 0; i < num_fences; i++) { struct amdgpu_userq_fence_driver *fence_drv; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c index 23b6f7a4aa4a..b03c3895897b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c @@ -709,10 +709,10 @@ void amdgpu_xcp_cfg_sysfs_fini(struct amdgpu_device *adev) struct amdgpu_xcp_cfg *xcp_cfg; int i; - if (!adev->xcp_mgr) + if (!adev->xcp_mgr || !adev->xcp_mgr->xcp_cfg) return; - xcp_cfg = adev->xcp_mgr->xcp_cfg; + xcp_cfg = adev->xcp_mgr->xcp_cfg; for (i = 0; i < xcp_cfg->num_res; i++) { xcp_res = &xcp_cfg->xcp_res[i]; kobject_put(&xcp_res->kobj); diff --git a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c index ae071985f26e..1c083304ae77 100644 --- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c @@ -448,53 +448,71 @@ static int __aqua_vanjaram_get_xcp_ip_info(struct amdgpu_xcp_mgr *xcp_mgr, int x return 0; } -static int aqua_vanjaram_get_xcp_res_info(struct amdgpu_xcp_mgr *xcp_mgr, - int mode, - struct amdgpu_xcp_cfg *xcp_cfg) +static int __aqua_vanjaram_get_px_mode_info(struct amdgpu_xcp_mgr *xcp_mgr, + int px_mode, int *num_xcp, + uint16_t *nps_modes) { struct amdgpu_device *adev = xcp_mgr->adev; - int max_res[AMDGPU_XCP_RES_MAX] = {}; - bool res_lt_xcp; - int num_xcp, i; - u16 nps_modes; - if (!(xcp_mgr->supp_xcp_modes & BIT(mode))) + if (!num_xcp || !nps_modes || !(xcp_mgr->supp_xcp_modes & BIT(px_mode))) return -EINVAL; - max_res[AMDGPU_XCP_RES_XCC] = NUM_XCC(adev->gfx.xcc_mask); - max_res[AMDGPU_XCP_RES_DMA] = adev->sdma.num_instances; - max_res[AMDGPU_XCP_RES_DEC] = adev->vcn.num_vcn_inst; - max_res[AMDGPU_XCP_RES_JPEG] = adev->jpeg.num_jpeg_inst; - - switch (mode) { + switch (px_mode) { case AMDGPU_SPX_PARTITION_MODE: - num_xcp = 1; - nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE); + *num_xcp = 1; + *nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE); break; case AMDGPU_DPX_PARTITION_MODE: - num_xcp = 2; - nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE) | - BIT(AMDGPU_NPS2_PARTITION_MODE); + *num_xcp = 2; + *nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE) | + BIT(AMDGPU_NPS2_PARTITION_MODE); break; case AMDGPU_TPX_PARTITION_MODE: - num_xcp = 3; - nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE) | - BIT(AMDGPU_NPS4_PARTITION_MODE); + *num_xcp = 3; + *nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE) | + BIT(AMDGPU_NPS4_PARTITION_MODE); break; case AMDGPU_QPX_PARTITION_MODE: - num_xcp = 4; - nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE) | - BIT(AMDGPU_NPS4_PARTITION_MODE); + *num_xcp = 4; + *nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE) | + BIT(AMDGPU_NPS4_PARTITION_MODE); break; case AMDGPU_CPX_PARTITION_MODE: - num_xcp = NUM_XCC(adev->gfx.xcc_mask); - nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE) | - BIT(AMDGPU_NPS4_PARTITION_MODE); + *num_xcp = NUM_XCC(adev->gfx.xcc_mask); + *nps_modes = BIT(AMDGPU_NPS1_PARTITION_MODE) | + BIT(AMDGPU_NPS4_PARTITION_MODE); + if (amdgpu_sriov_vf(adev)) + *nps_modes |= BIT(AMDGPU_NPS2_PARTITION_MODE); break; default: return -EINVAL; } + return 0; +} + +static int aqua_vanjaram_get_xcp_res_info(struct amdgpu_xcp_mgr *xcp_mgr, + int mode, + struct amdgpu_xcp_cfg *xcp_cfg) +{ + struct amdgpu_device *adev = xcp_mgr->adev; + int max_res[AMDGPU_XCP_RES_MAX] = {}; + bool res_lt_xcp; + int num_xcp, i, r; + u16 nps_modes; + + if (!(xcp_mgr->supp_xcp_modes & BIT(mode))) + return -EINVAL; + + max_res[AMDGPU_XCP_RES_XCC] = NUM_XCC(adev->gfx.xcc_mask); + max_res[AMDGPU_XCP_RES_DMA] = adev->sdma.num_instances; + max_res[AMDGPU_XCP_RES_DEC] = adev->vcn.num_vcn_inst; + max_res[AMDGPU_XCP_RES_JPEG] = adev->jpeg.num_jpeg_inst; + + r = __aqua_vanjaram_get_px_mode_info(xcp_mgr, mode, &num_xcp, &nps_modes); + if (r) + return r; + xcp_cfg->compatible_nps_modes = (adev->gmc.supported_nps_modes & nps_modes); xcp_cfg->num_res = ARRAY_SIZE(max_res); @@ -543,30 +561,31 @@ static bool __aqua_vanjaram_is_valid_mode(struct amdgpu_xcp_mgr *xcp_mgr, enum amdgpu_gfx_partition mode) { struct amdgpu_device *adev = xcp_mgr->adev; - int num_xcc, num_xccs_per_xcp; + int num_xcc, num_xccs_per_xcp, r; + int num_xcp, nps_mode; + u16 supp_nps_modes; + bool comp_mode; + + nps_mode = adev->gmc.gmc_funcs->query_mem_partition_mode(adev); + r = __aqua_vanjaram_get_px_mode_info(xcp_mgr, mode, &num_xcp, + &supp_nps_modes); + if (r) + return false; + comp_mode = !!(BIT(nps_mode) & supp_nps_modes); num_xcc = NUM_XCC(adev->gfx.xcc_mask); switch (mode) { case AMDGPU_SPX_PARTITION_MODE: - return adev->gmc.num_mem_partitions == 1 && num_xcc > 0; + return comp_mode && num_xcc > 0; case AMDGPU_DPX_PARTITION_MODE: - return adev->gmc.num_mem_partitions <= 2 && (num_xcc % 4) == 0; + return comp_mode && (num_xcc % 4) == 0; case AMDGPU_TPX_PARTITION_MODE: - return (adev->gmc.num_mem_partitions == 1 || - adev->gmc.num_mem_partitions == 3) && - ((num_xcc % 3) == 0); + return comp_mode && ((num_xcc % 3) == 0); case AMDGPU_QPX_PARTITION_MODE: num_xccs_per_xcp = num_xcc / 4; - return (adev->gmc.num_mem_partitions == 1 || - adev->gmc.num_mem_partitions == 4) && - (num_xccs_per_xcp >= 2); + return comp_mode && (num_xccs_per_xcp >= 2); case AMDGPU_CPX_PARTITION_MODE: - /* (num_xcc > 1) because 1 XCC is considered SPX, not CPX. - * (num_xcc % adev->gmc.num_mem_partitions) == 0 because - * num_compute_partitions can't be less than num_mem_partitions - */ - return ((num_xcc > 1) && - (num_xcc % adev->gmc.num_mem_partitions) == 0); + return comp_mode && (num_xcc > 1); default: return false; } diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c index 9db2bde5c59d..c233edf60569 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c @@ -1153,6 +1153,12 @@ static int gfx_v9_4_3_sw_init(struct amdgpu_ip_block *ip_block) adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_PIPE; } break; + case IP_VERSION(9, 5, 0): + if (adev->gfx.mec_fw_version >= 21) { + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; + adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_PIPE; + } + break; default: break; } @@ -1267,6 +1273,22 @@ static void gfx_v9_4_3_xcc_init_gds_vmid(struct amdgpu_device *adev, int xcc_id) } } +/* For ASICs that needs xnack chain and MEC version supports, set SG_CONFIG1 + * DISABLE_XNACK_CHECK_IN_RETRY_DISABLE bit and inform KFD to set xnack_chain + * bit in SET_RESOURCES + */ +static void gfx_v9_4_3_xcc_init_sq(struct amdgpu_device *adev, int xcc_id) +{ + uint32_t data; + + if (!(adev->gmc.xnack_flags & AMDGPU_GMC_XNACK_FLAG_CHAIN)) + return; + + data = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regSQ_CONFIG1); + data = REG_SET_FIELD(data, SQ_CONFIG1, DISABLE_XNACK_CHECK_IN_RETRY_DISABLE, 1); + WREG32_SOC15(GC, xcc_id, regSQ_CONFIG1, data); +} + static void gfx_v9_4_3_xcc_constants_init(struct amdgpu_device *adev, int xcc_id) { @@ -1311,6 +1333,7 @@ static void gfx_v9_4_3_xcc_constants_init(struct amdgpu_device *adev, gfx_v9_4_3_xcc_init_compute_vmid(adev, xcc_id); gfx_v9_4_3_xcc_init_gds_vmid(adev, xcc_id); + gfx_v9_4_3_xcc_init_sq(adev, xcc_id); } static void gfx_v9_4_3_constants_init(struct amdgpu_device *adev) @@ -1323,6 +1346,20 @@ static void gfx_v9_4_3_constants_init(struct amdgpu_device *adev) adev->gfx.config.db_debug2 = RREG32_SOC15(GC, GET_INST(GC, 0), regDB_DEBUG2); + switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { + /* ToDo: GC 9.4.4 */ + case IP_VERSION(9, 4, 3): + if (adev->gfx.mec_fw_version >= 184) + adev->gmc.xnack_flags |= AMDGPU_GMC_XNACK_FLAG_CHAIN; + break; + case IP_VERSION(9, 5, 0): + if (adev->gfx.mec_fw_version >= 23) + adev->gmc.xnack_flags |= AMDGPU_GMC_XNACK_FLAG_CHAIN; + break; + default: + break; + } + for (i = 0; i < num_xcc; i++) gfx_v9_4_3_xcc_constants_init(adev, i); } @@ -3452,9 +3489,7 @@ static int gfx_v9_4_3_unmap_done(struct amdgpu_device *adev, uint32_t me, static bool gfx_v9_4_3_pipe_reset_support(struct amdgpu_device *adev) { - /*TODO: Need check gfx9.4.4 mec fw whether supports pipe reset as well.*/ - if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) && - adev->gfx.mec_fw_version >= 0x0000009b) + if (!!(adev->gfx.compute_supported_reset & AMDGPU_RESET_TYPE_PER_PIPE)) return true; else dev_warn_once(adev->dev, "Please use the latest MEC version to see whether support pipe reset\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c index 917d894a1316..72211409227b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -748,6 +748,18 @@ static int gmc_v11_0_sw_init(struct amdgpu_ip_block *ip_block) adev->gmc.vram_type = vram_type; adev->gmc.vram_vendor = vram_vendor; + /* The mall_size is already calculated as mall_size_per_umc * num_umc. + * However, for gfx1151, which features a 2-to-1 UMC mapping, + * the result must be multiplied by 2 to determine the actual mall size. + */ + switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { + case IP_VERSION(11, 5, 1): + adev->gmc.mall_size *= 2; + break; + default: + break; + } + switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 1): diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 53050176c244..282197f4ffb1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1502,7 +1502,6 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev) adev->umc.umc_inst_num = UMC_V12_0_UMC_INSTANCE_NUM; adev->umc.node_inst_num /= UMC_V12_0_UMC_INSTANCE_NUM; adev->umc.channel_offs = UMC_V12_0_PER_CHANNEL_OFFSET; - adev->umc.retire_unit = UMC_V12_0_BAD_PAGE_NUM_PER_CHANNEL; if (!adev->gmc.xgmi.connected_to_cpu && !adev->gmc.is_app_apu) adev->umc.ras = &umc_v12_0_ras; break; @@ -2072,6 +2071,9 @@ static void gmc_v9_4_3_init_vram_info(struct amdgpu_device *adev) { adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM; adev->gmc.vram_width = 128 * 64; + + if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0)) + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM3E; } static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block) diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c index 6f73033d78b5..cb94bd71300f 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c @@ -28,11 +28,13 @@ #include "soc15d.h" #include "jpeg_v4_0_3.h" #include "jpeg_v5_0_1.h" +#include "mmsch_v5_0.h" #include "vcn/vcn_5_0_0_offset.h" #include "vcn/vcn_5_0_0_sh_mask.h" #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h" +static int jpeg_v5_0_1_start_sriov(struct amdgpu_device *adev); static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev); static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev); static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block, @@ -163,14 +165,9 @@ static int jpeg_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block) (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + j + 11 * jpeg_inst; } else { - if (j < 4) - ring->doorbell_index = - (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + - 4 + j + 32 * jpeg_inst; - else - ring->doorbell_index = - (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + - 8 + j + 32 * jpeg_inst; + ring->doorbell_index = + (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 2 + j + 32 * jpeg_inst; } sprintf(ring->name, "jpeg_dec_%d.%d", adev->jpeg.inst[i].aid_id, j); r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0, @@ -237,7 +234,10 @@ static int jpeg_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block) int i, j, r, jpeg_inst; if (amdgpu_sriov_vf(adev)) { - /* jpeg_v5_0_1_start_sriov(adev); */ + r = jpeg_v5_0_1_start_sriov(adev); + if (r) + return r; + for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { ring = &adev->jpeg.inst[i].ring_dec[j]; @@ -291,8 +291,10 @@ static int jpeg_v5_0_1_hw_fini(struct amdgpu_ip_block *ip_block) cancel_delayed_work_sync(&adev->jpeg.idle_work); - if (adev->jpeg.cur_state != AMD_PG_STATE_GATE) - ret = jpeg_v5_0_1_set_powergating_state(ip_block, AMD_PG_STATE_GATE); + if (!amdgpu_sriov_vf(adev)) { + if (adev->jpeg.cur_state != AMD_PG_STATE_GATE) + ret = jpeg_v5_0_1_set_powergating_state(ip_block, AMD_PG_STATE_GATE); + } return ret; } @@ -422,6 +424,119 @@ static void jpeg_v5_0_1_init_jrbc(struct amdgpu_ring *ring) reg_offset); } +static int jpeg_v5_0_1_start_sriov(struct amdgpu_device *adev) +{ + struct amdgpu_ring *ring; + uint64_t ctx_addr; + uint32_t param, resp, expected; + uint32_t tmp, timeout; + + struct amdgpu_mm_table *table = &adev->virt.mm_table; + uint32_t *table_loc; + uint32_t table_size; + uint32_t size, size_dw, item_offset; + uint32_t init_status; + int i, j, jpeg_inst; + + struct mmsch_v5_0_cmd_direct_write + direct_wt = { {0} }; + struct mmsch_v5_0_cmd_end end = { {0} }; + struct mmsch_v5_0_init_header header; + + direct_wt.cmd_header.command_type = + MMSCH_COMMAND__DIRECT_REG_WRITE; + end.cmd_header.command_type = + MMSCH_COMMAND__END; + + for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) { + jpeg_inst = GET_INST(JPEG, i); + + memset(&header, 0, sizeof(struct mmsch_v5_0_init_header)); + header.version = MMSCH_VERSION; + header.total_size = sizeof(struct mmsch_v5_0_init_header) >> 2; + + table_loc = (uint32_t *)table->cpu_addr; + table_loc += header.total_size; + + item_offset = header.total_size; + + for (j = 0; j < adev->jpeg.num_jpeg_rings; j++) { + ring = &adev->jpeg.inst[i].ring_dec[j]; + table_size = 0; + + tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW); + MMSCH_V5_0_INSERT_DIRECT_WT(tmp, lower_32_bits(ring->gpu_addr)); + tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH); + MMSCH_V5_0_INSERT_DIRECT_WT(tmp, upper_32_bits(ring->gpu_addr)); + tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_JRBC_RB_SIZE); + MMSCH_V5_0_INSERT_DIRECT_WT(tmp, ring->ring_size / 4); + + if (j < 5) { + header.mjpegdec0[j].table_offset = item_offset; + header.mjpegdec0[j].init_status = 0; + header.mjpegdec0[j].table_size = table_size; + } else { + header.mjpegdec1[j - 5].table_offset = item_offset; + header.mjpegdec1[j - 5].init_status = 0; + header.mjpegdec1[j - 5].table_size = table_size; + } + header.total_size += table_size; + item_offset += table_size; + } + + MMSCH_V5_0_INSERT_END(); + + /* send init table to MMSCH */ + size = sizeof(struct mmsch_v5_0_init_header); + table_loc = (uint32_t *)table->cpu_addr; + memcpy((void *)table_loc, &header, size); + + ctx_addr = table->gpu_addr; + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr)); + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr)); + + tmp = RREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_VMID); + tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK; + tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT); + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_VMID, tmp); + + size = header.total_size; + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_SIZE, size); + + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_RESP, 0); + + param = 0x00000001; + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_HOST, param); + tmp = 0; + timeout = 1000; + resp = 0; + expected = MMSCH_VF_MAILBOX_RESP__OK; + init_status = + ((struct mmsch_v5_0_init_header *)(table_loc))->mjpegdec0[i].init_status; + while (resp != expected) { + resp = RREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_RESP); + + if (resp != 0) + break; + udelay(10); + tmp = tmp + 10; + if (tmp >= timeout) { + DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\ + " waiting for regMMSCH_VF_MAILBOX_RESP "\ + "(expected=0x%08x, readback=0x%08x)\n", + tmp, expected, resp); + return -EBUSY; + } + } + if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE && + init_status != MMSCH_VF_ENGINE_STATUS__PASS) + DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init status for jpeg: %x\n", + resp, init_status); + + } + return 0; +} + /** * jpeg_v5_0_1_start - start JPEG block * @@ -581,6 +696,11 @@ static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block, struct amdgpu_device *adev = ip_block->adev; int ret; + if (amdgpu_sriov_vf(adev)) { + adev->jpeg.cur_state = AMD_PG_STATE_UNGATE; + return 0; + } + if (state == adev->jpeg.cur_state) return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/mmsch_v5_0.h b/drivers/gpu/drm/amd/amdgpu/mmsch_v5_0.h new file mode 100644 index 000000000000..6f749814929f --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/mmsch_v5_0.h @@ -0,0 +1,144 @@ +/* + * Copyright 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __MMSCH_V5_0_H__ +#define __MMSCH_V5_0_H__ + +#include "amdgpu_vcn.h" + +#define MMSCH_VERSION_MAJOR 5 +#define MMSCH_VERSION_MINOR 0 +#define MMSCH_VERSION (MMSCH_VERSION_MAJOR << 16 | MMSCH_VERSION_MINOR) + +#define RB_ENABLED (1 << 0) +#define RB4_ENABLED (1 << 1) + +#define MMSCH_VF_ENGINE_STATUS__PASS 0x1 + +#define MMSCH_VF_MAILBOX_RESP__OK 0x1 +#define MMSCH_VF_MAILBOX_RESP__INCOMPLETE 0x2 +#define MMSCH_VF_MAILBOX_RESP__FAILED 0x3 +#define MMSCH_VF_MAILBOX_RESP__FAILED_SMALL_CTX_SIZE 0x4 +#define MMSCH_VF_MAILBOX_RESP__UNKNOWN_CMD 0x5 + +enum mmsch_v5_0_command_type { + MMSCH_COMMAND__DIRECT_REG_WRITE = 0, + MMSCH_COMMAND__DIRECT_REG_POLLING = 2, + MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE = 3, + MMSCH_COMMAND__INDIRECT_REG_WRITE = 8, + MMSCH_COMMAND__END = 0xf +}; + +struct mmsch_v5_0_table_info { + uint32_t init_status; + uint32_t table_offset; + uint32_t table_size; +}; + +struct mmsch_v5_0_init_header { + uint32_t version; + uint32_t total_size; + struct mmsch_v5_0_table_info vcn0; + struct mmsch_v5_0_table_info mjpegdec0[5]; + struct mmsch_v5_0_table_info mjpegdec1[5]; +}; + +struct mmsch_v5_0_cmd_direct_reg_header { + uint32_t reg_offset : 28; + uint32_t command_type : 4; +}; + +struct mmsch_v5_0_cmd_indirect_reg_header { + uint32_t reg_offset : 20; + uint32_t reg_idx_space : 8; + uint32_t command_type : 4; +}; + +struct mmsch_v5_0_cmd_direct_write { + struct mmsch_v5_0_cmd_direct_reg_header cmd_header; + uint32_t reg_value; +}; + +struct mmsch_v5_0_cmd_direct_read_modify_write { + struct mmsch_v5_0_cmd_direct_reg_header cmd_header; + uint32_t write_data; + uint32_t mask_value; +}; + +struct mmsch_v5_0_cmd_direct_polling { + struct mmsch_v5_0_cmd_direct_reg_header cmd_header; + uint32_t mask_value; + uint32_t wait_value; +}; + +struct mmsch_v5_0_cmd_end { + struct mmsch_v5_0_cmd_direct_reg_header cmd_header; +}; + +struct mmsch_v5_0_cmd_indirect_write { + struct mmsch_v5_0_cmd_indirect_reg_header cmd_header; + uint32_t reg_value; +}; + +#define MMSCH_V5_0_INSERT_DIRECT_RD_MOD_WT(reg, mask, data) { \ + size = sizeof(struct mmsch_v5_0_cmd_direct_read_modify_write); \ + size_dw = size / 4; \ + direct_rd_mod_wt.cmd_header.reg_offset = reg; \ + direct_rd_mod_wt.mask_value = mask; \ + direct_rd_mod_wt.write_data = data; \ + memcpy((void *)table_loc, &direct_rd_mod_wt, size); \ + table_loc += size_dw; \ + table_size += size_dw; \ +} + +#define MMSCH_V5_0_INSERT_DIRECT_WT(reg, value) { \ + size = sizeof(struct mmsch_v5_0_cmd_direct_write); \ + size_dw = size / 4; \ + direct_wt.cmd_header.reg_offset = reg; \ + direct_wt.reg_value = value; \ + memcpy((void *)table_loc, &direct_wt, size); \ + table_loc += size_dw; \ + table_size += size_dw; \ +} + +#define MMSCH_V5_0_INSERT_DIRECT_POLL(reg, mask, wait) { \ + size = sizeof(struct mmsch_v5_0_cmd_direct_polling); \ + size_dw = size / 4; \ + direct_poll.cmd_header.reg_offset = reg; \ + direct_poll.mask_value = mask; \ + direct_poll.wait_value = wait; \ + memcpy((void *)table_loc, &direct_poll, size); \ + table_loc += size_dw; \ + table_size += size_dw; \ +} + +#define MMSCH_V5_0_INSERT_END() { \ + size = sizeof(struct mmsch_v5_0_cmd_end); \ + size_dw = size / 4; \ + memcpy((void *)table_loc, &end, size); \ + table_loc += size_dw; \ + table_size += size_dw; \ +} + +#endif + diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index f8af2cc63446..df612fd9cc50 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -71,15 +71,6 @@ MODULE_FIRMWARE("amdgpu/psp_14_0_4_ta.bin"); /* Retry times for vmbx ready wait */ #define PSP_VMBX_POLLING_LIMIT 3000 -/* VBIOS gfl defines */ -#define MBOX_READY_MASK 0x80000000 -#define MBOX_STATUS_MASK 0x0000FFFF -#define MBOX_COMMAND_MASK 0x00FF0000 -#define MBOX_READY_FLAG 0x80000000 -#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_LO 0x2 -#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_HI 0x3 -#define C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE 0x4 - /* memory training timeout define */ #define MEM_TRAIN_SEND_MSG_TIMEOUT_US 3000000 @@ -741,7 +732,8 @@ static int psp_v13_0_exec_spi_cmd(struct psp_context *psp, int cmd) /* Ring the doorbell */ WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_73, 1); - if (cmd == C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE) + if (cmd == C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE || + cmd == C2PMSG_CMD_SPI_GET_FLASH_IMAGE) ret = psp_wait_for_spirom_update(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115), MBOX_READY_FLAG, MBOX_READY_MASK, PSP_SPIROM_UPDATE_TIMEOUT); else @@ -797,6 +789,37 @@ static int psp_v13_0_update_spirom(struct psp_context *psp, return 0; } +static int psp_v13_0_dump_spirom(struct psp_context *psp, + uint64_t fw_pri_mc_addr) +{ + struct amdgpu_device *adev = psp->adev; + int ret; + + /* Confirm PSP is ready to start */ + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115), + MBOX_READY_FLAG, MBOX_READY_MASK, false); + if (ret) { + dev_err(adev->dev, "PSP Not ready to start processing, ret = %d", ret); + return ret; + } + + WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_116, lower_32_bits(fw_pri_mc_addr)); + + ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_LO); + if (ret) + return ret; + + WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_116, upper_32_bits(fw_pri_mc_addr)); + + ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_GET_ROM_IMAGE_ADDR_HI); + if (ret) + return ret; + + ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_GET_FLASH_IMAGE); + + return ret; +} + static int psp_v13_0_vbflash_status(struct psp_context *psp) { struct amdgpu_device *adev = psp->adev; @@ -929,6 +952,7 @@ static const struct psp_funcs psp_v13_0_funcs = { .load_usbc_pd_fw = psp_v13_0_load_usbc_pd_fw, .read_usbc_pd_fw = psp_v13_0_read_usbc_pd_fw, .update_spirom = psp_v13_0_update_spirom, + .dump_spirom = psp_v13_0_dump_spirom, .vbflash_stat = psp_v13_0_vbflash_status, .fatal_error_recovery_quirk = psp_v13_0_fatal_error_recovery_quirk, .get_ras_capability = psp_v13_0_get_ras_capability, diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c index da00d6b3b6a3..e590cbdd8de9 100644 --- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c @@ -174,19 +174,76 @@ static void umc_v12_0_query_ras_error_count(struct amdgpu_device *adev, umc_v12_0_reset_error_count(adev); } +static void umc_v12_0_get_retire_flip_bits(struct amdgpu_device *adev) +{ + enum amdgpu_memory_partition nps = AMDGPU_NPS1_PARTITION_MODE; + uint32_t vram_type = adev->gmc.vram_type; + struct amdgpu_umc_flip_bits *flip_bits = &(adev->umc.flip_bits); + + if (adev->gmc.gmc_funcs->query_mem_partition_mode) + nps = adev->gmc.gmc_funcs->query_mem_partition_mode(adev); + + /* default setting */ + flip_bits->flip_bits_in_pa[0] = UMC_V12_0_PA_C2_BIT; + flip_bits->flip_bits_in_pa[1] = UMC_V12_0_PA_C3_BIT; + flip_bits->flip_bits_in_pa[2] = UMC_V12_0_PA_C4_BIT; + flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R13_BIT; + flip_bits->flip_row_bit = 13; + flip_bits->bit_num = 4; + flip_bits->r13_in_pa = UMC_V12_0_PA_R13_BIT; + + if (nps == AMDGPU_NPS2_PARTITION_MODE) { + flip_bits->flip_bits_in_pa[0] = UMC_V12_0_PA_CH5_BIT; + flip_bits->flip_bits_in_pa[1] = UMC_V12_0_PA_C2_BIT; + flip_bits->flip_bits_in_pa[2] = UMC_V12_0_PA_B1_BIT; + flip_bits->r13_in_pa = UMC_V12_0_PA_R12_BIT; + } else if (nps == AMDGPU_NPS4_PARTITION_MODE) { + flip_bits->flip_bits_in_pa[0] = UMC_V12_0_PA_CH4_BIT; + flip_bits->flip_bits_in_pa[1] = UMC_V12_0_PA_CH5_BIT; + flip_bits->flip_bits_in_pa[2] = UMC_V12_0_PA_B0_BIT; + flip_bits->r13_in_pa = UMC_V12_0_PA_R11_BIT; + } + + switch (vram_type) { + case AMDGPU_VRAM_TYPE_HBM: + /* other nps modes are taken as nps1 */ + if (nps == AMDGPU_NPS2_PARTITION_MODE) + flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R12_BIT; + else if (nps == AMDGPU_NPS4_PARTITION_MODE) + flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R11_BIT; + + break; + case AMDGPU_VRAM_TYPE_HBM3E: + flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R12_BIT; + flip_bits->flip_row_bit = 12; + + if (nps == AMDGPU_NPS2_PARTITION_MODE) + flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R11_BIT; + else if (nps == AMDGPU_NPS4_PARTITION_MODE) + flip_bits->flip_bits_in_pa[3] = UMC_V12_0_PA_R10_BIT; + + break; + default: + dev_warn(adev->dev, + "Unknown HBM type, set RAS retire flip bits to the value in NPS1 mode.\n"); + break; + } + + adev->umc.retire_unit = 0x1 << flip_bits->bit_num; +} + static int umc_v12_0_convert_error_address(struct amdgpu_device *adev, struct ras_err_data *err_data, struct ta_ras_query_address_input *addr_in, struct ta_ras_query_address_output *addr_out, bool dump_addr) { - uint32_t col, col_lower, row, row_lower, bank; + uint32_t col, col_lower, row, row_lower, row_high, bank; uint32_t channel_index = 0, umc_inst = 0; - uint32_t i, loop_bits[UMC_V12_0_RETIRE_LOOP_BITS]; + uint32_t i, bit_num, retire_unit, *flip_bits; uint64_t soc_pa, column, err_addr; struct ta_ras_query_address_output addr_out_tmp; struct ta_ras_query_address_output *paddr_out; - enum amdgpu_memory_partition nps = AMDGPU_NPS1_PARTITION_MODE; int ret = 0; if (!addr_out) @@ -211,53 +268,46 @@ static int umc_v12_0_convert_error_address(struct amdgpu_device *adev, umc_inst = addr_in->ma.umc_inst; } - loop_bits[0] = UMC_V12_0_PA_C2_BIT; - loop_bits[1] = UMC_V12_0_PA_C3_BIT; - loop_bits[2] = UMC_V12_0_PA_C4_BIT; - loop_bits[3] = UMC_V12_0_PA_R13_BIT; - - if (adev->gmc.gmc_funcs->query_mem_partition_mode) - nps = adev->gmc.gmc_funcs->query_mem_partition_mode(adev); - - /* other nps modes are taken as nps1 */ - if (nps == AMDGPU_NPS2_PARTITION_MODE) { - loop_bits[0] = UMC_V12_0_PA_CH5_BIT; - loop_bits[1] = UMC_V12_0_PA_C2_BIT; - loop_bits[2] = UMC_V12_0_PA_B1_BIT; - loop_bits[3] = UMC_V12_0_PA_R12_BIT; - } - - if (nps == AMDGPU_NPS4_PARTITION_MODE) { - loop_bits[0] = UMC_V12_0_PA_CH4_BIT; - loop_bits[1] = UMC_V12_0_PA_CH5_BIT; - loop_bits[2] = UMC_V12_0_PA_B0_BIT; - loop_bits[3] = UMC_V12_0_PA_R11_BIT; - } + flip_bits = adev->umc.flip_bits.flip_bits_in_pa; + bit_num = adev->umc.flip_bits.bit_num; + retire_unit = adev->umc.retire_unit; soc_pa = paddr_out->pa.pa; channel_index = paddr_out->pa.channel_idx; /* clear loop bits in soc physical address */ - for (i = 0; i < UMC_V12_0_RETIRE_LOOP_BITS; i++) - soc_pa &= ~BIT_ULL(loop_bits[i]); + for (i = 0; i < bit_num; i++) + soc_pa &= ~BIT_ULL(flip_bits[i]); paddr_out->pa.pa = soc_pa; /* get column bit 0 and 1 in mca address */ col_lower = (err_addr >> 1) & 0x3ULL; - /* MA_R13_BIT will be handled later */ + /* extra row bit will be handled later */ row_lower = (err_addr >> UMC_V12_0_MA_R0_BIT) & 0x1fffULL; + row_lower &= ~BIT_ULL(adev->umc.flip_bits.flip_row_bit); + + if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 5, 0)) { + row_high = (soc_pa >> adev->umc.flip_bits.r13_in_pa) & 0x3ULL; + /* it's 2.25GB in each channel, from MCA address to PA + * [R14 R13] is converted if the two bits value are 0x3, + * get them from PA instead of MCA address. + */ + row_lower |= (row_high << 13); + } if (!err_data && !dump_addr) goto out; /* loop for all possibilities of retired bits */ - for (column = 0; column < UMC_V12_0_BAD_PAGE_NUM_PER_CHANNEL; column++) { + for (column = 0; column < retire_unit; column++) { soc_pa = paddr_out->pa.pa; - for (i = 0; i < UMC_V12_0_RETIRE_LOOP_BITS; i++) - soc_pa |= (((column >> i) & 0x1ULL) << loop_bits[i]); + for (i = 0; i < bit_num; i++) + soc_pa |= (((column >> i) & 0x1ULL) << flip_bits[i]); col = ((column & 0x7) << 2) | col_lower; - /* add row bit 13 */ - row = ((column >> 3) << 13) | row_lower; + /* handle extra row bit */ + if (bit_num == RETIRE_FLIP_BITS_NUM) + row = ((column >> 3) << adev->umc.flip_bits.flip_row_bit) | + row_lower; if (dump_addr) dev_info(adev->dev, @@ -435,8 +485,12 @@ static int umc_v12_0_aca_bank_parser(struct aca_handle *handle, struct aca_bank bank->regs[ACA_REG_IDX_ADDR]); ext_error_code = ACA_REG__STATUS__ERRORCODEEXT(status); - count = ext_error_code == 0 ? - ACA_REG__MISC0__ERRCNT(bank->regs[ACA_REG_IDX_MISC0]) : 1ULL; + if (umc_v12_0_is_deferred_error(adev, status)) + count = ext_error_code == 0 ? + adev->umc.err_addr_cnt / adev->umc.retire_unit : 1ULL; + else + count = ext_error_code == 0 ? + ACA_REG__MISC0__ERRCNT(bank->regs[ACA_REG_IDX_MISC0]) : 1ULL; return aca_error_cache_log_bank_error(handle, &info, err_type, count); } @@ -476,8 +530,7 @@ static int umc_v12_0_update_ecc_status(struct amdgpu_device *adev, uint64_t err_addr, pa_addr = 0; struct ras_ecc_err *ecc_err; struct ta_ras_query_address_output addr_out; - enum amdgpu_memory_partition nps = AMDGPU_NPS1_PARTITION_MODE; - uint32_t shift_bit = UMC_V12_0_PA_C4_BIT; + uint32_t shift_bit = adev->umc.flip_bits.flip_bits_in_pa[2]; int count, ret, i; hwid = REG_GET_FIELD(ipid, MCMP1_IPIDT0, HardwareID); @@ -522,14 +575,6 @@ static int umc_v12_0_update_ecc_status(struct amdgpu_device *adev, ecc_err->pa_pfn = pa_addr >> AMDGPU_GPU_PAGE_SHIFT; ecc_err->channel_idx = addr_out.pa.channel_idx; - if (adev->gmc.gmc_funcs->query_mem_partition_mode) - nps = adev->gmc.gmc_funcs->query_mem_partition_mode(adev); - - if (nps == AMDGPU_NPS2_PARTITION_MODE) - shift_bit = UMC_V12_0_PA_B1_BIT; - if (nps == AMDGPU_NPS4_PARTITION_MODE) - shift_bit = UMC_V12_0_PA_B0_BIT; - /* If converted pa_pfn is 0, use pa C4 pfn. */ if (!ecc_err->pa_pfn) ecc_err->pa_pfn = BIT_ULL(shift_bit) >> AMDGPU_GPU_PAGE_SHIFT; @@ -675,5 +720,6 @@ struct amdgpu_umc_ras umc_v12_0_ras = { .update_ecc_status = umc_v12_0_update_ecc_status, .convert_ras_err_addr = umc_v12_0_convert_error_address, .get_die_id_from_pa = umc_v12_0_get_die_id, + .get_retire_flip_bits = umc_v12_0_get_retire_flip_bits, }; diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h index 056bbc038312..63b7e7254526 100644 --- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h +++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.h @@ -55,8 +55,6 @@ #define UMC_V12_0_NA_MAP_PA_NUM 8 /* R13 bit shift should be considered, double the number */ #define UMC_V12_0_BAD_PAGE_NUM_PER_CHANNEL (UMC_V12_0_NA_MAP_PA_NUM * 2) -/* C2, C3, C4, R13, four bits in MCA address are looped in retirement */ -#define UMC_V12_0_RETIRE_LOOP_BITS 4 /* column bits in SOC physical address */ #define UMC_V12_0_PA_C2_BIT 15 @@ -64,6 +62,7 @@ #define UMC_V12_0_PA_C4_BIT 21 /* row bits in SOC physical address */ #define UMC_V12_0_PA_R0_BIT 22 +#define UMC_V12_0_PA_R10_BIT 32 #define UMC_V12_0_PA_R11_BIT 33 #define UMC_V12_0_PA_R12_BIT 34 #define UMC_V12_0_PA_R13_BIT 35 diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c index ed00d35039c1..a09f9a2dd471 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c @@ -1034,6 +1034,10 @@ static int vcn_v4_0_5_start_dpg_mode(struct amdgpu_vcn_inst *vinst, ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | VCN_RB1_DB_CTRL__EN_MASK); + /* Keeping one read-back to ensure all register writes are done, otherwise + * it may introduce race conditions */ + RREG32_SOC15(VCN, inst_idx, regVCN_RB1_DB_CTRL); + return 0; } @@ -1216,6 +1220,10 @@ static int vcn_v4_0_5_start(struct amdgpu_vcn_inst *vinst) WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF); + /* Keeping one read-back to ensure all register writes are done, otherwise + * it may introduce race conditions */ + RREG32_SOC15(VCN, i, regVCN_RB_ENABLE); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c index 60ee6e02e6ac..8e843011703c 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c @@ -30,6 +30,7 @@ #include "soc15_hw_ip.h" #include "vcn_v2_0.h" #include "vcn_v4_0_3.h" +#include "mmsch_v5_0.h" #include "vcn/vcn_5_0_0_offset.h" #include "vcn/vcn_5_0_0_sh_mask.h" @@ -39,6 +40,7 @@ #include <drm/drm_drv.h> +static int vcn_v5_0_1_start_sriov(struct amdgpu_device *adev); static void vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device *adev); static void vcn_v5_0_1_set_irq_funcs(struct amdgpu_device *adev); static int vcn_v5_0_1_set_pg_state(struct amdgpu_vcn_inst *vinst, @@ -126,7 +128,14 @@ static int vcn_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block) ring = &adev->vcn.inst[i].ring_enc[0]; ring->use_doorbell = true; - ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 11 * vcn_inst; + if (!amdgpu_sriov_vf(adev)) + ring->doorbell_index = + (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 11 * vcn_inst; + else + ring->doorbell_index = + (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 32 * vcn_inst; ring->vm_hub = AMDGPU_MMHUB0(adev->vcn.inst[i].aid_id); sprintf(ring->name, "vcn_unified_%d", adev->vcn.inst[i].aid_id); @@ -143,6 +152,12 @@ static int vcn_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block) adev->vcn.supported_reset = amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]); + if (amdgpu_sriov_vf(adev)) { + r = amdgpu_virt_alloc_mm_table(adev); + if (r) + return r; + } + vcn_v5_0_0_alloc_ip_dump(adev); return amdgpu_vcn_sysfs_reset_mask_init(adev); @@ -172,6 +187,9 @@ static int vcn_v5_0_1_sw_fini(struct amdgpu_ip_block *ip_block) drm_dev_exit(idx); } + if (amdgpu_sriov_vf(adev)) + amdgpu_virt_free_mm_table(adev); + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { r = amdgpu_vcn_suspend(adev, i); if (r) @@ -204,24 +222,38 @@ static int vcn_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block) struct amdgpu_ring *ring; int i, r, vcn_inst; - if (RREG32_SOC15(VCN, GET_INST(VCN, 0), regVCN_RRMT_CNTL) & 0x100) - adev->vcn.caps |= AMDGPU_VCN_CAPS(RRMT_ENABLED); - for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { - vcn_inst = GET_INST(VCN, i); - ring = &adev->vcn.inst[i].ring_enc[0]; - - if (ring->use_doorbell) - adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, - ((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + - 11 * vcn_inst), - adev->vcn.inst[i].aid_id); - - /* Re-init fw_shared, if required */ - vcn_v5_0_1_fw_shared_init(adev, i); - - r = amdgpu_ring_test_helper(ring); + if (amdgpu_sriov_vf(adev)) { + r = vcn_v5_0_1_start_sriov(adev); if (r) return r; + + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + ring = &adev->vcn.inst[i].ring_enc[0]; + ring->wptr = 0; + ring->wptr_old = 0; + vcn_v5_0_1_unified_ring_set_wptr(ring); + ring->sched.ready = true; + } + } else { + if (RREG32_SOC15(VCN, GET_INST(VCN, 0), regVCN_RRMT_CNTL) & 0x100) + adev->vcn.caps |= AMDGPU_VCN_CAPS(RRMT_ENABLED); + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + vcn_inst = GET_INST(VCN, i); + ring = &adev->vcn.inst[i].ring_enc[0]; + + if (ring->use_doorbell) + adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, + ((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 11 * vcn_inst), + adev->vcn.inst[i].aid_id); + + /* Re-init fw_shared, if required */ + vcn_v5_0_1_fw_shared_init(adev, i); + + r = amdgpu_ring_test_helper(ring); + if (r) + return r; + } } return 0; @@ -663,6 +695,195 @@ static int vcn_v5_0_1_start_dpg_mode(struct amdgpu_vcn_inst *vinst, return 0; } +static int vcn_v5_0_1_start_sriov(struct amdgpu_device *adev) +{ + int i, vcn_inst; + struct amdgpu_ring *ring_enc; + uint64_t cache_addr; + uint64_t rb_enc_addr; + uint64_t ctx_addr; + uint32_t param, resp, expected; + uint32_t offset, cache_size; + uint32_t tmp, timeout; + + struct amdgpu_mm_table *table = &adev->virt.mm_table; + uint32_t *table_loc; + uint32_t table_size; + uint32_t size, size_dw; + uint32_t init_status; + uint32_t enabled_vcn; + + struct mmsch_v5_0_cmd_direct_write + direct_wt = { {0} }; + struct mmsch_v5_0_cmd_direct_read_modify_write + direct_rd_mod_wt = { {0} }; + struct mmsch_v5_0_cmd_end end = { {0} }; + struct mmsch_v5_0_init_header header; + + volatile struct amdgpu_vcn5_fw_shared *fw_shared; + volatile struct amdgpu_fw_shared_rb_setup *rb_setup; + + direct_wt.cmd_header.command_type = + MMSCH_COMMAND__DIRECT_REG_WRITE; + direct_rd_mod_wt.cmd_header.command_type = + MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; + end.cmd_header.command_type = MMSCH_COMMAND__END; + + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + vcn_inst = GET_INST(VCN, i); + + vcn_v5_0_1_fw_shared_init(adev, vcn_inst); + + memset(&header, 0, sizeof(struct mmsch_v5_0_init_header)); + header.version = MMSCH_VERSION; + header.total_size = sizeof(struct mmsch_v5_0_init_header) >> 2; + + table_loc = (uint32_t *)table->cpu_addr; + table_loc += header.total_size; + + table_size = 0; + + MMSCH_V5_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, 0, regUVD_STATUS), + ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY); + + cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[i].fw->size + 4); + + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo); + + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi); + + offset = 0; + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_OFFSET0), 0); + } else { + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), + lower_32_bits(adev->vcn.inst[i].gpu_addr)); + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), + upper_32_bits(adev->vcn.inst[i].gpu_addr)); + offset = cache_size; + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_OFFSET0), + AMDGPU_UVD_FIRMWARE_OFFSET >> 3); + } + + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_SIZE0), + cache_size); + + cache_addr = adev->vcn.inst[vcn_inst].gpu_addr + offset; + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), lower_32_bits(cache_addr)); + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), upper_32_bits(cache_addr)); + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_OFFSET1), 0); + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE); + + cache_addr = adev->vcn.inst[vcn_inst].gpu_addr + offset + + AMDGPU_VCN_STACK_SIZE; + + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), lower_32_bits(cache_addr)); + + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), upper_32_bits(cache_addr)); + + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_OFFSET2), 0); + + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE); + + fw_shared = adev->vcn.inst[vcn_inst].fw_shared.cpu_addr; + rb_setup = &fw_shared->rb_setup; + + ring_enc = &adev->vcn.inst[vcn_inst].ring_enc[0]; + ring_enc->wptr = 0; + rb_enc_addr = ring_enc->gpu_addr; + + rb_setup->is_rb_enabled_flags |= RB_ENABLED; + rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr); + rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr); + rb_setup->rb_size = ring_enc->ring_size / 4; + fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG); + + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), + lower_32_bits(adev->vcn.inst[vcn_inst].fw_shared.gpu_addr)); + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), + upper_32_bits(adev->vcn.inst[vcn_inst].fw_shared.gpu_addr)); + MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_NONCACHE_SIZE0), + AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared))); + MMSCH_V5_0_INSERT_END(); + + header.vcn0.init_status = 0; + header.vcn0.table_offset = header.total_size; + header.vcn0.table_size = table_size; + header.total_size += table_size; + + /* Send init table to mmsch */ + size = sizeof(struct mmsch_v5_0_init_header); + table_loc = (uint32_t *)table->cpu_addr; + memcpy((void *)table_loc, &header, size); + + ctx_addr = table->gpu_addr; + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr)); + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr)); + + tmp = RREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_VMID); + tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK; + tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT); + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_VMID, tmp); + + size = header.total_size; + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_SIZE, size); + + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_RESP, 0); + + param = 0x00000001; + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_HOST, param); + tmp = 0; + timeout = 1000; + resp = 0; + expected = MMSCH_VF_MAILBOX_RESP__OK; + while (resp != expected) { + resp = RREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_RESP); + if (resp != 0) + break; + + udelay(10); + tmp = tmp + 10; + if (tmp >= timeout) { + DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\ + " waiting for regMMSCH_VF_MAILBOX_RESP "\ + "(expected=0x%08x, readback=0x%08x)\n", + tmp, expected, resp); + return -EBUSY; + } + } + + enabled_vcn = amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, 0) ? 1 : 0; + init_status = ((struct mmsch_v5_0_init_header *)(table_loc))->vcn0.init_status; + if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE + && init_status != MMSCH_VF_ENGINE_STATUS__PASS) { + DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init "\ + "status for VCN%x: 0x%x\n", resp, enabled_vcn, init_status); + } + } + + return 0; +} + /** * vcn_v5_0_1_start - VCN start * @@ -1103,8 +1324,18 @@ static int vcn_v5_0_1_set_clockgating_state(struct amdgpu_ip_block *ip_block, static int vcn_v5_0_1_set_pg_state(struct amdgpu_vcn_inst *vinst, enum amd_powergating_state state) { + struct amdgpu_device *adev = vinst->adev; int ret = 0; + /* for SRIOV, guest should not control VCN Power-gating + * MMSCH FW should control Power-gating and clock-gating + * guest should avoid touching CGC and PG + */ + if (amdgpu_sriov_vf(adev)) { + vinst->cur_state = AMD_PG_STATE_UNGATE; + return 0; + } + if (state == vinst->cur_state) return 0; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c index 54870b4c5000..3e1ad8974797 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c @@ -175,8 +175,7 @@ static bool event_interrupt_isr_v10(struct kfd_node *dev, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); - /* If there is no valid PASID, it's likely a bug */ - if (WARN_ONCE(pasid == 0, "Bug: No PASID in KFD interrupt")) + if (pasid == 0) return 0; /* Interrupt types we care about: various signals and faults. diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c index eb88ba8d8b01..2788a52714d1 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c @@ -287,8 +287,7 @@ static bool event_interrupt_isr_v11(struct kfd_node *dev, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); - /* If there is no valid PASID, it's likely a bug */ - if (WARN_ONCE(pasid == 0, "Bug: No PASID in KFD interrupt")) + if (pasid == 0) return false; /* Interrupt types we care about: various signals and faults. diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c index 271c567242ab..b1a6eb349bb3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c @@ -31,6 +31,7 @@ #define OVER_SUBSCRIPTION_PROCESS_COUNT (1 << 0) #define OVER_SUBSCRIPTION_COMPUTE_QUEUE_COUNT (1 << 1) #define OVER_SUBSCRIPTION_GWS_QUEUE_COUNT (1 << 2) +#define OVER_SUBSCRIPTION_XNACK_CONFLICT (1 << 3) static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes, unsigned int buffer_size_bytes) @@ -44,7 +45,8 @@ static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes, static void pm_calc_rlib_size(struct packet_manager *pm, unsigned int *rlib_size, - int *over_subscription) + int *over_subscription, + int xnack_conflict) { unsigned int process_count, queue_count, compute_queue_count, gws_queue_count; unsigned int map_queue_size; @@ -73,6 +75,8 @@ static void pm_calc_rlib_size(struct packet_manager *pm, *over_subscription |= OVER_SUBSCRIPTION_COMPUTE_QUEUE_COUNT; if (gws_queue_count > 1) *over_subscription |= OVER_SUBSCRIPTION_GWS_QUEUE_COUNT; + if (xnack_conflict && (node->adev->gmc.xnack_flags & AMDGPU_GMC_XNACK_FLAG_CHAIN)) + *over_subscription |= OVER_SUBSCRIPTION_XNACK_CONFLICT; if (*over_subscription) dev_dbg(dev, "Over subscribed runlist\n"); @@ -96,7 +100,8 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm, unsigned int **rl_buffer, uint64_t *rl_gpu_buffer, unsigned int *rl_buffer_size, - int *is_over_subscription) + int *is_over_subscription, + int xnack_conflict) { struct kfd_node *node = pm->dqm->dev; struct device *dev = node->adev->dev; @@ -105,7 +110,8 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm, if (WARN_ON(pm->allocated)) return -EINVAL; - pm_calc_rlib_size(pm, rl_buffer_size, is_over_subscription); + pm_calc_rlib_size(pm, rl_buffer_size, is_over_subscription, + xnack_conflict); mutex_lock(&pm->lock); @@ -142,11 +148,27 @@ static int pm_create_runlist_ib(struct packet_manager *pm, struct queue *q; struct kernel_queue *kq; int is_over_subscription; + int xnack_enabled = -1; + bool xnack_conflict = 0; rl_wptr = retval = processes_mapped = 0; + /* Check if processes set different xnack modes */ + list_for_each_entry(cur, queues, list) { + qpd = cur->qpd; + if (xnack_enabled < 0) + /* First process */ + xnack_enabled = qpd->pqm->process->xnack_enabled; + else if (qpd->pqm->process->xnack_enabled != xnack_enabled) { + /* Found a process with a different xnack mode */ + xnack_conflict = 1; + break; + } + } + retval = pm_allocate_runlist_ib(pm, &rl_buffer, rl_gpu_addr, - &alloc_size_bytes, &is_over_subscription); + &alloc_size_bytes, &is_over_subscription, + xnack_conflict); if (retval) return retval; @@ -156,9 +178,13 @@ static int pm_create_runlist_ib(struct packet_manager *pm, dev_dbg(dev, "Building runlist ib process count: %d queues count %d\n", pm->dqm->processes_count, pm->dqm->active_queue_count); +build_runlist_ib: /* build the run list ib packet */ list_for_each_entry(cur, queues, list) { qpd = cur->qpd; + /* group processes with the same xnack mode together */ + if (qpd->pqm->process->xnack_enabled != xnack_enabled) + continue; /* build map process packet */ if (processes_mapped >= pm->dqm->processes_count) { dev_dbg(dev, "Not enough space left in runlist IB\n"); @@ -215,18 +241,26 @@ static int pm_create_runlist_ib(struct packet_manager *pm, alloc_size_bytes); } } + if (xnack_conflict) { + /* pick up processes with the other xnack mode */ + xnack_enabled = !xnack_enabled; + xnack_conflict = 0; + goto build_runlist_ib; + } dev_dbg(dev, "Finished map process and queues to runlist\n"); if (is_over_subscription) { if (!pm->is_over_subscription) - dev_warn(dev, "Runlist is getting oversubscribed due to%s%s%s. Expect reduced ROCm performance.\n", - is_over_subscription & OVER_SUBSCRIPTION_PROCESS_COUNT ? - " too many processes." : "", - is_over_subscription & OVER_SUBSCRIPTION_COMPUTE_QUEUE_COUNT ? - " too many queues." : "", - is_over_subscription & OVER_SUBSCRIPTION_GWS_QUEUE_COUNT ? - " multiple processes using cooperative launch." : ""); + dev_warn(dev, "Runlist is getting oversubscribed due to%s%s%s%s. Expect reduced ROCm performance.\n", + is_over_subscription & OVER_SUBSCRIPTION_PROCESS_COUNT ? + " too many processes" : "", + is_over_subscription & OVER_SUBSCRIPTION_COMPUTE_QUEUE_COUNT ? + " too many queues" : "", + is_over_subscription & OVER_SUBSCRIPTION_GWS_QUEUE_COUNT ? + " multiple processes using cooperative launch" : "", + is_over_subscription & OVER_SUBSCRIPTION_XNACK_CONFLICT ? + " xnack on/off processes mixed on gfx9" : ""); retval = pm->pmf->runlist(pm, &rl_buffer[rl_wptr], *rl_gpu_addr, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c index fa28c57692b8..8fa6489b6f5d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c @@ -203,6 +203,8 @@ static int pm_set_resources_v9(struct packet_manager *pm, uint32_t *buffer, queue_type__mes_set_resources__hsa_interface_queue_hiq; packet->bitfields2.vmid_mask = res->vmid_mask; packet->bitfields2.unmap_latency = KFD_UNMAP_LATENCY_MS / 100; + if (pm->dqm->dev->adev->gmc.xnack_flags & AMDGPU_GMC_XNACK_FLAG_CHAIN) + packet->bitfields2.enb_xnack_retry_disable_check = 1; packet->bitfields7.oac_mask = res->oac_mask; packet->bitfields8.gds_heap_base = res->gds_heap_base; packet->bitfields8.gds_heap_size = res->gds_heap_size; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h index cd8611401a66..e356a207d03c 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h @@ -63,7 +63,8 @@ struct pm4_mes_set_resources { struct { uint32_t vmid_mask:16; uint32_t unmap_latency:8; - uint32_t reserved1:5; + uint32_t reserved1:4; + uint32_t enb_xnack_retry_disable_check:1; enum mes_set_resources_queue_type_enum queue_type:3; } bitfields2; uint32_t ordinal2; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile index ab2a97e354da..7329b8cc2576 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile @@ -38,6 +38,7 @@ AMDGPUDM = \ amdgpu_dm_pp_smu.o \ amdgpu_dm_psr.o \ amdgpu_dm_replay.o \ + amdgpu_dm_quirks.o \ amdgpu_dm_wb.o ifdef CONFIG_DRM_AMD_DC_FP diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 8984e211dd1c..4b4e9241619f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -80,7 +80,6 @@ #include <linux/power_supply.h> #include <linux/firmware.h> #include <linux/component.h> -#include <linux/dmi.h> #include <linux/sort.h> #include <drm/display/drm_dp_mst_helper.h> @@ -374,6 +373,8 @@ get_crtc_by_otg_inst(struct amdgpu_device *adev, static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state, struct dm_crtc_state *new_state) { + if (new_state->stream->adjust.timing_adjust_pending) + return true; if (new_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED) return true; else if (amdgpu_dm_crtc_vrr_active(old_state) != amdgpu_dm_crtc_vrr_active(new_state)) @@ -866,7 +867,7 @@ static void dmub_hpd_callback(struct amdgpu_device *adev, static void dmub_hpd_sense_callback(struct amdgpu_device *adev, struct dmub_notification *notify) { - DRM_DEBUG_DRIVER("DMUB HPD SENSE callback.\n"); + drm_dbg_driver(adev_to_drm(adev), "DMUB HPD SENSE callback.\n"); } /** @@ -963,7 +964,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params) trace_amdgpu_dmub_trace_high_irq(entry.trace_code, entry.tick_count, entry.param0, entry.param1); - DRM_DEBUG_DRIVER("trace_code:%u, tick_count:%u, param0:%u, param1:%u\n", + drm_dbg_driver(adev_to_drm(adev), "trace_code:%u, tick_count:%u, param0:%u, param1:%u\n", entry.trace_code, entry.tick_count, entry.param0, entry.param1); } else break; @@ -973,7 +974,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params) } while (count <= DMUB_TRACE_MAX_READ); if (count > DMUB_TRACE_MAX_READ) - DRM_DEBUG_DRIVER("Warning : count > DMUB_TRACE_MAX_READ"); + drm_dbg_driver(adev_to_drm(adev), "Warning : count > DMUB_TRACE_MAX_READ"); if (dc_enable_dmub_notifications(adev->dm.dc) && irq_params->irq_src == DC_IRQ_SOURCE_DMCUB_OUTBOX) { @@ -1677,153 +1678,6 @@ static bool dm_should_disable_stutter(struct pci_dev *pdev) return false; } -struct amdgpu_dm_quirks { - bool aux_hpd_discon; - bool support_edp0_on_dp1; -}; - -static struct amdgpu_dm_quirks quirk_entries = { - .aux_hpd_discon = false, - .support_edp0_on_dp1 = false -}; - -static int edp0_on_dp1_callback(const struct dmi_system_id *id) -{ - quirk_entries.support_edp0_on_dp1 = true; - return 0; -} - -static int aux_hpd_discon_callback(const struct dmi_system_id *id) -{ - quirk_entries.aux_hpd_discon = true; - return 0; -} - -static const struct dmi_system_id dmi_quirk_table[] = { - { - .callback = aux_hpd_discon_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3660"), - }, - }, - { - .callback = aux_hpd_discon_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3260"), - }, - }, - { - .callback = aux_hpd_discon_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"), - }, - }, - { - .callback = aux_hpd_discon_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"), - }, - }, - { - .callback = aux_hpd_discon_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"), - }, - }, - { - .callback = aux_hpd_discon_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"), - }, - }, - { - .callback = aux_hpd_discon_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"), - }, - }, - { - .callback = aux_hpd_discon_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"), - }, - }, - { - .callback = aux_hpd_discon_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"), - }, - }, - { - .callback = edp0_on_dp1_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite mt645 G8 Mobile Thin Client"), - }, - }, - { - .callback = edp0_on_dp1_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 645 14 inch G11 Notebook PC"), - }, - }, - { - .callback = edp0_on_dp1_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 665 16 inch G11 Notebook PC"), - }, - }, - { - .callback = edp0_on_dp1_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 445 14 inch G11 Notebook PC"), - }, - }, - { - .callback = edp0_on_dp1_callback, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 465 16 inch G11 Notebook PC"), - }, - }, - {} - /* TODO: refactor this from a fixed table to a dynamic option */ -}; - -static void retrieve_dmi_info(struct amdgpu_display_manager *dm, struct dc_init_data *init_data) -{ - int dmi_id; - struct drm_device *dev = dm->ddev; - - dm->aux_hpd_discon_quirk = false; - init_data->flags.support_edp0_on_dp1 = false; - - dmi_id = dmi_check_system(dmi_quirk_table); - - if (!dmi_id) - return; - - if (quirk_entries.aux_hpd_discon) { - dm->aux_hpd_discon_quirk = true; - drm_info(dev, "aux_hpd_discon_quirk attached\n"); - } - if (quirk_entries.support_edp0_on_dp1) { - init_data->flags.support_edp0_on_dp1 = true; - drm_info(dev, "support_edp0_on_dp1 attached\n"); - } -} void* dm_allocate_gpu_mem( @@ -2110,7 +1964,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0)) init_data.num_virtual_links = 1; - retrieve_dmi_info(&adev->dm, &init_data); + retrieve_dmi_info(&adev->dm); + if (adev->dm.edp0_on_dp1_quirk) + init_data.flags.support_edp0_on_dp1 = true; if (adev->dm.bb_from_dmub) init_data.bb_from_dmub = adev->dm.bb_from_dmub; @@ -2200,7 +2056,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) drm_err(adev_to_drm(adev), "amdgpu: failed to initialize freesync_module.\n"); } else - DRM_DEBUG_DRIVER("amdgpu: freesync_module init done %p.\n", + drm_dbg_driver(adev_to_drm(adev), "amdgpu: freesync_module init done %p.\n", adev->dm.freesync_module); amdgpu_dm_init_color_mod(); @@ -2222,7 +2078,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) if (!adev->dm.hdcp_workqueue) drm_err(adev_to_drm(adev), "amdgpu: failed to initialize hdcp_workqueue.\n"); else - DRM_DEBUG_DRIVER("amdgpu: hdcp_workqueue init done %p.\n", adev->dm.hdcp_workqueue); + drm_dbg_driver(adev_to_drm(adev), "amdgpu: hdcp_workqueue init done %p.\n", adev->dm.hdcp_workqueue); dc_init_callbacks(adev->dm.dc, &init_params); } @@ -2299,7 +2155,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) #endif - DRM_DEBUG_DRIVER("KMS initialized.\n"); + drm_dbg_driver(adev_to_drm(adev), "KMS initialized.\n"); return 0; error: @@ -5097,7 +4953,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) drm_err(drm, "DM: Backlight registration failed!\n"); dm->backlight_dev[aconnector->bl_idx] = NULL; } else - DRM_DEBUG_DRIVER("DM: Registered Backlight device: %s\n", bl_name); + drm_dbg_driver(drm, "DM: Registered Backlight device: %s\n", bl_name); } static int initialize_plane(struct amdgpu_display_manager *dm, @@ -6749,7 +6605,7 @@ get_highest_refresh_rate_mode(struct amdgpu_dm_connector *aconnector, m_pref = list_first_entry_or_null( &aconnector->base.modes, struct drm_display_mode, head); if (!m_pref) { - DRM_DEBUG_DRIVER("No preferred mode found in EDID\n"); + drm_dbg_driver(aconnector->base.dev, "No preferred mode found in EDID\n"); return NULL; } } @@ -6924,7 +6780,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, dc_link_get_highest_encoding_format(aconnector->dc_link), &stream->timing.dsc_cfg)) { stream->timing.flags.DSC = 1; - DRM_DEBUG_DRIVER("%s: SST_DSC [%s] DSC is selected from SST RX\n", + drm_dbg_driver(drm_connector->dev, "%s: SST_DSC [%s] DSC is selected from SST RX\n", __func__, drm_connector->name); } } else if (sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) { @@ -6944,7 +6800,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, dc_link_get_highest_encoding_format(aconnector->dc_link), &stream->timing.dsc_cfg)) { stream->timing.flags.DSC = 1; - DRM_DEBUG_DRIVER("%s: SST_DSC [%s] DSC is selected from DP-HDMI PCON\n", + drm_dbg_driver(drm_connector->dev, "%s: SST_DSC [%s] DSC is selected from DP-HDMI PCON\n", __func__, drm_connector->name); } } @@ -7053,7 +6909,7 @@ create_stream_for_sink(struct drm_connector *connector, * case, we call set mode ourselves to restore the previous mode * and the modelist may not be filled in time. */ - DRM_DEBUG_DRIVER("No preferred mode found\n"); + drm_dbg_driver(dev, "No preferred mode found\n"); } else if (aconnector) { recalculate_timing = amdgpu_freesync_vid_mode && is_freesync_video_mode(&mode, aconnector); @@ -9201,7 +9057,7 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, */ WARN_ON(amdgpu_dm_crtc_set_vupdate_irq(new_state->base.crtc, true) != 0); WARN_ON(drm_crtc_vblank_get(new_state->base.crtc) != 0); - DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n", + drm_dbg_driver(new_state->base.crtc->dev, "%s: crtc=%u VRR off->on: Get vblank ref\n", __func__, new_state->base.crtc->base.id); } else if (old_vrr_active && !new_vrr_active) { /* Transition VRR active -> inactive: @@ -9209,7 +9065,7 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, */ WARN_ON(amdgpu_dm_crtc_set_vupdate_irq(new_state->base.crtc, false) != 0); drm_crtc_vblank_put(new_state->base.crtc); - DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n", + drm_dbg_driver(new_state->base.crtc->dev, "%s: crtc=%u VRR on->off: Drop vblank ref\n", __func__, new_state->base.crtc->base.id); } } @@ -10836,6 +10692,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, struct dm_atomic_state *dm_state = NULL; struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state; struct dc_stream_state *new_stream; + struct amdgpu_device *adev = dm->adev; int ret = 0; /* @@ -10889,7 +10746,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, */ if (!new_stream) { - DRM_DEBUG_DRIVER("%s: Failed to create new stream for crtc %d\n", + drm_dbg_driver(adev_to_drm(adev), "%s: Failed to create new stream for crtc %d\n", __func__, acrtc->base.base.id); ret = -ENOMEM; goto fail; @@ -10927,7 +10784,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) { new_crtc_state->mode_changed = false; - DRM_DEBUG_DRIVER("Mode change not required, setting mode_changed to %d", + drm_dbg_driver(adev_to_drm(adev), "Mode change not required, setting mode_changed to %d", new_crtc_state->mode_changed); } } @@ -10965,7 +10822,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state)) { new_crtc_state->mode_changed = false; - DRM_DEBUG_DRIVER( + drm_dbg_driver(adev_to_drm(adev), "Mode change not required for front porch change, setting mode_changed to %d", new_crtc_state->mode_changed); @@ -10986,7 +10843,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, if (ret) goto fail; - DRM_DEBUG_DRIVER("Disabling DRM crtc: %d\n", + drm_dbg_driver(adev_to_drm(adev), "Disabling DRM crtc: %d\n", crtc->base.id); /* i.e. reset mode */ @@ -12844,7 +12701,7 @@ int amdgpu_dm_process_dmub_aux_transfer_sync( payload->address, payload->length, p_notify->result); } - *operation_result = AUX_RET_ERROR_INVALID_REPLY; + *operation_result = p_notify->result; goto out; } @@ -12853,7 +12710,8 @@ int amdgpu_dm_process_dmub_aux_transfer_sync( /* The reply is stored in the top nibble of the command. */ payload->reply[0] = (adev->dm.dmub_notify->aux_reply.command >> 4) & 0xF; - if (!payload->write && p_notify->aux_reply.length) + /*write req may receive a byte indicating partially written number as well*/ + if (p_notify->aux_reply.length) memcpy(payload->data, p_notify->aux_reply.data, p_notify->aux_reply.length); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 4b615071e93b..d7d92f9911e4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -619,6 +619,13 @@ struct amdgpu_display_manager { bool aux_hpd_discon_quirk; /** + * @edp0_on_dp1_quirk: + * + * quirk for platforms that put edp0 on DP1. + */ + bool edp0_on_dp1_quirk; + + /** * @dpia_aux_lock: * * Guards access to DPIA AUX @@ -1068,4 +1075,6 @@ void hdmi_cec_set_edid(struct amdgpu_dm_connector *aconnector); void hdmi_cec_unset_edid(struct amdgpu_dm_connector *aconnector); int amdgpu_dm_initialize_hdmi_connector(struct amdgpu_dm_connector *aconnector); +void retrieve_dmi_info(struct amdgpu_display_manager *dm); + #endif /* __AMDGPU_DM_H__ */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index d19aea595722..25e8befbcc47 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -62,6 +62,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, enum aux_return_code_type operation_result; struct amdgpu_device *adev; struct ddc_service *ddc; + uint8_t copy[16]; if (WARN_ON(msg->size > 16)) return -E2BIG; @@ -77,6 +78,11 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, (msg->request & DP_AUX_I2C_WRITE_STATUS_UPDATE) != 0; payload.defer_delay = 0; + if (payload.write) { + memcpy(copy, msg->buffer, msg->size); + payload.data = copy; + } + result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload, &operation_result); @@ -100,9 +106,9 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, */ if (payload.write && result >= 0) { if (result) { - /*one byte indicating partially written bytes. Force 0 to retry*/ - drm_info(adev_to_drm(adev), "amdgpu: AUX partially written\n"); - result = 0; + /*one byte indicating partially written bytes*/ + drm_dbg_dp(adev_to_drm(adev), "amdgpu: AUX partially written\n"); + result = payload.data[0]; } else if (!payload.reply[0]) /*I2C_ACK|AUX_ACK*/ result = msg->size; @@ -127,11 +133,11 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, break; } - drm_info(adev_to_drm(adev), "amdgpu: DP AUX transfer fail:%d\n", operation_result); + drm_dbg_dp(adev_to_drm(adev), "amdgpu: DP AUX transfer fail:%d\n", operation_result); } if (payload.reply[0]) - drm_info(adev_to_drm(adev), "amdgpu: AUX reply command not ACK: 0x%02x.", + drm_dbg_dp(adev_to_drm(adev), "amdgpu: AUX reply command not ACK: 0x%02x.", payload.reply[0]); return result; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_quirks.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_quirks.c new file mode 100644 index 000000000000..1da07ebf9217 --- /dev/null +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_quirks.c @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright 2025 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include <linux/dmi.h> + +#include "amdgpu.h" +#include "amdgpu_dm.h" + +struct amdgpu_dm_quirks { + bool aux_hpd_discon; + bool support_edp0_on_dp1; +}; + +static struct amdgpu_dm_quirks quirk_entries = { + .aux_hpd_discon = false, + .support_edp0_on_dp1 = false +}; + +static int edp0_on_dp1_callback(const struct dmi_system_id *id) +{ + quirk_entries.support_edp0_on_dp1 = true; + return 0; +} + +static int aux_hpd_discon_callback(const struct dmi_system_id *id) +{ + quirk_entries.aux_hpd_discon = true; + return 0; +} + +static const struct dmi_system_id dmi_quirk_table[] = { + { + .callback = aux_hpd_discon_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3660"), + }, + }, + { + .callback = aux_hpd_discon_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3260"), + }, + }, + { + .callback = aux_hpd_discon_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"), + }, + }, + { + .callback = aux_hpd_discon_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"), + }, + }, + { + .callback = aux_hpd_discon_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"), + }, + }, + { + .callback = aux_hpd_discon_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"), + }, + }, + { + .callback = aux_hpd_discon_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"), + }, + }, + { + .callback = aux_hpd_discon_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"), + }, + }, + { + .callback = aux_hpd_discon_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"), + }, + }, + { + .callback = edp0_on_dp1_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite mt645 G8 Mobile Thin Client"), + }, + }, + { + .callback = edp0_on_dp1_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 645 14 inch G11 Notebook PC"), + }, + }, + { + .callback = edp0_on_dp1_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 665 16 inch G11 Notebook PC"), + }, + }, + { + .callback = edp0_on_dp1_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 445 14 inch G11 Notebook PC"), + }, + }, + { + .callback = edp0_on_dp1_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 465 16 inch G11 Notebook PC"), + }, + }, + {} + /* TODO: refactor this from a fixed table to a dynamic option */ +}; + +void retrieve_dmi_info(struct amdgpu_display_manager *dm) +{ + struct drm_device *dev = dm->ddev; + int dmi_id; + + dm->aux_hpd_discon_quirk = false; + dm->edp0_on_dp1_quirk = false; + + dmi_id = dmi_check_system(dmi_quirk_table); + + if (!dmi_id) + return; + + if (quirk_entries.aux_hpd_discon) { + dm->aux_hpd_discon_quirk = true; + drm_info(dev, "aux_hpd_discon_quirk attached\n"); + } + if (quirk_entries.support_edp0_on_dp1) { + dm->edp0_on_dp1_quirk = true; + drm_info(dev, "support_edp0_on_dp1 attached\n"); + } +} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index afd298e69d4e..56d011a1323c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -36,6 +36,7 @@ #include "resource.h" #include "dc_state.h" #include "dc_state_priv.h" +#include "dc_plane.h" #include "dc_plane_priv.h" #include "dc_stream_priv.h" @@ -440,9 +441,12 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc, * Don't adjust DRR while there's bandwidth optimizations pending to * avoid conflicting with firmware updates. */ - if (dc->ctx->dce_version > DCE_VERSION_MAX) - if (dc->optimized_required || dc->wm_optimized_required) + if (dc->ctx->dce_version > DCE_VERSION_MAX) { + if (dc->optimized_required || dc->wm_optimized_required) { + stream->adjust.timing_adjust_pending = true; return false; + } + } dc_exit_ips_for_hw_access(dc); @@ -2330,11 +2334,15 @@ enum dc_status dc_commit_streams(struct dc *dc, struct dc_commit_streams_params for (i = 0; i < params->stream_count; i++) { struct dc_stream_state *stream = params->streams[i]; struct dc_stream_status *status = dc_stream_get_status(stream); + struct dc_sink *sink = stream->sink; /* revalidate streams */ - res = dc_validate_stream(dc, stream); - if (res != DC_OK) - return res; + if (!dc_is_virtual_signal(sink->sink_signal)) { + res = dc_validate_stream(dc, stream); + if (res != DC_OK) + return res; + } + dc_stream_log(dc, stream); @@ -3240,7 +3248,8 @@ static void copy_stream_update_to_stream(struct dc *dc, if (update->crtc_timing_adjust) { if (stream->adjust.v_total_min != update->crtc_timing_adjust->v_total_min || - stream->adjust.v_total_max != update->crtc_timing_adjust->v_total_max) + stream->adjust.v_total_max != update->crtc_timing_adjust->v_total_max || + stream->adjust.timing_adjust_pending) update->crtc_timing_adjust->timing_adjust_pending = true; stream->adjust = *update->crtc_timing_adjust; update->crtc_timing_adjust->timing_adjust_pending = false; @@ -3320,7 +3329,7 @@ static void backup_planes_and_stream_state( return; for (i = 0; i < status->plane_count; i++) { - scratch->plane_states[i] = *status->plane_states[i]; + dc_plane_copy_config(&scratch->plane_states[i], status->plane_states[i]); } scratch->stream_state = *stream; } @@ -3336,10 +3345,7 @@ static void restore_planes_and_stream_state( return; for (i = 0; i < status->plane_count; i++) { - /* refcount will always be valid, restore everything else */ - struct kref refcount = status->plane_states[i]->refcount; - *status->plane_states[i] = scratch->plane_states[i]; - status->plane_states[i]->refcount = refcount; + dc_plane_copy_config(status->plane_states[i], &scratch->plane_states[i]); } *stream = scratch->stream_state; } @@ -4244,12 +4250,6 @@ static void commit_planes_for_stream(struct dc *dc, if (update_type == UPDATE_TYPE_FAST) continue; - ASSERT(!pipe_ctx->plane_state->triplebuffer_flips); - if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) { - /*turn off triple buffer for full update*/ - dc->hwss.program_triplebuffer( - dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips); - } stream_status = stream_get_status(context, pipe_ctx->stream); @@ -4258,6 +4258,25 @@ static void commit_planes_for_stream(struct dc *dc, dc, pipe_ctx->stream, stream_status->plane_count, context); } } + + for (j = 0; j < dc->res_pool->pipe_count; j++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; + + if (!pipe_ctx->plane_state) + continue; + + /* Full fe update*/ + if (update_type == UPDATE_TYPE_FAST) + continue; + + ASSERT(!pipe_ctx->plane_state->triplebuffer_flips); + if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) { + /*turn off triple buffer for full update*/ + dc->hwss.program_triplebuffer( + dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips); + } + } + if (dc->hwss.program_front_end_for_ctx && update_type != UPDATE_TYPE_FAST) { dc->hwss.program_front_end_for_ctx(dc, context); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 13559fe56062..3da25bd8b578 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -3911,6 +3911,10 @@ enum dc_status resource_map_pool_resources( if (!dc->link_srv->dp_decide_link_settings(stream, &pipe_ctx->link_config.dp_link_settings)) return DC_FAIL_DP_LINK_BANDWIDTH; + + dc->link_srv->dp_decide_tunnel_settings(stream, + &pipe_ctx->link_config.dp_tunnel_settings); + if (dc->link_srv->dp_get_encoding_format( &pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) { pipe_ctx->stream_res.hpo_dp_stream_enc = @@ -5521,6 +5525,14 @@ struct dscl_prog_data *resource_get_dscl_prog_data(struct pipe_ctx *pipe_ctx) return &pipe_ctx->plane_res.scl_data.dscl_prog_data; } +static bool resource_allocate_mcache(struct dc_state *context, const struct dc_mcache_params *mcache_params) +{ + if (context->clk_mgr->ctx->dc->res_pool->funcs->program_mcache_pipe_config) + context->clk_mgr->ctx->dc->res_pool->funcs->program_mcache_pipe_config(context, mcache_params); + + return true; +} + void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuration_options *dml2_options) { dml2_options->callbacks.dc = dc; @@ -5540,6 +5552,7 @@ void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuratio dml2_options->callbacks.get_stream_status = &dc_state_get_stream_status; dml2_options->callbacks.get_stream_from_id = &dc_state_get_stream_from_id; dml2_options->callbacks.get_max_flickerless_instant_vtotal_increase = &dc_stream_get_max_flickerless_instant_vtotal_increase; + dml2_options->callbacks.allocate_mcache = &resource_allocate_mcache; dml2_options->svp_pstate.callbacks.dc = dc; dml2_options->svp_pstate.callbacks.add_phantom_plane = &dc_state_add_phantom_plane; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index e6fcc21bb9bc..922f23557f5d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -109,7 +109,8 @@ struct dc_plane_state *dc_create_plane_state(const struct dc *dc) ***************************************************************************** */ const struct dc_plane_status *dc_plane_get_status( - const struct dc_plane_state *plane_state) + const struct dc_plane_state *plane_state, + union dc_plane_status_update_flags flags) { const struct dc_plane_status *plane_status; struct dc *dc; @@ -136,7 +137,7 @@ const struct dc_plane_status *dc_plane_get_status( if (pipe_ctx->plane_state != plane_state) continue; - if (pipe_ctx->plane_state) + if (pipe_ctx->plane_state && flags.bits.address) pipe_ctx->plane_state->status.is_flip_pending = false; break; @@ -151,7 +152,8 @@ const struct dc_plane_status *dc_plane_get_status( if (pipe_ctx->plane_state != plane_state) continue; - dc->hwss.update_pending_status(pipe_ctx); + if (flags.bits.address) + dc->hwss.update_pending_status(pipe_ctx); } return plane_status; @@ -294,3 +296,17 @@ void dc_plane_force_dcc_and_tiling_disable(struct dc_plane_state *plane_state, dc->hwss.clear_surface_dcc_and_tiling(pipe_ctx, plane_state, clear_tiling); } } + +void dc_plane_copy_config(struct dc_plane_state *dst, const struct dc_plane_state *src) +{ + struct kref temp_refcount; + + /* backup persistent info */ + memcpy(&temp_refcount, &dst->refcount, sizeof(struct kref)); + + /* copy all configuration information */ + memcpy(dst, src, sizeof(struct dc_plane_state)); + + /* restore persistent info */ + memcpy(&dst->refcount, &temp_refcount, sizeof(struct kref)); +} diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 2230e36c4f12..1d917be36fc4 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -53,7 +53,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.331" +#define DC_VER "3.2.334" /** * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 6115b5364394..afbcf866520e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -39,6 +39,7 @@ #define CTX dc_dmub_srv->ctx #define DC_LOGGER CTX->logger +#define GPINT_RETRY_NUM 20 static void dc_dmub_srv_construct(struct dc_dmub_srv *dc_srv, struct dc *dc, struct dmub_srv *dmub) @@ -207,7 +208,7 @@ static bool dc_dmub_srv_fb_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_sr return false; do { - status = dmub_srv_wait_for_inbox_free(dmub, 100000, count - i); + status = dmub_srv_wait_for_inbox_free(dmub, 100000, count - i); } while (dc_dmub_srv->ctx->dc->debug.disable_timeout && status != DMUB_STATUS_OK); /* Requeue the command. */ @@ -247,6 +248,9 @@ bool dc_dmub_srv_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv, } else { res = dc_dmub_srv_fb_cmd_list_queue_execute(dc_dmub_srv, count, cmd_list); } + + if (res) + res = dmub_srv_update_inbox_status(dc_dmub_srv->dmub) == DMUB_STATUS_OK; } return res; @@ -1885,11 +1889,14 @@ void dc_dmub_srv_ips_query_residency_info(struct dc_dmub_srv *dc_dmub_srv, struc if (command_code == DMUB_GPINT__INVALID_COMMAND) return; - // send gpint commands and wait for ack - if (!dc_wake_and_execute_gpint(dc_dmub_srv->ctx, DMUB_GPINT__GET_IPS_RESIDENCY_PERCENT, - (uint16_t)(output->ips_mode), - &output->residency_percent, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) - output->residency_percent = 0; + for (i = 0; i < GPINT_RETRY_NUM; i++) { + // false could mean GPINT timeout, in which case we should retry + if (dc_wake_and_execute_gpint(dc_dmub_srv->ctx, DMUB_GPINT__GET_IPS_RESIDENCY_PERCENT, + (uint16_t)(output->ips_mode), &output->residency_percent, + DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) + break; + udelay(100); + } if (!dc_wake_and_execute_gpint(dc_dmub_srv->ctx, DMUB_GPINT__GET_IPS_RESIDENCY_ENTRY_COUNTER, (uint16_t)(output->ips_mode), diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index 77c87ad57220..0bad8304ccf6 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -159,6 +159,11 @@ struct dc_link_settings { uint8_t link_rate_set; }; +struct dc_tunnel_settings { + bool should_enable_dp_tunneling; + bool should_use_dp_bw_allocation; +}; + union dc_dp_ffe_preset { struct { uint8_t level : 4; @@ -943,10 +948,20 @@ union dpia_info { uint8_t raw; }; +/* DPCD[0xE0020] USB4_DRIVER_BW_CAPABILITY register. */ +union usb4_driver_bw_cap { + struct { + uint8_t rsvd :7; + uint8_t driver_bw_alloc_support :1; + } bits; + uint8_t raw; +}; + /* DP Tunneling over USB4 */ struct dpcd_usb4_dp_tunneling_info { union dp_tun_cap_support dp_tun_cap; union dpia_info dpia_info; + union usb4_driver_bw_cap driver_bw_cap; uint8_t usb4_driver_id; uint8_t usb4_topology_id[DPCD_USB4_TOPOLOGY_ID_LEN]; }; @@ -1486,5 +1501,11 @@ struct dp_trace { # ifndef DP_TUNNELING_BW_ALLOC_CAP_CHANGED # define DP_TUNNELING_BW_ALLOC_CAP_CHANGED (1 << 3) # endif +# ifndef DPTX_BW_ALLOC_UNMASK_IRQ +# define DPTX_BW_ALLOC_UNMASK_IRQ (1 << 6) +# endif +# ifndef DPTX_BW_ALLOC_MODE_ENABLE +# define DPTX_BW_ALLOC_MODE_ENABLE (1 << 7) +# endif #endif /* DC_DP_TYPES_H */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_plane.h b/drivers/gpu/drm/amd/display/dc/dc_plane.h index e9413685ed4f..14feb843e694 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_plane.h +++ b/drivers/gpu/drm/amd/display/dc/dc_plane.h @@ -28,13 +28,24 @@ #include "dc_hw_types.h" +union dc_plane_status_update_flags { + struct { + uint32_t address : 1; + } bits; + uint32_t raw; +}; + struct dc_plane_state *dc_create_plane_state(const struct dc *dc); const struct dc_plane_status *dc_plane_get_status( - const struct dc_plane_state *plane_state); + const struct dc_plane_state *plane_state, + union dc_plane_status_update_flags flags); void dc_plane_state_retain(struct dc_plane_state *plane_state); void dc_plane_state_release(struct dc_plane_state *plane_state); void dc_plane_force_dcc_and_tiling_disable(struct dc_plane_state *plane_state, bool clear_tiling); + +void dc_plane_copy_config(struct dc_plane_state *dst, const struct dc_plane_state *src); + #endif /* _DC_PLANE_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c index d9159ca55412..92f0a099d089 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c @@ -195,9 +195,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = { .dcn_downspread_percent = 0.5, .gpuvm_min_page_size_bytes = 4096, .hostvm_min_page_size_bytes = 4096, - .do_urgent_latency_adjustment = 1, + .do_urgent_latency_adjustment = 0, .urgent_latency_adjustment_fabric_clock_component_us = 0, - .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000, + .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, }; void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr) diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c index ed75319a07d5..d47cacfdb695 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c @@ -916,7 +916,7 @@ static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dm } //TODO : Could be possibly moved to a common helper layer. -static bool dml21_wrapper_get_plane_id(const struct dc_state *context, const struct dc_plane_state *plane, unsigned int *plane_id) +static bool dml21_wrapper_get_plane_id(const struct dc_state *context, unsigned int stream_id, const struct dc_plane_state *plane, unsigned int *plane_id) { int i, j; @@ -924,10 +924,12 @@ static bool dml21_wrapper_get_plane_id(const struct dc_state *context, const str return false; for (i = 0; i < context->stream_count; i++) { - for (j = 0; j < context->stream_status[i].plane_count; j++) { - if (context->stream_status[i].plane_states[j] == plane) { - *plane_id = (i << 16) | j; - return true; + if (context->streams[i]->stream_id == stream_id) { + for (j = 0; j < context->stream_status[i].plane_count; j++) { + if (context->stream_status[i].plane_states[j] == plane) { + *plane_id = (i << 16) | j; + return true; + } } } } @@ -950,14 +952,14 @@ static unsigned int map_stream_to_dml21_display_cfg(const struct dml2_context *d return location; } -static unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, +unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, unsigned int stream_id, const struct dc_plane_state *plane, const struct dc_state *context) { unsigned int plane_id; int i = 0; int location = -1; - if (!dml21_wrapper_get_plane_id(context, plane, &plane_id)) { + if (!dml21_wrapper_get_plane_id(context, stream_id, plane, &plane_id)) { ASSERT(false); return -1; } @@ -1043,7 +1045,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location; } else { for (plane_index = 0; plane_index < context->stream_status[stream_index].plane_count; plane_index++) { - disp_cfg_plane_location = map_plane_to_dml21_display_cfg(dml_ctx, context->stream_status[stream_index].plane_states[plane_index], context); + disp_cfg_plane_location = map_plane_to_dml21_display_cfg(dml_ctx, context->streams[stream_index]->stream_id, context->stream_status[stream_index].plane_states[plane_index], context); if (disp_cfg_plane_location < 0) disp_cfg_plane_location = dml_dispcfg->num_planes++; @@ -1054,7 +1056,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s populate_dml21_plane_config_from_plane_state(dml_ctx, &dml_dispcfg->plane_descriptors[disp_cfg_plane_location], context->stream_status[stream_index].plane_states[plane_index], context, stream_index); dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location; - if (dml21_wrapper_get_plane_id(context, context->stream_status[stream_index].plane_states[plane_index], &dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[disp_cfg_plane_location])) + if (dml21_wrapper_get_plane_id(context, context->streams[stream_index]->stream_id, context->stream_status[stream_index].plane_states[plane_index], &dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[disp_cfg_plane_location])) dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id_valid[disp_cfg_plane_location] = true; /* apply forced pstate policy */ diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.h index 069b939c672a..73a013be1e48 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.h +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.h @@ -11,6 +11,7 @@ struct dc_state; struct dcn_watermarks; union dcn_watermark_set; struct pipe_ctx; +struct dc_plane_state; struct dml2_context; struct dml2_configuration_options; @@ -25,4 +26,5 @@ void dml21_extract_watermark_sets(const struct dc *in_dc, union dcn_watermark_se void dml21_map_hw_resources(struct dml2_context *dml_ctx); void dml21_get_pipe_mcache_config(struct dc_state *context, struct pipe_ctx *pipe_ctx, struct dml2_per_plane_programming *pln_prog, struct dml2_pipe_configuration_descriptor *mcache_pipe_config); void dml21_set_dc_p_state_type(struct pipe_ctx *pipe_ctx, struct dml2_per_stream_programming *stream_programming, bool sub_vp_enabled); +unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, unsigned int stream_id, const struct dc_plane_state *plane, const struct dc_state *context); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c index ed6584535e89..208d3651b6ba 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c @@ -12,6 +12,8 @@ #include "dml21_translation_helper.h" #include "dml2_dc_resource_mgmt.h" +#define INVALID -1 + static bool dml21_allocate_memory(struct dml2_context **dml_ctx) { *dml_ctx = vzalloc(sizeof(struct dml2_context)); @@ -208,10 +210,40 @@ static void dml21_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_sta } } +static void dml21_prepare_mcache_params(struct dml2_context *dml_ctx, struct dc_state *context, struct dc_mcache_params *mcache_params) +{ + int dc_plane_idx = 0; + int dml_prog_idx, stream_idx, plane_idx; + struct dml2_per_plane_programming *pln_prog = NULL; + + for (stream_idx = 0; stream_idx < context->stream_count; stream_idx++) { + for (plane_idx = 0; plane_idx < context->stream_status[stream_idx].plane_count; plane_idx++) { + dml_prog_idx = map_plane_to_dml21_display_cfg(dml_ctx, context->streams[stream_idx]->stream_id, context->stream_status[stream_idx].plane_states[plane_idx], context); + if (dml_prog_idx == INVALID) { + continue; + } + pln_prog = &dml_ctx->v21.mode_programming.programming->plane_programming[dml_prog_idx]; + mcache_params[dc_plane_idx].valid = pln_prog->mcache_allocation.valid; + mcache_params[dc_plane_idx].num_mcaches_plane0 = pln_prog->mcache_allocation.num_mcaches_plane0; + mcache_params[dc_plane_idx].num_mcaches_plane1 = pln_prog->mcache_allocation.num_mcaches_plane1; + mcache_params[dc_plane_idx].requires_dedicated_mall_mcache = pln_prog->mcache_allocation.requires_dedicated_mall_mcache; + mcache_params[dc_plane_idx].last_slice_sharing.plane0_plane1 = pln_prog->mcache_allocation.last_slice_sharing.plane0_plane1; + memcpy(mcache_params[dc_plane_idx].mcache_x_offsets_plane0, + pln_prog->mcache_allocation.mcache_x_offsets_plane0, + sizeof(int) * (DML2_MAX_MCACHES + 1)); + memcpy(mcache_params[dc_plane_idx].mcache_x_offsets_plane1, + pln_prog->mcache_allocation.mcache_x_offsets_plane1, + sizeof(int) * (DML2_MAX_MCACHES + 1)); + dc_plane_idx++; + } + } +} + static bool dml21_mode_check_and_programming(const struct dc *in_dc, struct dc_state *context, struct dml2_context *dml_ctx) { bool result = false; struct dml2_build_mode_programming_in_out *mode_programming = &dml_ctx->v21.mode_programming; + struct dc_mcache_params mcache_params[MAX_PLANES] = {0}; memset(&dml_ctx->v21.display_config, 0, sizeof(struct dml2_display_cfg)); memset(&dml_ctx->v21.dml_to_dc_pipe_mapping, 0, sizeof(struct dml2_dml_to_dc_pipe_mapping)); @@ -246,6 +278,14 @@ static bool dml21_mode_check_and_programming(const struct dc *in_dc, struct dc_s dml2_map_dc_pipes(dml_ctx, context, NULL, &dml_ctx->v21.dml_to_dc_pipe_mapping, in_dc->current_state); /* if subvp phantoms are present, expand them into dc context */ dml21_handle_phantom_streams_planes(in_dc, context, dml_ctx); + + if (in_dc->res_pool->funcs->program_mcache_pipe_config) { + //Prepare mcache params for each plane based on mcache output from DML + dml21_prepare_mcache_params(dml_ctx, context, mcache_params); + + //populate mcache regs to each pipe + dml_ctx->config.callbacks.allocate_mcache(context, mcache_params); + } } /* Copy DML CLK, WM and REG outputs to bandwidth context */ diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.h index b2075b8c363b..42e715024bc9 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.h +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.h @@ -8,6 +8,7 @@ #include "os_types.h" #include "dml_top_soc_parameter_types.h" +#include "dml_top_display_cfg_types.h" struct dc; struct dc_state; @@ -65,4 +66,67 @@ struct socbb_ip_params_external { struct dml2_ip_capabilities ip_params; struct dml2_soc_bb soc_bb; }; + +/*mcache parameters decided by dml*/ +struct dc_mcache_params { + bool valid; + /* + * For iMALL, dedicated mall mcaches are required (sharing of last + * slice possible), for legacy phantom or phantom without return + * the only mall mcaches need to be valid. + */ + bool requires_dedicated_mall_mcache; + unsigned int num_mcaches_plane0; + unsigned int num_mcaches_plane1; + /* + * Generally, plane0/1 slices must use a disjoint set of caches + * but in some cases the final segement of the two planes can + * use the same cache. If plane0_plane1 is set, then this is + * allowed. + * + * Similarly, the caches allocated to MALL prefetcher are generally + * disjoint, but if mall_prefetch is set, then the final segment + * between the main and the mall pixel requestor can use the same + * cache. + * + * Note that both bits may be set at the same time. + */ + struct { + bool mall_comb_mcache_p0; + bool mall_comb_mcache_p1; + bool plane0_plane1; + } last_slice_sharing; + /* + * A plane is divided into vertical slices of mcaches, + * which wrap on the surface width. + * + * For example, if the surface width is 7680, and split into + * three slices of equal width, the boundary array would contain + * [2560, 5120, 7680] + * + * The assignments are + * 0 = [0 .. 2559] + * 1 = [2560 .. 5119] + * 2 = [5120 .. 7679] + * 0 = [7680 .. INF] + * The final element implicitly is the same as the first, and + * at first seems invalid since it is never referenced (since) + * it is outside the surface. However, its useful when shifting + * (see below). + * + * For any given valid mcache assignment, a shifted version, wrapped + * on the surface width boundary is also assumed to be valid. + * + * For example, shifting [2560, 5120, 7680] by -50 results in + * [2510, 5170, 7630]. + * + * The assignments are now: + * 0 = [0 .. 2509] + * 1 = [2510 .. 5169] + * 2 = [5170 .. 7629] + * 0 = [7630 .. INF] + */ + int mcache_x_offsets_plane0[DML2_MAX_MCACHES + 1]; + int mcache_x_offsets_plane1[DML2_MAX_MCACHES + 1]; +}; #endif diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h index 785226945699..5100f269368e 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h @@ -40,6 +40,7 @@ struct dc_sink; struct dc_stream_state; struct resource_context; struct display_stream_compressor; +struct dc_mcache_params; // Configuration of the MALL on the SoC struct dml2_soc_mall_info { @@ -107,6 +108,7 @@ struct dml2_dc_callbacks { unsigned int (*get_max_flickerless_instant_vtotal_increase)( struct dc_stream_state *stream, bool is_gaming); + bool (*allocate_mcache)(struct dc_state *context, const struct dc_mcache_params *mcache_params); }; struct dml2_dc_svp_callbacks { diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c index 1236e0f9a256..712aff7e17f7 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c @@ -120,10 +120,11 @@ void dpp401_set_cursor_attributes( enum dc_cursor_color_format color_format = cursor_attributes->color_format; int cur_rom_en = 0; - // DCN4 should always do Cursor degamma for Cursor Color modes if (color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA || color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) { - cur_rom_en = 1; + if (cursor_attributes->attribute_flags.bits.ENABLE_CURSOR_DEGAMMA) { + cur_rom_en = 1; + } } REG_UPDATE_3(CURSOR0_CONTROL, diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c index 5ed195377a6c..baed31611477 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c @@ -1032,7 +1032,7 @@ static struct hubp_funcs dcn401_hubp_funcs = { .hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected, .hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar, .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done, - .hubp_clear_tiling = hubp2_clear_tiling, + .hubp_clear_tiling = hubp401_clear_tiling, }; bool hubp401_construct( diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index 5e78b553adbd..858288c3b1ac 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -2053,7 +2053,7 @@ void dcn20_program_front_end_for_ctx( for (i = 0; i < dc->res_pool->pipe_count; i++) { pipe = &context->res_ctx.pipe_ctx[i]; - if (!pipe->top_pipe && !pipe->prev_odm_pipe && pipe->plane_state) { + if (pipe->plane_state) { ASSERT(!pipe->plane_state->triplebuffer_flips); /*turn off triple buffer for full update*/ dc->hwss.program_triplebuffer( diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c index 63077c1fad85..c814d957305a 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c @@ -1550,7 +1550,7 @@ static bool should_avoid_empty_tu(struct pipe_ctx *pipe_ctx) struct dc_link_settings *link_settings = &pipe_ctx->link_config.dp_link_settings; const struct dc *dc = pipe_ctx->stream->link->dc; - if (pipe_ctx->stream->link->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) + if (pipe_ctx->link_config.dp_tunnel_settings.should_enable_dp_tunneling == false) return false; // Not necessary for MST configurations diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index ae7194da5987..c4177a9a662f 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -525,11 +525,11 @@ bool dcn401_program_rmcm_luts( enum MCM_LUT_XABLE shaper_xable, lut3d_xable = MCM_LUT_DISABLE, lut1d_xable; enum hubp_3dlut_fl_mode mode; enum hubp_3dlut_fl_addressing_mode addr_mode; - enum hubp_3dlut_fl_format format; - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g; - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b; - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r; - enum hubp_3dlut_fl_width width; + enum hubp_3dlut_fl_format format = 0; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 0; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 0; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 0; + enum hubp_3dlut_fl_width width = 0; struct dc *dc = hubp->ctx->dc; bool bypass_rmcm_3dlut = false; @@ -654,9 +654,9 @@ void dcn401_populate_mcm_luts(struct dc *dc, enum hubp_3dlut_fl_mode mode; enum hubp_3dlut_fl_width width = 0; enum hubp_3dlut_fl_addressing_mode addr_mode; - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g; - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b; - enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g = 0; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b = 0; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r = 0; enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE; enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE; enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE; @@ -2260,9 +2260,9 @@ void dcn401_program_pipe( dc->res_pool->hubbub, pipe_ctx->plane_res.hubp->inst, pipe_ctx->hubp_regs.det_size); } - if (pipe_ctx->update_flags.raw || - (pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.raw) || - pipe_ctx->stream->update_flags.raw) + if (pipe_ctx->plane_state && (pipe_ctx->update_flags.raw || + pipe_ctx->plane_state->update_flags.raw || + pipe_ctx->stream->update_flags.raw)) dc->hwss.update_dchubp_dpp(dc, pipe_ctx, context); if (pipe_ctx->plane_state && (pipe_ctx->update_flags.bits.enable || @@ -2361,7 +2361,7 @@ void dcn401_program_front_end_for_ctx( for (i = 0; i < dc->res_pool->pipe_count; i++) { pipe = &context->res_ctx.pipe_ctx[i]; - if (!pipe->top_pipe && !pipe->prev_odm_pipe && pipe->plane_state) { + if (pipe->plane_state) { if (pipe->plane_state->triplebuffer_flips) BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 051bd83680d1..0cf349cafb3e 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -65,6 +65,7 @@ struct resource_pool; struct dc_state; struct resource_context; struct clk_bw_params; +struct dc_mcache_params; struct resource_funcs { enum engine_id (*get_preferred_eng_id_dpia)(unsigned int dpia_index); @@ -220,6 +221,8 @@ struct resource_funcs { unsigned int (*get_max_hw_cursor_size)(const struct dc *dc, struct dc_state *state, const struct dc_stream_state *stream); + bool (*program_mcache_pipe_config)(struct dc_state *context, + const struct dc_mcache_params *mcache_params); }; struct audio_support{ @@ -384,7 +387,9 @@ struct link_resource { struct link_config { struct dc_link_settings dp_link_settings; + struct dc_tunnel_settings dp_tunnel_settings; }; + union pipe_update_flags { struct { uint32_t enable : 1; diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h index 2948a696ee12..7d16351bba99 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -207,6 +207,9 @@ struct link_service { bool (*dp_decide_link_settings)( struct dc_stream_state *stream, struct dc_link_settings *link_setting); + void (*dp_decide_tunnel_settings)( + struct dc_stream_state *stream, + struct dc_tunnel_settings *dp_tunnel_setting); enum dp_link_encoding (*mst_decide_link_encoding_format)( const struct dc_link *link); bool (*edp_decide_link_settings)(struct dc_link *link, diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index 7a87a7c07c1b..a890f581f4e8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -32,6 +32,7 @@ #define MEMORY_TYPE_MULTIPLIER_CZ 4 #define MEMORY_TYPE_HBM 2 +#define MAX_MCACHES 8 #define IS_PIPE_SYNCD_VALID(pipe) ((((pipe)->pipe_idx_syncd) & 0x80)?1:0) @@ -65,6 +66,13 @@ struct resource_straps { uint32_t audio_stream_number; }; +struct dc_mcache_allocations { + int global_mcache_ids_plane0[MAX_MCACHES + 1]; + int global_mcache_ids_plane1[MAX_MCACHES + 1]; + int global_mcache_ids_mall_plane0[MAX_MCACHES + 1]; + int global_mcache_ids_mall_plane1[MAX_MCACHES + 1]; +}; + struct resource_create_funcs { void (*read_dce_straps)( struct dc_context *ctx, struct resource_straps *straps); diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c b/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c index 953f4a4dacad..33ce470e4c88 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c @@ -37,36 +37,9 @@ #include "ivsrcid/ivsrcid_vislands30.h" -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c b/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c index 2c72074310c7..d777b85e70da 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c @@ -46,36 +46,9 @@ #include "dc_types.h" -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - DC_HPD1_INT_STATUS, - DC_HPD1_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - DC_HPD1_INT_CONTROL, - DC_HPD1_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd1_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { @@ -391,5 +364,3 @@ struct irq_service *dal_irq_service_dce60_create( dce60_irq_construct(irq_service, init_data); return irq_service; } - - diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c b/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c index 49317934ef4f..3a9163acb49b 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c @@ -37,36 +37,9 @@ #include "dc_types.h" -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - DC_HPD1_INT_STATUS, - DC_HPD1_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - DC_HPD1_INT_CONTROL, - DC_HPD1_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd1_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { @@ -303,5 +276,3 @@ struct irq_service *dal_irq_service_dce80_create( dce80_irq_construct(irq_service, init_data); return irq_service; } - - diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c index 9ca28565a9d1..4ce9edd16344 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c @@ -129,36 +129,9 @@ static enum dc_irq_source to_dal_irq_source_dcn10(struct irq_service *irq_servic } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c index 916f0c974637..5847af0e66cb 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c @@ -130,36 +130,9 @@ static enum dc_irq_source to_dal_irq_source_dcn20( } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c index 1d61d475d36f..6417011d2246 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c @@ -80,36 +80,9 @@ static enum dc_irq_source to_dal_irq_source_dcn201( } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c index 42cdfe6c3538..71d2f065140b 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c @@ -132,36 +132,9 @@ static enum dc_irq_source to_dal_irq_source_dcn21(struct irq_service *irq_servic return DC_IRQ_SOURCE_INVALID; } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c index a443a8abb1ea..2a4080bdcf6b 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c @@ -139,36 +139,9 @@ static enum dc_irq_source to_dal_irq_source_dcn30( } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { @@ -447,4 +420,3 @@ struct irq_service *dal_irq_service_dcn30_create( dcn30_irq_construct(irq_service, init_data); return irq_service; } - diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c b/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c index 8ffc7e2c681a..624f1ac309f8 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c @@ -126,26 +126,9 @@ static enum dc_irq_source to_dal_irq_source_dcn302(struct irq_service *irq_servi } } -static bool hpd_ack(struct irq_service *irq_service, const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = get_reg_field_value(value, HPD0_DC_HPD_INT_STATUS, DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value(value, current_status ? 0 : 1, HPD0_DC_HPD_INT_CONTROL, DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c b/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c index 262bb8b74b15..137caffae916 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c @@ -77,26 +77,9 @@ static enum dc_irq_source to_dal_irq_source_dcn303(struct irq_service *irq_servi } } -static bool hpd_ack(struct irq_service *irq_service, const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = get_reg_field_value(value, HPD0_DC_HPD_INT_STATUS, DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value(value, current_status ? 0 : 1, HPD0_DC_HPD_INT_CONTROL, DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c b/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c index 53e78ae7eecf..921cb167d920 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c @@ -128,36 +128,9 @@ static enum dc_irq_source to_dal_irq_source_dcn31(struct irq_service *irq_servic } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn314/irq_service_dcn314.c b/drivers/gpu/drm/amd/display/dc/irq/dcn314/irq_service_dcn314.c index e0563e880432..0118fd6e5db0 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn314/irq_service_dcn314.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn314/irq_service_dcn314.c @@ -130,36 +130,9 @@ static enum dc_irq_source to_dal_irq_source_dcn314(struct irq_service *irq_servi } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c b/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c index 2ef22299101a..adebfc888618 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c @@ -135,36 +135,9 @@ static enum dc_irq_source to_dal_irq_source_dcn315( } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn32/irq_service_dcn32.c b/drivers/gpu/drm/amd/display/dc/irq/dcn32/irq_service_dcn32.c index f839afacd5a5..e9e315c75d76 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn32/irq_service_dcn32.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn32/irq_service_dcn32.c @@ -129,36 +129,9 @@ static enum dc_irq_source to_dal_irq_source_dcn32( } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn35/irq_service_dcn35.c b/drivers/gpu/drm/amd/display/dc/irq/dcn35/irq_service_dcn35.c index ea8c271171bc..79e5e8c137ca 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn35/irq_service_dcn35.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn35/irq_service_dcn35.c @@ -127,36 +127,9 @@ static enum dc_irq_source to_dal_irq_source_dcn35( } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn351/irq_service_dcn351.c b/drivers/gpu/drm/amd/display/dc/irq/dcn351/irq_service_dcn351.c index 7ec8e0de2f01..163b8ee9ebf7 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn351/irq_service_dcn351.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn351/irq_service_dcn351.c @@ -106,36 +106,9 @@ static enum dc_irq_source to_dal_irq_source_dcn351( } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c b/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c index ea958628f8b8..f716ab0fd30e 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c @@ -105,36 +105,9 @@ static enum dc_irq_source to_dal_irq_source_dcn36( } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn401/irq_service_dcn401.c b/drivers/gpu/drm/amd/display/dc/irq/dcn401/irq_service_dcn401.c index 8499e505cf3e..fd9bb1950c20 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn401/irq_service_dcn401.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn401/irq_service_dcn401.c @@ -109,36 +109,9 @@ static enum dc_irq_source to_dal_irq_source_dcn401( } } -static bool hpd_ack( - struct irq_service *irq_service, - const struct irq_source_info *info) -{ - uint32_t addr = info->status_reg; - uint32_t value = dm_read_reg(irq_service->ctx, addr); - uint32_t current_status = - get_reg_field_value( - value, - HPD0_DC_HPD_INT_STATUS, - DC_HPD_SENSE_DELAYED); - - dal_irq_service_ack_generic(irq_service, info); - - value = dm_read_reg(irq_service->ctx, info->enable_reg); - - set_reg_field_value( - value, - current_status ? 0 : 1, - HPD0_DC_HPD_INT_CONTROL, - DC_HPD_INT_POLARITY); - - dm_write_reg(irq_service->ctx, info->enable_reg, value); - - return true; -} - static struct irq_source_info_funcs hpd_irq_info_funcs = { .set = NULL, - .ack = hpd_ack + .ack = hpd0_ack }; static struct irq_source_info_funcs hpd_rx_irq_info_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c index eca3d7ee7e4e..b595a11c5eaf 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c +++ b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c @@ -41,6 +41,16 @@ #include "reg_helper.h" #include "irq_service.h" +//HPD0_DC_HPD_INT_STATUS +#define HPD0_DC_HPD_INT_STATUS__DC_HPD_SENSE_DELAYED_MASK 0x00000010L +#define HPD0_DC_HPD_INT_CONTROL__DC_HPD_INT_POLARITY_MASK 0x00000100L +#define HPD0_DC_HPD_INT_STATUS__DC_HPD_SENSE_DELAYED__SHIFT 0x4 +#define HPD0_DC_HPD_INT_CONTROL__DC_HPD_INT_POLARITY__SHIFT 0x8 +//HPD1_DC_HPD_INT_STATUS +#define DC_HPD1_INT_STATUS__DC_HPD1_SENSE_DELAYED_MASK 0x10 +#define DC_HPD1_INT_STATUS__DC_HPD1_SENSE_DELAYED__SHIFT 0x4 +#define DC_HPD1_INT_CONTROL__DC_HPD1_INT_POLARITY_MASK 0x100 +#define DC_HPD1_INT_CONTROL__DC_HPD1_INT_POLARITY__SHIFT 0x8 #define CTX \ @@ -177,3 +187,57 @@ enum dc_irq_source dal_irq_service_to_irq_source( src_id, ext_id); } + +bool hpd0_ack( + struct irq_service *irq_service, + const struct irq_source_info *info) +{ + uint32_t addr = info->status_reg; + uint32_t value = dm_read_reg(irq_service->ctx, addr); + uint32_t current_status = + get_reg_field_value( + value, + HPD0_DC_HPD_INT_STATUS, + DC_HPD_SENSE_DELAYED); + + dal_irq_service_ack_generic(irq_service, info); + + value = dm_read_reg(irq_service->ctx, info->enable_reg); + + set_reg_field_value( + value, + current_status ? 0 : 1, + HPD0_DC_HPD_INT_CONTROL, + DC_HPD_INT_POLARITY); + + dm_write_reg(irq_service->ctx, info->enable_reg, value); + + return true; +} + +bool hpd1_ack( + struct irq_service *irq_service, + const struct irq_source_info *info) +{ + uint32_t addr = info->status_reg; + uint32_t value = dm_read_reg(irq_service->ctx, addr); + uint32_t current_status = + get_reg_field_value( + value, + DC_HPD1_INT_STATUS, + DC_HPD1_SENSE_DELAYED); + + dal_irq_service_ack_generic(irq_service, info); + + value = dm_read_reg(irq_service->ctx, info->enable_reg); + + set_reg_field_value( + value, + current_status ? 0 : 1, + DC_HPD1_INT_CONTROL, + DC_HPD1_INT_POLARITY); + + dm_write_reg(irq_service->ctx, info->enable_reg, value); + + return true; +} diff --git a/drivers/gpu/drm/amd/display/dc/irq/irq_service.h b/drivers/gpu/drm/amd/display/dc/irq/irq_service.h index b178f85944cd..bbcef3d2fe33 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/irq_service.h +++ b/drivers/gpu/drm/amd/display/dc/irq/irq_service.h @@ -82,4 +82,12 @@ void dal_irq_service_set_generic( const struct irq_source_info *info, bool enable); +bool hpd0_ack( + struct irq_service *irq_service, + const struct irq_source_info *info); + +bool hpd1_ack( + struct irq_service *irq_service, + const struct irq_source_info *info); + #endif diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index cc9191a5c9e6..9655e6fa53a4 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -611,6 +611,7 @@ static bool detect_dp(struct dc_link *link, link->dpcd_caps.dongle_type = sink_caps->dongle_type; link->dpcd_caps.is_dongle_type_one = sink_caps->is_dongle_type_one; link->dpcd_caps.dpcd_rev.raw = 0; + link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.raw = 0; } return true; @@ -1007,21 +1008,11 @@ static bool detect_link_and_local_sink(struct dc_link *link, link->reported_link_cap.link_rate > LINK_RATE_HIGH3) link->reported_link_cap.link_rate = LINK_RATE_HIGH3; - /* - * If this is DP over USB4 link then we need to: - * - Enable BW ALLOC support on DPtx if applicable - */ - if (dc->config.usb4_bw_alloc_support) { - if (link_dp_dpia_set_dptx_usb4_bw_alloc_support(link)) { - /* update with non reduced link cap if bw allocation mode is supported */ - if (link->dpia_bw_alloc_config.nrd_max_link_rate && - link->dpia_bw_alloc_config.nrd_max_lane_count) { - link->reported_link_cap.link_rate = - link->dpia_bw_alloc_config.nrd_max_link_rate; - link->reported_link_cap.lane_count = - link->dpia_bw_alloc_config.nrd_max_lane_count; - } - } + if (link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dp_tunneling + && link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dpia_bw_alloc + && link->dpcd_caps.usb4_dp_tun_info.driver_bw_cap.bits.driver_bw_alloc_support) { + if (link_dpia_enable_usb4_dp_bw_alloc_mode(link) == false) + link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dpia_bw_alloc = false; } break; } diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 268626e73c54..273a3be6d593 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -148,6 +148,7 @@ void link_blank_dp_stream(struct dc_link *link, bool hw_init) void link_set_all_streams_dpms_off_for_link(struct dc_link *link) { struct pipe_ctx *pipes[MAX_PIPES]; + struct dc_stream_state *streams[MAX_PIPES]; struct dc_state *state = link->dc->current_state; uint8_t count; int i; @@ -160,10 +161,18 @@ void link_set_all_streams_dpms_off_for_link(struct dc_link *link) link_get_master_pipes_with_dpms_on(link, state, &count, pipes); + /* The subsequent call to dc_commit_updates_for_stream for a full update + * will release the current state and swap to a new state. Releasing the + * current state results in the stream pointers in the pipe_ctx structs + * to be zero'd. Hence, cache all streams prior to dc_commit_updates_for_stream. + */ + for (i = 0; i < count; i++) + streams[i] = pipes[i]->stream; + for (i = 0; i < count; i++) { - stream_update.stream = pipes[i]->stream; + stream_update.stream = streams[i]; dc_commit_updates_for_stream(link->ctx->dc, NULL, 0, - pipes[i]->stream, &stream_update, + streams[i], &stream_update, state); } @@ -2365,7 +2374,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) update_psp_stream_config(pipe_ctx, true); dc->hwss.blank_stream(pipe_ctx); - if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) + if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation) deallocate_usb4_bandwidth(pipe_ctx->stream); if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) @@ -2433,7 +2442,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) if (link->connector_signal == SIGNAL_TYPE_EDP && dc->debug.psp_disabled_wa) { /* reset internal save state to default since eDP is off */ enum dp_panel_mode panel_mode = dp_get_panel_mode(pipe_ctx->stream->link); - /* since current psp not loaded, we need to reset it to default*/ + /* since current psp not loaded, we need to reset it to default */ link->panel_mode = panel_mode; } } @@ -2611,7 +2620,7 @@ void link_set_dpms_on( if (dc_is_dp_signal(pipe_ctx->stream->signal)) dp_set_hblank_reduction_on_rx(pipe_ctx); - if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) + if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation) allocate_usb4_bandwidth(pipe_ctx->stream); if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index 0125f2cfc114..1a04f4b74585 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -156,6 +156,7 @@ static void construct_link_service_dp_capability(struct link_service *link_srv) link_srv->dp_get_encoding_format = link_dp_get_encoding_format; link_srv->dp_should_enable_fec = dp_should_enable_fec; link_srv->dp_decide_link_settings = link_decide_link_settings; + link_srv->dp_decide_tunnel_settings = link_decide_dp_tunnel_settings; link_srv->mst_decide_link_encoding_format = mst_decide_link_encoding_format; link_srv->edp_decide_link_settings = edp_decide_link_settings; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 21ee0d96c9d4..8f79881ad9f1 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -158,6 +158,14 @@ uint8_t dp_parse_lttpr_repeater_count(uint8_t lttpr_repeater_count) return 0; // invalid value } +uint32_t dp_get_closest_lttpr_offset(uint8_t lttpr_count) +{ + /* Calculate offset for LTTPR closest to DPTX which is highest in the chain + * Offset is 0 for single LTTPR cases as base LTTPR DPCD addresses target LTTPR 1 + */ + return DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE * (lttpr_count - 1); +} + uint32_t link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw) { switch (bw) { @@ -2013,11 +2021,9 @@ static bool retrieve_link_cap(struct dc_link *link) sizeof(link->dpcd_caps.max_uncompressed_pixel_rate_cap.raw)); /* Read DP tunneling information. */ - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { - status = dpcd_get_tunneling_device_data(link); - if (status != DC_OK) - dm_error("%s: Read DP tunneling device data failed.\n", __func__); - } + status = dpcd_get_tunneling_device_data(link); + if (status != DC_OK) + dm_error("%s: Read DP tunneling device data failed.\n", __func__); retrieve_cable_id(link); dpcd_write_cable_id_to_dprx(link); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h index 0ce0af3ddbeb..940b147cc5d4 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h @@ -48,6 +48,9 @@ enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link); /* Convert PHY repeater count read from DPCD uint8_t. */ uint8_t dp_parse_lttpr_repeater_count(uint8_t lttpr_repeater_count); +/* Calculate embedded LTTPR address offset for vendor-specific behaviour */ +uint32_t dp_get_closest_lttpr_offset(uint8_t lttpr_count); + bool dp_is_sink_present(struct dc_link *link); bool dp_is_lttpr_present(struct dc_link *link); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c index c149210096ac..22bfdced64ab 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c @@ -62,6 +62,36 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link) if (status != DC_OK) goto err; + link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.raw = + dpcd_dp_tun_data[DP_TUNNELING_CAPABILITIES_SUPPORT - DP_TUNNELING_CAPABILITIES_SUPPORT]; + + if (link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dp_tunneling == false) + goto err; + + link->dpcd_caps.usb4_dp_tun_info.dpia_info.raw = + dpcd_dp_tun_data[DP_IN_ADAPTER_INFO - DP_TUNNELING_CAPABILITIES_SUPPORT]; + link->dpcd_caps.usb4_dp_tun_info.usb4_driver_id = + dpcd_dp_tun_data[DP_USB4_DRIVER_ID - DP_TUNNELING_CAPABILITIES_SUPPORT]; + + if (link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dpia_bw_alloc) { + status = core_link_read_dpcd(link, USB4_DRIVER_BW_CAPABILITY, + dpcd_dp_tun_data, 1); + + if (status != DC_OK) + goto err; + + link->dpcd_caps.usb4_dp_tun_info.driver_bw_cap.raw = dpcd_dp_tun_data[0]; + } + + DC_LOG_DEBUG("%s: Link[%d] DP tunneling support (RouterId=%d AdapterId=%d) " + "DPIA_BW_Alloc_support=%d " + "CM_BW_Alloc_support=%d ", + __func__, link->link_index, + link->dpcd_caps.usb4_dp_tun_info.usb4_driver_id, + link->dpcd_caps.usb4_dp_tun_info.dpia_info.bits.dpia_num, + link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dpia_bw_alloc, + link->dpcd_caps.usb4_dp_tun_info.driver_bw_cap.bits.driver_bw_alloc_support); + status = core_link_read_dpcd( link, DP_USB4_ROUTER_TOPOLOGY_ID, @@ -71,13 +101,6 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link) if (status != DC_OK) goto err; - link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.raw = - dpcd_dp_tun_data[DP_TUNNELING_CAPABILITIES_SUPPORT - DP_TUNNELING_CAPABILITIES_SUPPORT]; - link->dpcd_caps.usb4_dp_tun_info.dpia_info.raw = - dpcd_dp_tun_data[DP_IN_ADAPTER_INFO - DP_TUNNELING_CAPABILITIES_SUPPORT]; - link->dpcd_caps.usb4_dp_tun_info.usb4_driver_id = - dpcd_dp_tun_data[DP_USB4_DRIVER_ID - DP_TUNNELING_CAPABILITIES_SUPPORT]; - for (i = 0; i < DPCD_USB4_TOPOLOGY_ID_LEN; i++) link->dpcd_caps.usb4_dp_tun_info.usb4_topology_id[i] = dpcd_topology_data[i]; @@ -120,3 +143,20 @@ bool dpia_query_hpd_status(struct dc_link *link) return link->hpd_status; } +void link_decide_dp_tunnel_settings(struct dc_stream_state *stream, + struct dc_tunnel_settings *dp_tunnel_setting) +{ + struct dc_link *link = stream->link; + + memset(dp_tunnel_setting, 0, sizeof(*dp_tunnel_setting)); + + if ((stream->signal == SIGNAL_TYPE_DISPLAY_PORT) || (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) { + dp_tunnel_setting->should_enable_dp_tunneling = + link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dp_tunneling; + + if (link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dpia_bw_alloc + && link->dpcd_caps.usb4_dp_tun_info.driver_bw_cap.bits.driver_bw_alloc_support) + dp_tunnel_setting->should_use_dp_bw_allocation = true; + } +} + diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.h index 363f45a1a964..a61edfc9ca7a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.h @@ -38,4 +38,10 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link); * Returns true if HPD high. */ bool dpia_query_hpd_status(struct dc_link *link); + +/* Decide the DP tunneling settings based on the DPCD capabilities + */ +void link_decide_dp_tunnel_settings(struct dc_stream_state *stream, + struct dc_tunnel_settings *dp_tunnel_setting); + #endif /* __DC_LINK_DPIA_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index a254ead2f7e8..3af7564a84f1 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -46,9 +46,10 @@ */ static bool link_dp_is_bw_alloc_available(struct dc_link *link) { - return (link && link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA - && link->hpd_status - && link->dpia_bw_alloc_config.bw_alloc_enabled); + return (link && link->hpd_status + && link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dp_tunneling + && link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dpia_bw_alloc + && link->dpcd_caps.usb4_dp_tun_info.driver_bw_cap.bits.driver_bw_alloc_support); } static void reset_bw_alloc_struct(struct dc_link *link) @@ -141,7 +142,7 @@ static int get_non_reduced_max_lane_count(struct dc_link *link) * granuality, Driver_ID, CM_Group, & populate the BW allocation structs * for host router and dpia */ -static void init_usb4_bw_struct(struct dc_link *link) +static void retrieve_usb4_dp_bw_allocation_info(struct dc_link *link) { reset_bw_alloc_struct(link); @@ -282,49 +283,26 @@ static void link_dpia_send_bw_alloc_request(struct dc_link *link, int req_bw) // ------------------------------------------------------------------ // PUBLIC FUNCTIONS // ------------------------------------------------------------------ -bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link) +bool link_dpia_enable_usb4_dp_bw_alloc_mode(struct dc_link *link) { bool ret = false; - uint8_t response = 0, - bw_support_dpia = 0, - bw_support_cm = 0; + uint8_t val; - if (!(link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && link->hpd_status)) - goto out; + if (link->hpd_status) { + val = DPTX_BW_ALLOC_MODE_ENABLE | DPTX_BW_ALLOC_UNMASK_IRQ; - if (core_link_read_dpcd( - link, - DP_TUNNELING_CAPABILITIES, - &response, - sizeof(uint8_t)) == DC_OK) - bw_support_dpia = (response >> 7) & 1; - - if (core_link_read_dpcd( - link, - USB4_DRIVER_BW_CAPABILITY, - &response, - sizeof(uint8_t)) == DC_OK) - bw_support_cm = (response >> 7) & 1; - - /* Send request acknowledgment to Turn ON DPTX support */ - if (bw_support_cm && bw_support_dpia) { - - response = 0x80; - if (core_link_write_dpcd( - link, - DPTX_BW_ALLOCATION_MODE_CONTROL, - &response, - sizeof(uint8_t)) != DC_OK) { - DC_LOG_DEBUG("%s: FAILURE Enabling DPtx BW Allocation Mode Support for link(%d)\n", - __func__, link->link_index); - } else { - // SUCCESS Enabled DPtx BW Allocation Mode Support - DC_LOG_DEBUG("%s: SUCCESS Enabling DPtx BW Allocation Mode Support for link(%d)\n", - __func__, link->link_index); + if (core_link_write_dpcd(link, DPTX_BW_ALLOCATION_MODE_CONTROL, &val, sizeof(uint8_t)) == DC_OK) { + DC_LOG_DEBUG("%s: link[%d] DPTX BW allocation mode enabled", __func__, link->link_index); + + retrieve_usb4_dp_bw_allocation_info(link); + + if (link->dpia_bw_alloc_config.nrd_max_link_rate && link->dpia_bw_alloc_config.nrd_max_lane_count) { + link->reported_link_cap.link_rate = link->dpia_bw_alloc_config.nrd_max_link_rate; + link->reported_link_cap.lane_count = link->dpia_bw_alloc_config.nrd_max_lane_count; + } - ret = true; - init_usb4_bw_struct(link); link->dpia_bw_alloc_config.bw_alloc_enabled = true; + ret = true; /* * During DP tunnel creation, CM preallocates BW and reduces estimated BW of other @@ -332,11 +310,12 @@ bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link) * to make the CM to release preallocation and update estimated BW correctly for * all DPIAs per host router */ + // TODO: Zero allocation can be removed once the MSFT CM fix has been released link_dp_dpia_allocate_usb4_bandwidth_for_stream(link, 0); - } + } else + DC_LOG_DEBUG("%s: link[%d] failed to enable DPTX BW allocation mode", __func__, link->link_index); } -out: return ret; } @@ -378,7 +357,8 @@ void link_dp_dpia_handle_bw_alloc_status(struct dc_link *link, uint8_t status) */ void dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int peak_bw) { - if (link && link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && link->dpia_bw_alloc_config.bw_alloc_enabled) { + if (link && link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dp_tunneling + && link->dpia_bw_alloc_config.bw_alloc_enabled) { //1. Hot Plug if (link->hpd_status && peak_bw > 0) { // If DP over USB4 then we need to check BW allocation @@ -401,7 +381,7 @@ void link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int r if (link_dp_is_bw_alloc_available(link)) link_dpia_send_bw_alloc_request(link, req_bw); else - DC_LOG_DEBUG("%s: Not able to send the BW Allocation request", __func__); + DC_LOG_DEBUG("%s: BW Allocation mode not available", __func__); } bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, const unsigned int num_dpias) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h index 6df9b946b00f..801965b5f9a4 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h @@ -43,13 +43,13 @@ enum bw_type { }; /* - * Enable BW Allocation Mode Support from the DP-Tx side + * Enable USB4 DP BW allocation mode * * @link: pointer to the dc_link struct instance * * return: SUCCESS or FAILURE */ -bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link); +bool link_dpia_enable_usb4_dp_bw_alloc_mode(struct dc_link *link); /* * Allocates only what the stream needs for bw, so if: diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c index 991b8ad4984b..693477413347 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c @@ -352,7 +352,7 @@ enum dc_status dp_read_hpd_rx_irq_data( irq_data->raw, DP_SINK_STATUS - DP_SINK_COUNT + 1); - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { + if (link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dp_tunneling) { retval = core_link_read_dpcd( link, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, &irq_data->bytes.link_service_irq_esi0.raw, 1); @@ -521,7 +521,7 @@ bool dp_handle_hpd_rx_irq(struct dc_link *link, dp_trace_link_loss_increment(link); } - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { + if (link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dp_tunneling) { if (hpd_irq_dpcd_data.bytes.link_service_irq_esi0.bits.DP_LINK_TUNNELING_IRQ) dp_handle_tunneling_irq(link); } diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index ef358afdfb65..2dc1a660e504 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -785,7 +785,6 @@ void override_training_settings( lt_settings->lttpr_mode = LTTPR_MODE_NON_LTTPR; dp_get_lttpr_mode_override(link, <_settings->lttpr_mode); - } enum dc_dp_training_pattern decide_cr_training_pattern( diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c index 5a5d48fadbf2..66d0fb1b9b9d 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c @@ -142,6 +142,14 @@ void decide_8b_10b_training_settings( lt_settings->lttpr_mode = dp_decide_8b_10b_lttpr_mode(link); lt_settings->cr_pattern_time = get_cr_training_aux_rd_interval(link, link_setting, lt_settings->lttpr_mode); dp_hw_to_dpcd_lane_settings(lt_settings, lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); + + /* Some embedded LTTPRs rely on receiving TPS2 before LT to interop reliably with sensitive VGA dongles + * This allows these LTTPRs to minimize freq/phase and skew variation during lock and deskew sequences + */ + if ((link->chip_caps & AMD_EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK) == + AMD_EXT_DISPLAY_PATH_CAPS__DP_EARLY_8B10B_TPS2) { + lt_settings->lttpr_early_tps2 = true; + } } enum lttpr_mode dp_decide_8b_10b_lttpr_mode(struct dc_link *link) @@ -173,6 +181,42 @@ enum lttpr_mode dp_decide_8b_10b_lttpr_mode(struct dc_link *link) return LTTPR_MODE_NON_LTTPR; } +static void set_link_settings_and_perform_early_tps2_retimer_pre_lt_sequence(struct dc_link *link, + const struct link_resource *link_res, + struct link_training_settings *lt_settings, + uint32_t lttpr_count) +{ + /* Vendor-specific LTTPR early TPS2 sequence: + * 1. Output TPS2 + * 2. Wait 400us + * 3. Set link settings as usual + * 4. Write TPS1 to DP_TRAINING_PATTERN_SET_PHY_REPEATERx targeting LTTPR closest to host + * 5. Wait 1ms + * 6. Begin link training as usual + * */ + + uint32_t closest_lttpr_address_offset = dp_get_closest_lttpr_offset(lttpr_count); + + union dpcd_training_pattern dpcd_pattern = {0}; + + dpcd_pattern.v1_4.TRAINING_PATTERN_SET = 1; + dpcd_pattern.v1_4.SCRAMBLING_DISABLE = 1; + + DC_LOG_HW_LINK_TRAINING("%s\n GPU sends TPS2. Wait 400us.\n", __func__); + + dp_set_hw_training_pattern(link, link_res, DP_TRAINING_PATTERN_SEQUENCE_2, DPRX); + + dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX); + + udelay(400); + + dpcd_set_link_settings(link, lt_settings); + + core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET_PHY_REPEATER1 + closest_lttpr_address_offset, &dpcd_pattern.raw, 1); + + udelay(1000); + } + enum link_training_result perform_8b_10b_clock_recovery_sequence( struct dc_link *link, const struct link_resource *link_res, @@ -383,7 +427,7 @@ enum link_training_result dp_perform_8b_10b_link_training( { enum link_training_result status = LINK_TRAINING_SUCCESS; - uint8_t repeater_cnt; + uint8_t repeater_cnt = dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt); uint8_t repeater_id; uint8_t lane = 0; @@ -391,14 +435,16 @@ enum link_training_result dp_perform_8b_10b_link_training( start_clock_recovery_pattern_early(link, link_res, lt_settings, DPRX); /* 1. set link rate, lane count and spread. */ - dpcd_set_link_settings(link, lt_settings); + if (lt_settings->lttpr_early_tps2) + set_link_settings_and_perform_early_tps2_retimer_pre_lt_sequence(link, link_res, lt_settings, repeater_cnt); + else + dpcd_set_link_settings(link, lt_settings); if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) { /* 2. perform link training (set link training done * to false is done as well) */ - repeater_cnt = dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt); for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS); repeater_id--) { diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c index 002eb926cca4..e0008c5f08ad 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c @@ -1299,7 +1299,7 @@ static void spl_set_easf_data(struct spl_scratch *spl_scratch, struct spl_out *s if (enable_easf_v) { dscl_prog_data->easf_v_en = true; dscl_prog_data->easf_v_ring = 0; - dscl_prog_data->easf_v_sharp_factor = 0; + dscl_prog_data->easf_v_sharp_factor = 1; dscl_prog_data->easf_v_bf1_en = 1; // 1-bit, BF1 calculation enable, 0=disable, 1=enable dscl_prog_data->easf_v_bf2_mode = 0xF; // 4-bit, BF2 calculation mode /* 2-bit, BF3 chroma mode correction calculation mode */ @@ -1463,7 +1463,7 @@ static void spl_set_easf_data(struct spl_scratch *spl_scratch, struct spl_out *s if (enable_easf_h) { dscl_prog_data->easf_h_en = true; dscl_prog_data->easf_h_ring = 0; - dscl_prog_data->easf_h_sharp_factor = 0; + dscl_prog_data->easf_h_sharp_factor = 1; dscl_prog_data->easf_h_bf1_en = 1; // 1-bit, BF1 calculation enable, 0=disable, 1=enable dscl_prog_data->easf_h_bf2_mode = diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h index 1c3949b24611..36a284305a70 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h @@ -480,6 +480,10 @@ enum sharpness_setting { SHARPNESS_ZERO, SHARPNESS_CUSTOM }; +enum sharpness_range_source { + SHARPNESS_RANGE_DCN = 0, + SHARPNESS_RANGE_DCN_OVERRIDE +}; struct spl_sharpness_range { int sdr_rgb_min; int sdr_rgb_max; diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index e759ce6ca700..3f3fa1b6a69e 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -445,6 +445,8 @@ struct dmub_srv_hw_funcs { uint32_t (*emul_get_inbox1_rptr)(struct dmub_srv *dmub); + uint32_t (*emul_get_inbox1_wptr)(struct dmub_srv *dmub); + void (*emul_set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset); bool (*is_supported)(struct dmub_srv *dmub); @@ -1053,4 +1055,16 @@ enum dmub_status dmub_srv_wait_for_inbox_free(struct dmub_srv *dmub, uint32_t timeout_us, uint32_t num_free_required); +/** + * dmub_srv_update_inbox_status() - Updates pending status for inbox & reg inbox0 + * @dmub: the dmub service + * + * Return: + * DMUB_STATUS_OK - success + * DMUB_STATUS_TIMEOUT - wait for buffer to flush timed out + * DMUB_STATUS_HW_FAILURE - issue with HW programming + * DMUB_STATUS_INVALID - unspecified error + */ +enum dmub_status dmub_srv_update_inbox_status(struct dmub_srv *dmub); + #endif /* _DMUB_SRV_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 76e9dcc15466..57fa05bddb45 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -550,6 +550,11 @@ union replay_hw_flags { * @is_alpm_initialized: Indicates whether ALPM is initialized */ uint32_t is_alpm_initialized : 1; + + /** + * @alpm_mode: Indicates ALPM mode selected + */ + uint32_t alpm_mode : 2; } bitfields; uint32_t u32All; @@ -742,6 +747,14 @@ enum dmub_ips_disable_type { DMUB_IPS_DISABLE_IPS2_Z10 = 4, DMUB_IPS_DISABLE_DYNAMIC = 5, DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF = 6, + DMUB_IPS_DISABLE_Z8_RETENTION = 7, +}; + +enum dmub_ips_rcg_disable_type { + DMUB_IPS_RCG_ENABLE = 0, + DMUB_IPS0_RCG_DISABLE = 1, + DMUB_IPS1_RCG_DISABLE = 2, + DMUB_IPS_RCG_DISABLE = 3 }; #define DMUB_IPS1_ALLOW_MASK 0x00000001 @@ -820,11 +833,12 @@ enum dmub_shared_state_feature_id { */ union dmub_shared_state_ips_fw_signals { struct { - uint32_t ips1_commit : 1; /**< 1 if in IPS1 */ + uint32_t ips1_commit : 1; /**< 1 if in IPS1 or IPS0 RCG */ uint32_t ips2_commit : 1; /**< 1 if in IPS2 */ uint32_t in_idle : 1; /**< 1 if DMCUB is in idle */ uint32_t detection_required : 1; /**< 1 if detection is required */ - uint32_t reserved_bits : 28; /**< Reversed */ + uint32_t ips1z8_commit: 1; /**< 1 if in IPS1 Z8 Retention */ + uint32_t reserved_bits : 27; /**< Reversed */ } bits; uint32_t all; }; @@ -839,7 +853,10 @@ union dmub_shared_state_ips_driver_signals { uint32_t allow_ips2 : 1; /**< 1 is IPS1 is allowed */ uint32_t allow_z10 : 1; /**< 1 if Z10 is allowed */ uint32_t allow_idle: 1; /**< 1 if driver is allowing idle */ - uint32_t reserved_bits : 27; /**< Reversed bits */ + uint32_t allow_ips0_rcg : 1; /**< 1 is IPS0 RCG is allowed */ + uint32_t allow_ips1_rcg : 1; /**< 1 is IPS1 RCG is allowed */ + uint32_t allow_ips1z8 : 1; /**< 1 is IPS1 Z8 Retention is allowed */ + uint32_t reserved_bits : 24; /**< Reversed bits */ } bits; uint32_t all; }; @@ -868,7 +885,9 @@ struct dmub_shared_state_ips_fw { uint32_t ips1_exit_count; /**< Exit counter for IPS1 */ uint32_t ips2_entry_count; /**< Entry counter for IPS2 */ uint32_t ips2_exit_count; /**< Exit counter for IPS2 */ - uint32_t reserved[55]; /**< Reversed, to be updated when adding new fields. */ + uint32_t ips1_z8ret_entry_count; /**< Entry counter for IPS1 Z8 Retention */ + uint32_t ips1_z8ret_exit_count; /**< Exit counter for IPS1 Z8 Retention */ + uint32_t reserved[53]; /**< Reversed, to be updated when adding new fields. */ }; /* 248-bytes, fixed */ /** @@ -1256,6 +1275,10 @@ enum dmub_gpint_command { * DESC: Setup debug configs. */ DMUB_GPINT__SETUP_DEBUG_MODE = 136, + /** + * DESC: Initiates IPS wake sequence. + */ + DMUB_GPINT__IPS_DEBUG_WAKE = 137, }; /** @@ -2116,6 +2139,11 @@ union dmub_cmd_fams2_config { } stream_v1; //v1 }; +struct dmub_fams2_config_v2 { + struct dmub_cmd_fams2_global_config global; + struct dmub_fams2_stream_static_state_v1 stream_v1[DMUB_MAX_STREAMS]; //v1 +}; + /** * DMUB rb command definition for FAMS2 (merged SubVP, FPO, Legacy) */ @@ -2125,6 +2153,22 @@ struct dmub_rb_cmd_fams2 { }; /** + * Indirect buffer descriptor + */ +struct dmub_ib_data { + union dmub_addr src; // location of indirect buffer in memory + uint16_t size; // indirect buffer size in bytes +}; + +/** + * DMUB rb command definition for commands passed over indirect buffer + */ +struct dmub_rb_cmd_ib { + struct dmub_cmd_header header; + struct dmub_ib_data ib_data; +}; + +/** * enum dmub_cmd_idle_opt_type - Idle optimization command type. */ enum dmub_cmd_idle_opt_type { @@ -2147,6 +2191,11 @@ enum dmub_cmd_idle_opt_type { * DCN hardware notify power state. */ DMUB_CMD__IDLE_OPT_SET_DC_POWER_STATE = 3, + + /** + * DCN notify to release HW. + */ + DMUB_CMD__IDLE_OPT_RELEASE_HW = 4, }; /** @@ -2908,8 +2957,9 @@ enum dmub_cmd_fams_type { */ DMUB_CMD__FAMS_SET_MANUAL_TRIGGER = 3, DMUB_CMD__FAMS2_CONFIG = 4, - DMUB_CMD__FAMS2_DRR_UPDATE = 5, - DMUB_CMD__FAMS2_FLIP = 6, + DMUB_CMD__FAMS2_IB_CONFIG = 5, + DMUB_CMD__FAMS2_DRR_UPDATE = 6, + DMUB_CMD__FAMS2_FLIP = 7, }; /** @@ -3616,6 +3666,12 @@ struct dmub_rb_cmd_psr_set_power_opt { struct dmub_cmd_psr_set_power_opt_data psr_set_power_opt_data; }; +enum dmub_alpm_mode { + ALPM_AUXWAKE = 0, + ALPM_AUXLESS = 1, + ALPM_UNSUPPORTED = 2, +}; + /** * Definition of Replay Residency GPINT command. * Bit[0] - Residency mode for Revision 0 @@ -3749,6 +3805,15 @@ enum dmub_cmd_replay_general_subtype { REPLAY_GENERAL_CMD_SET_LOW_RR_ACTIVATE, }; +struct dmub_alpm_auxless_data { + uint16_t lfps_setup_ns; + uint16_t lfps_period_ns; + uint16_t lfps_silence_ns; + uint16_t lfps_t1_t2_override_us; + short lfps_t1_t2_offset_us; + uint8_t lttpr_count; +}; + /** * Data passed from driver to FW in a DMUB_CMD__REPLAY_COPY_SETTINGS command. */ @@ -3819,6 +3884,10 @@ struct dmub_cmd_replay_copy_settings_data { * Use FSM state for Replay power up/down */ uint8_t use_phy_fsm; + /** + * Use for AUX-less ALPM LFPS wake operation + */ + struct dmub_alpm_auxless_data auxless_alpm_data; }; /** @@ -5884,8 +5953,11 @@ union dmub_rb_cmd { * Definition of a DMUB_CMD__PSP_ASSR_ENABLE command. */ struct dmub_rb_cmd_assr_enable assr_enable; + struct dmub_rb_cmd_fams2 fams2_config; + struct dmub_rb_cmd_ib ib_fams2_config; + struct dmub_rb_cmd_fams2_drr_update fams2_drr_update; struct dmub_rb_cmd_fams2_flip fams2_flip; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c index 731ca9b6a6cf..2575dbc448f7 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c @@ -66,24 +66,20 @@ void dmub_dcn401_reset(struct dmub_srv *dmub) const uint32_t timeout_us = 1 * 1000 * 1000; //1s const uint32_t poll_delay_us = 1; //1us uint32_t i = 0; - uint32_t in_reset, scratch, pwait_mode; + uint32_t enabled, in_reset, scratch, pwait_mode; - REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); + REG_GET(DMCUB_CNTL, + DMCUB_ENABLE, &enabled); + REG_GET(DMCUB_CNTL2, + DMCUB_SOFT_RESET, &in_reset); - if (in_reset == 0) { + if (enabled && in_reset == 0) { cmd.bits.status = 1; cmd.bits.command_code = DMUB_GPINT__STOP_FW; cmd.bits.param = 0; dmub->hw_funcs.set_gpint(dmub, cmd); - for (i = 0; i < timeout_us; i++) { - if (dmub->hw_funcs.is_gpint_acked(dmub, cmd)) - break; - - udelay(poll_delay_us); - } - for (; i < timeout_us; i++) { scratch = dmub->hw_funcs.get_gpint_response(dmub); if (scratch == DMUB_GPINT__STOP_FW_RESPONSE) diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index c917a70b3c19..acca7943a8c8 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -952,10 +952,8 @@ enum dmub_status dmub_srv_wait_for_pending(struct dmub_srv *dmub, !dmub->hw_funcs.get_inbox1_wptr) return DMUB_STATUS_INVALID; - /* take a snapshot of the required mailbox state */ - scratch_inbox1.rb.wrpt = dmub->hw_funcs.get_inbox1_wptr(dmub); - for (i = 0; i <= timeout_us; i += polling_interval_us) { + scratch_inbox1.rb.wrpt = dmub->hw_funcs.get_inbox1_wptr(dmub); scratch_inbox1.rb.rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); scratch_reg_inbox0.is_pending = scratch_reg_inbox0.is_pending && @@ -978,30 +976,6 @@ enum dmub_status dmub_srv_wait_for_pending(struct dmub_srv *dmub, return DMUB_STATUS_TIMEOUT; } -static enum dmub_status dmub_srv_update_inbox_status(struct dmub_srv *dmub) -{ - uint32_t rptr; - - /* update inbox1 state */ - rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); - - if (rptr > dmub->inbox1.rb.capacity) - return DMUB_STATUS_HW_FAILURE; - - if (dmub->inbox1.rb.rptr > rptr) { - /* rb wrapped */ - dmub->inbox1.num_reported += (rptr + dmub->inbox1.rb.capacity - dmub->inbox1.rb.rptr) / DMUB_RB_CMD_SIZE; - } else { - dmub->inbox1.num_reported += (rptr - dmub->inbox1.rb.rptr) / DMUB_RB_CMD_SIZE; - } - dmub->inbox1.rb.rptr = rptr; - - /* update reg_inbox0 */ - dmub_srv_update_reg_inbox0_status(dmub); - - return DMUB_STATUS_OK; -} - enum dmub_status dmub_srv_wait_for_idle(struct dmub_srv *dmub, uint32_t timeout_us) { @@ -1353,3 +1327,33 @@ enum dmub_status dmub_srv_wait_for_inbox_free(struct dmub_srv *dmub, return DMUB_STATUS_TIMEOUT; } + +enum dmub_status dmub_srv_update_inbox_status(struct dmub_srv *dmub) +{ + uint32_t rptr; + + if (!dmub->hw_init) + return DMUB_STATUS_INVALID; + + if (dmub->power_state != DMUB_POWER_STATE_D0) + return DMUB_STATUS_POWER_STATE_D3; + + /* update inbox1 state */ + rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); + + if (rptr > dmub->inbox1.rb.capacity) + return DMUB_STATUS_HW_FAILURE; + + if (dmub->inbox1.rb.rptr > rptr) { + /* rb wrapped */ + dmub->inbox1.num_reported += (rptr + dmub->inbox1.rb.capacity - dmub->inbox1.rb.rptr) / DMUB_RB_CMD_SIZE; + } else { + dmub->inbox1.num_reported += (rptr - dmub->inbox1.rb.rptr) / DMUB_RB_CMD_SIZE; + } + dmub->inbox1.rb.rptr = rptr; + + /* update reg_inbox0 */ + dmub_srv_update_reg_inbox0_status(dmub); + + return DMUB_STATUS_OK; +} diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h b/drivers/gpu/drm/amd/display/include/link_service_types.h index 1867aac57cf2..da74ed66c8f9 100644 --- a/drivers/gpu/drm/amd/display/include/link_service_types.h +++ b/drivers/gpu/drm/amd/display/include/link_service_types.h @@ -89,6 +89,8 @@ struct link_training_settings { bool enhanced_framing; enum lttpr_mode lttpr_mode; + bool lttpr_early_tps2; + /* disallow different lanes to have different lane settings */ bool disallow_per_lane_settings; /* dpcd lane settings will always use the same hw lane settings diff --git a/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_5_0_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_5_0_0_offset.h index 14574112c469..c4aaa86a95e2 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_5_0_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_5_0_0_offset.h @@ -1147,6 +1147,22 @@ #define regUVD_DPG_LMA_CTL2_BASE_IDX 1 +// addressBlock: uvd_mmsch_dec +// base address: 0x20d2c +#define regMMSCH_VF_VMID 0x054b +#define regMMSCH_VF_VMID_BASE_IDX 1 +#define regMMSCH_VF_CTX_ADDR_LO 0x054c +#define regMMSCH_VF_CTX_ADDR_LO_BASE_IDX 1 +#define regMMSCH_VF_CTX_ADDR_HI 0x054d +#define regMMSCH_VF_CTX_ADDR_HI_BASE_IDX 1 +#define regMMSCH_VF_CTX_SIZE 0x054e +#define regMMSCH_VF_CTX_SIZE_BASE_IDX 1 +#define regMMSCH_VF_MAILBOX_HOST 0x0552 +#define regMMSCH_VF_MAILBOX_HOST_BASE_IDX 1 +#define regMMSCH_VF_MAILBOX_RESP 0x0553 +#define regMMSCH_VF_MAILBOX_RESP_BASE_IDX 1 + + // addressBlock: uvd_vcn_umsch_dec // base address: 0x21500 #define regVCN_UMSCH_MES_CNTL 0x0740 diff --git a/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_5_0_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_5_0_0_sh_mask.h index 5c119a6b87fb..bd7242e4e9c6 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_5_0_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_5_0_0_sh_mask.h @@ -5929,6 +5929,29 @@ #define UVD_DPG_LMA_CTL2__JPEG_WRITE_PTR_MASK 0x0000FE00L +// addressBlock: uvd_mmsch_dec +//MMSCH_VF_VMID +#define MMSCH_VF_VMID__VF_CTX_VMID__SHIFT 0x0 +#define MMSCH_VF_VMID__VF_GPCOM_VMID__SHIFT 0x5 +#define MMSCH_VF_VMID__VF_CTX_VMID_MASK 0x0000001FL +#define MMSCH_VF_VMID__VF_GPCOM_VMID_MASK 0x000003E0L +//MMSCH_VF_CTX_ADDR_LO +#define MMSCH_VF_CTX_ADDR_LO__VF_CTX_ADDR_LO__SHIFT 0x6 +#define MMSCH_VF_CTX_ADDR_LO__VF_CTX_ADDR_LO_MASK 0xFFFFFFC0L +//MMSCH_VF_CTX_ADDR_HI +#define MMSCH_VF_CTX_ADDR_HI__VF_CTX_ADDR_HI__SHIFT 0x0 +#define MMSCH_VF_CTX_ADDR_HI__VF_CTX_ADDR_HI_MASK 0xFFFFFFFFL +//MMSCH_VF_CTX_SIZE +#define MMSCH_VF_CTX_SIZE__VF_CTX_SIZE__SHIFT 0x0 +#define MMSCH_VF_CTX_SIZE__VF_CTX_SIZE_MASK 0xFFFFFFFFL +//MMSCH_VF_MAILBOX_HOST +#define MMSCH_VF_MAILBOX_HOST__DATA__SHIFT 0x0 +#define MMSCH_VF_MAILBOX_HOST__DATA_MASK 0xFFFFFFFFL +//MMSCH_VF_MAILBOX_RESP +#define MMSCH_VF_MAILBOX_RESP__RESP__SHIFT 0x0 +#define MMSCH_VF_MAILBOX_RESP__RESP_MASK 0xFFFFFFFFL + + // addressBlock: uvd_vcn_umsch_dec //VCN_UMSCH_MES_CNTL #define VCN_UMSCH_MES_CNTL__PIPE_ID__SHIFT 0x0 diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h index 0160d65f3f5e..2d1135bdc4b9 100644 --- a/drivers/gpu/drm/amd/include/atomfirmware.h +++ b/drivers/gpu/drm/amd/include/atomfirmware.h @@ -183,6 +183,7 @@ enum atom_dgpu_vram_type { ATOM_DGPU_VRAM_TYPE_HBM2E = 0x61, ATOM_DGPU_VRAM_TYPE_GDDR6 = 0x70, ATOM_DGPU_VRAM_TYPE_HBM3 = 0x80, + ATOM_DGPU_VRAM_TYPE_HBM3E = 0x81, }; enum atom_dp_vs_preemph_def{ diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index f345c233bc47..f24a1d8c77db 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -3432,19 +3432,6 @@ bool smu_mode1_reset_is_support(struct smu_context *smu) return ret; } -bool smu_mode2_reset_is_support(struct smu_context *smu) -{ - bool ret = false; - - if (!smu->pm_enabled) - return false; - - if (smu->ppt_funcs && smu->ppt_funcs->mode2_reset_is_support) - ret = smu->ppt_funcs->mode2_reset_is_support(smu); - - return ret; -} - bool smu_link_reset_is_support(struct smu_context *smu) { bool ret = false; diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index a95a3dd5a895..d47e32ae4671 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -1233,11 +1233,6 @@ struct pptable_funcs { bool (*mode1_reset_is_support)(struct smu_context *smu); /** - * @mode2_reset_is_support: Check if GPU supports mode2 reset. - */ - bool (*mode2_reset_is_support)(struct smu_context *smu); - - /** * @link_reset_is_support: Check if GPU supports link reset. */ bool (*link_reset_is_support)(struct smu_context *smu); @@ -1621,7 +1616,6 @@ int smu_get_power_limit(void *handle, enum pp_power_type pp_power_type); bool smu_mode1_reset_is_support(struct smu_context *smu); -bool smu_mode2_reset_is_support(struct smu_context *smu); bool smu_link_reset_is_support(struct smu_context *smu); int smu_mode1_reset(struct smu_context *smu); int smu_link_reset(struct smu_context *smu); diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h index c22ed28c0cdb..4263798d716b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h @@ -163,8 +163,6 @@ int smu_v13_0_notify_memory_pool_location(struct smu_context *smu); int smu_v13_0_system_features_control(struct smu_context *smu, bool en); -int smu_v13_0_init_display_count(struct smu_context *smu, uint32_t count); - int smu_v13_0_set_allowed_mask(struct smu_context *smu); int smu_v13_0_notify_display_change(struct smu_context *smu); @@ -300,14 +298,5 @@ int smu_v13_0_get_boot_freq_by_index(struct smu_context *smu, void smu_v13_0_interrupt_work(struct smu_context *smu); void smu_v13_0_reset_custom_level(struct smu_context *smu); -bool smu_v13_0_12_is_dpm_running(struct smu_context *smu); -int smu_v13_0_12_get_max_metrics_size(void); -int smu_v13_0_12_setup_driver_pptable(struct smu_context *smu); -int smu_v13_0_12_get_smu_metrics_data(struct smu_context *smu, - MetricsMember_t member, - uint32_t *value); -ssize_t smu_v13_0_12_get_gpu_metrics(struct smu_context *smu, void **table); -extern const struct cmn2asic_mapping smu_v13_0_12_feature_mask_map[]; -extern const struct cmn2asic_msg_mapping smu_v13_0_12_message_map[]; #endif #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 19a25fdc2f5b..115e3fa456bc 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -3089,11 +3089,6 @@ static int sienna_cichlid_stb_get_data_direct(struct smu_context *smu, return 0; } -static bool sienna_cichlid_is_mode2_reset_supported(struct smu_context *smu) -{ - return true; -} - static int sienna_cichlid_mode2_reset(struct smu_context *smu) { int ret = 0, index; @@ -3229,7 +3224,6 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = { .get_default_config_table_settings = sienna_cichlid_get_default_config_table_settings, .set_config_table = sienna_cichlid_set_config_table, .get_unique_id = sienna_cichlid_get_unique_id, - .mode2_reset_is_support = sienna_cichlid_is_mode2_reset_supported, .mode2_reset = sienna_cichlid_mode2_reset, }; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index 5cb3b9bb6089..6de653d2ed62 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -1985,11 +1985,6 @@ static bool aldebaran_is_mode1_reset_supported(struct smu_context *smu) return true; } -static bool aldebaran_is_mode2_reset_supported(struct smu_context *smu) -{ - return true; -} - static int aldebaran_set_mp1_state(struct smu_context *smu, enum pp_mp1_state mp1_state) { @@ -2095,7 +2090,6 @@ static const struct pptable_funcs aldebaran_ppt_funcs = { .set_pp_feature_mask = smu_cmn_set_pp_feature_mask, .get_gpu_metrics = aldebaran_get_gpu_metrics, .mode1_reset_is_support = aldebaran_is_mode1_reset_supported, - .mode2_reset_is_support = aldebaran_is_mode2_reset_supported, .smu_handle_passthrough_sbr = aldebaran_smu_handle_passthrough_sbr, .mode1_reset = aldebaran_mode1_reset, .set_mp1_state = aldebaran_set_mp1_state, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index 45b5ab423844..a7167668d189 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -749,18 +749,6 @@ int smu_v13_0_set_tool_table_location(struct smu_context *smu) return ret; } -int smu_v13_0_init_display_count(struct smu_context *smu, uint32_t count) -{ - int ret = 0; - - if (!smu->pm_enabled) - return ret; - - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays, count, NULL); - - return ret; -} - int smu_v13_0_set_allowed_mask(struct smu_context *smu) { struct smu_feature *feature = &smu->smu_feature; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index b6e5da7b06ef..7d4ff09be7e8 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -2919,11 +2919,6 @@ static bool smu_v13_0_6_is_mode1_reset_supported(struct smu_context *smu) return true; } -static bool smu_v13_0_6_is_mode2_reset_supported(struct smu_context *smu) -{ - return true; -} - static inline bool smu_v13_0_6_is_link_reset_supported(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; @@ -3680,7 +3675,6 @@ static const struct pptable_funcs smu_v13_0_6_ppt_funcs = { .get_pm_metrics = smu_v13_0_6_get_pm_metrics, .get_thermal_temperature_range = smu_v13_0_6_get_thermal_temperature_range, .mode1_reset_is_support = smu_v13_0_6_is_mode1_reset_supported, - .mode2_reset_is_support = smu_v13_0_6_is_mode2_reset_supported, .link_reset_is_support = smu_v13_0_6_is_link_reset_supported, .mode1_reset = smu_v13_0_6_mode1_reset, .mode2_reset = smu_v13_0_6_mode2_reset, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h index 5313206ae4bb..d151bcd0cca7 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h @@ -74,4 +74,12 @@ extern void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu); bool smu_v13_0_6_cap_supported(struct smu_context *smu, enum smu_v13_0_6_caps cap); int smu_v13_0_6_get_static_metrics_table(struct smu_context *smu); +bool smu_v13_0_12_is_dpm_running(struct smu_context *smu); +int smu_v13_0_12_get_max_metrics_size(void); +int smu_v13_0_12_setup_driver_pptable(struct smu_context *smu); +int smu_v13_0_12_get_smu_metrics_data(struct smu_context *smu, + MetricsMember_t member, uint32_t *value); +ssize_t smu_v13_0_12_get_gpu_metrics(struct smu_context *smu, void **table); +extern const struct cmn2asic_mapping smu_v13_0_12_feature_mask_map[]; +extern const struct cmn2asic_msg_mapping smu_v13_0_12_message_map[]; #endif 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/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 56c7e3318f01..f2a6559a2710 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -2137,14 +2137,17 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, for (i = 0; i < num; i++) { msg.address = msgs[i].addr; - drm_dp_i2c_msg_set_request(&msg, &msgs[i]); - /* Send a bare address packet to start the transaction. - * Zero sized messages specify an address only (bare - * address) transaction. - */ - msg.buffer = NULL; - msg.size = 0; - err = drm_dp_i2c_do_msg(aux, &msg); + + if (!aux->no_zero_sized) { + drm_dp_i2c_msg_set_request(&msg, &msgs[i]); + /* Send a bare address packet to start the transaction. + * Zero sized messages specify an address only (bare + * address) transaction. + */ + msg.buffer = NULL; + msg.size = 0; + err = drm_dp_i2c_do_msg(aux, &msg); + } /* * Reset msg.request in case in case it got @@ -2163,6 +2166,8 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, msg.buffer = msgs[i].buf + j; msg.size = min(transfer_size, msgs[i].len - j); + if (j + msg.size == msgs[i].len && aux->no_zero_sized) + msg.request &= ~DP_AUX_I2C_MOT; err = drm_dp_i2c_drain_msg(aux, &msg); /* @@ -2180,15 +2185,17 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, } if (err >= 0) err = num; - /* Send a bare address packet to close out the transaction. - * Zero sized messages specify an address only (bare - * address) transaction. - */ - msg.request &= ~DP_AUX_I2C_MOT; - msg.buffer = NULL; - msg.size = 0; - (void)drm_dp_i2c_do_msg(aux, &msg); + if (!aux->no_zero_sized) { + /* Send a bare address packet to close out the transaction. + * Zero sized messages specify an address only (bare + * address) transaction. + */ + msg.request &= ~DP_AUX_I2C_MOT; + msg.buffer = NULL; + msg.size = 0; + (void)drm_dp_i2c_do_msg(aux, &msg); + } return err; } diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 3dc7acd56b1d..4589ab4bb1ec 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -830,36 +830,62 @@ void *__devm_drm_dev_alloc(struct device *parent, EXPORT_SYMBOL(__devm_drm_dev_alloc); /** - * drm_dev_alloc - Allocate new DRM device - * @driver: DRM driver to allocate device for + * __drm_dev_alloc - Allocation of a &drm_device instance * @parent: Parent device object + * @driver: DRM driver + * @size: the size of the struct which contains struct drm_device + * @offset: the offset of the &drm_device within the container. * - * This is the deprecated version of devm_drm_dev_alloc(), which does not support - * subclassing through embedding the struct &drm_device in a driver private - * structure, and which does not support automatic cleanup through devres. + * This should *NOT* be by any drivers, but is a dedicated interface for the + * corresponding Rust abstraction. * - * RETURNS: - * Pointer to new DRM device, or ERR_PTR on failure. + * This is the same as devm_drm_dev_alloc(), but without the corresponding + * resource management through the parent device, but not the same as + * drm_dev_alloc(), since the latter is the deprecated version, which does not + * support subclassing. + * + * Returns: A pointer to new DRM device, or an ERR_PTR on failure. */ -struct drm_device *drm_dev_alloc(const struct drm_driver *driver, - struct device *parent) +void *__drm_dev_alloc(struct device *parent, + const struct drm_driver *driver, + size_t size, size_t offset) { - struct drm_device *dev; + void *container; + struct drm_device *drm; int ret; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) + container = kzalloc(size, GFP_KERNEL); + if (!container) return ERR_PTR(-ENOMEM); - ret = drm_dev_init(dev, driver, parent); + drm = container + offset; + ret = drm_dev_init(drm, driver, parent); if (ret) { - kfree(dev); + kfree(container); return ERR_PTR(ret); } + drmm_add_final_kfree(drm, container); - drmm_add_final_kfree(dev, dev); + return container; +} +EXPORT_SYMBOL(__drm_dev_alloc); - return dev; +/** + * drm_dev_alloc - Allocate new DRM device + * @driver: DRM driver to allocate device for + * @parent: Parent device object + * + * This is the deprecated version of devm_drm_dev_alloc(), which does not support + * subclassing through embedding the struct &drm_device in a driver private + * structure, and which does not support automatic cleanup through devres. + * + * RETURNS: + * Pointer to new DRM device, or ERR_PTR on failure. + */ +struct drm_device *drm_dev_alloc(const struct drm_driver *driver, + struct device *parent) +{ + return __drm_dev_alloc(parent, driver, sizeof(struct drm_device), 0); } EXPORT_SYMBOL(drm_dev_alloc); diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 8642a2fb25a9..b4239fd04e9d 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -383,6 +383,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) prop = drm_property_create(dev, DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, + "IN_FORMATS_ASYNC", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.async_modifiers_property = prop; + + prop = drm_property_create(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, "SIZE_HINTS", 0); if (!prop) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index a28b22fdd7a4..04992dfd4c79 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -141,6 +141,14 @@ * various bugs in this area with inconsistencies between the capability * flag and per-plane properties. * + * IN_FORMATS_ASYNC: + * Blob property which contains the set of buffer format and modifier + * pairs supported by this plane for asynchronous flips. The blob is a struct + * drm_format_modifier_blob. Userspace cannot change this property. This is an + * optional property and if not present then user should expect a failure in + * atomic ioctl when the modifier/format is not supported by that plane under + * asynchronous flip. + * * SIZE_HINTS: * Blob property which contains the set of recommended plane size * which can used for simple "cursor like" use cases (eg. no scaling). @@ -185,9 +193,13 @@ modifiers_ptr(struct drm_format_modifier_blob *blob) return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); } -static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane) +static struct drm_property_blob *create_in_format_blob(struct drm_device *dev, + struct drm_plane *plane, + bool (*format_mod_supported) + (struct drm_plane *plane, + u32 format, + u64 modifier)) { - const struct drm_mode_config *config = &dev->mode_config; struct drm_property_blob *blob; struct drm_format_modifier *mod; size_t blob_size, formats_size, modifiers_size; @@ -213,7 +225,7 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane blob = drm_property_create_blob(dev, blob_size, NULL); if (IS_ERR(blob)) - return -1; + return NULL; blob_data = blob->data; blob_data->version = FORMAT_BLOB_CURRENT; @@ -229,10 +241,10 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane mod = modifiers_ptr(blob_data); for (i = 0; i < plane->modifier_count; i++) { for (j = 0; j < plane->format_count; j++) { - if (!plane->funcs->format_mod_supported || - plane->funcs->format_mod_supported(plane, - plane->format_types[j], - plane->modifiers[i])) { + if (!format_mod_supported || + format_mod_supported(plane, + plane->format_types[j], + plane->modifiers[i])) { mod->formats |= 1ULL << j; } } @@ -243,10 +255,7 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane mod++; } - drm_object_attach_property(&plane->base, config->modifiers_property, - blob->base.id); - - return 0; + return blob; } /** @@ -358,6 +367,7 @@ static int __drm_universal_plane_init(struct drm_device *dev, const char *name, va_list ap) { struct drm_mode_config *config = &dev->mode_config; + struct drm_property_blob *blob; static const uint64_t default_modifiers[] = { DRM_FORMAT_MOD_LINEAR, }; @@ -469,8 +479,24 @@ static int __drm_universal_plane_init(struct drm_device *dev, drm_plane_create_hotspot_properties(plane); } - if (format_modifier_count) - create_in_format_blob(dev, plane); + if (format_modifier_count) { + blob = create_in_format_blob(dev, plane, + plane->funcs->format_mod_supported); + if (!IS_ERR(blob)) + drm_object_attach_property(&plane->base, + config->modifiers_property, + blob->base.id); + } + + if (plane->funcs->format_mod_supported_async) { + blob = create_in_format_blob(dev, plane, + plane->funcs->format_mod_supported_async); + if (!IS_ERR(blob)) + drm_object_attach_property(&plane->base, + config->async_modifiers_property, + blob->base.id); + } + return 0; } diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 83778a6ff007..a2a6d52be0a5 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -821,7 +821,7 @@ unsigned int vlv_plane_min_alignment(struct intel_plane *plane, { struct intel_display *display = to_intel_display(plane); - if (intel_plane_can_async_flip(plane, fb->modifier)) + if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier)) return 256 * 1024; /* FIXME undocumented so not sure what's actually needed */ @@ -845,7 +845,7 @@ static unsigned int g4x_primary_min_alignment(struct intel_plane *plane, { struct intel_display *display = to_intel_display(plane); - if (intel_plane_can_async_flip(plane, fb->modifier)) + if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier)) return 256 * 1024; if (intel_scanout_needs_vtd_wa(display)) @@ -890,6 +890,7 @@ static const struct drm_plane_funcs i965_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = i965_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; static const struct drm_plane_funcs i8xx_plane_funcs = { @@ -899,6 +900,7 @@ static const struct drm_plane_funcs i8xx_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = i8xx_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; struct intel_plane * diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c index 1bf08b80c23f..c176bdbc19a3 100644 --- a/drivers/gpu/drm/i915/display/intel_alpm.c +++ b/drivers/gpu/drm/i915/display/intel_alpm.c @@ -426,8 +426,8 @@ void intel_alpm_pre_plane_update(struct intel_atomic_state *state, } } -static void intel_alpm_enable_sink(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) +void intel_alpm_enable_sink(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { u8 val; @@ -453,8 +453,8 @@ void intel_alpm_post_plane_update(struct intel_atomic_state *state, intel_atomic_get_old_crtc_state(state, crtc); struct intel_encoder *encoder; - if ((!crtc_state->has_lobf || - crtc_state->has_lobf == old_crtc_state->has_lobf) && !crtc_state->has_psr) + if (crtc_state->has_psr || !crtc_state->has_lobf || + crtc_state->has_lobf == old_crtc_state->has_lobf) return; for_each_intel_encoder_mask(display->drm, encoder, diff --git a/drivers/gpu/drm/i915/display/intel_alpm.h b/drivers/gpu/drm/i915/display/intel_alpm.h index d7126d65b60f..c9fe21e3e72c 100644 --- a/drivers/gpu/drm/i915/display/intel_alpm.h +++ b/drivers/gpu/drm/i915/display/intel_alpm.h @@ -23,6 +23,8 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp, struct drm_connector_state *conn_state); void intel_alpm_configure(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); +void intel_alpm_enable_sink(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); void intel_alpm_pre_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc); void intel_alpm_post_plane_update(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 7276179df878..1bcfa5f4fd63 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -174,11 +174,27 @@ bool intel_plane_needs_physical(struct intel_plane *plane) DISPLAY_INFO(display)->cursor_needs_physical; } -bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier) +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format, + u64 modifier) { + if (intel_format_info_is_yuv_semiplanar(drm_format_info(format), modifier) || + format == DRM_FORMAT_C8) + return false; + return plane->can_async_flip && plane->can_async_flip(modifier); } +bool intel_plane_format_mod_supported_async(struct drm_plane *plane, + u32 format, + u64 modifier) +{ + if (!plane->funcs->format_mod_supported(plane, format, modifier)) + return false; + + return intel_plane_can_async_flip(to_intel_plane(plane), + format, modifier); +} + unsigned int intel_adjusted_rate(const struct drm_rect *src, const struct drm_rect *dst, unsigned int rate) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 6efac923dcbc..317320c32285 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -21,7 +21,8 @@ enum plane_id; struct intel_plane * intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id); -bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier); +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format, + u64 modifier); unsigned int intel_adjusted_rate(const struct drm_rect *src, const struct drm_rect *dst, unsigned int rate); @@ -89,5 +90,8 @@ int intel_atomic_add_affected_planes(struct intel_atomic_state *state, int intel_atomic_check_planes(struct intel_atomic_state *state); u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state); +bool intel_plane_format_mod_supported_async(struct drm_plane *plane, + u32 format, + u64 modifier); #endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 40d8bbd8107d..55af3a553c58 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -397,6 +397,19 @@ hsw_audio_config_update(struct intel_encoder *encoder, hsw_hdmi_audio_config_update(encoder, crtc_state); } +static void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state, + bool enable) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder trans = crtc_state->cpu_transcoder; + + if (!HAS_DP20(display)) + return; + + intel_de_rmw(display, AUD_DP_2DOT0_CTRL(trans), AUD_ENABLE_SDP_SPLIT, + enable && crtc_state->sdp_split_enable ? AUD_ENABLE_SDP_SPLIT : 0); +} + static void hsw_audio_codec_disable(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) @@ -430,6 +443,8 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder, if (needs_wa_14020863754(display)) intel_de_rmw(display, AUD_CHICKENBIT_REG3, DACBE_DISABLE_MIN_HBLANK_FIX, 0); + intel_audio_sdp_split_update(old_crtc_state, false); + mutex_unlock(&display->audio.mutex); } @@ -555,6 +570,8 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP)) enable_audio_dsc_wa(encoder, crtc_state); + intel_audio_sdp_split_update(crtc_state, true); + if (needs_wa_14020863754(display)) intel_de_rmw(display, AUD_CHICKENBIT_REG3, 0, DACBE_DISABLE_MIN_HBLANK_FIX); @@ -681,16 +698,6 @@ static void ibx_audio_codec_enable(struct intel_encoder *encoder, mutex_unlock(&display->audio.mutex); } -void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state) -{ - struct intel_display *display = to_intel_display(crtc_state); - enum transcoder trans = crtc_state->cpu_transcoder; - - if (HAS_DP20(display)) - intel_de_rmw(display, AUD_DP_2DOT0_CTRL(trans), AUD_ENABLE_SDP_SPLIT, - crtc_state->sdp_split_enable ? AUD_ENABLE_SDP_SPLIT : 0); -} - bool intel_audio_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) diff --git a/drivers/gpu/drm/i915/display/intel_audio.h b/drivers/gpu/drm/i915/display/intel_audio.h index ad49eefa7182..42cf886f3d24 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.h +++ b/drivers/gpu/drm/i915/display/intel_audio.h @@ -31,6 +31,5 @@ int intel_audio_min_cdclk(const struct intel_crtc_state *crtc_state); void intel_audio_init(struct intel_display *display); void intel_audio_register(struct intel_display *display); void intel_audio_deinit(struct intel_display *display); -void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state); #endif /* __INTEL_AUDIO_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index b09f724c3046..a82b93cbc81d 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -2763,9 +2763,9 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder, val |= XELPDP_FORWARD_CLOCK_UNGATE; if (!is_dp && is_hdmi_frl(port_clock)) - val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_DIV18CLK); + val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_DIV18CLK); else - val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_MAXPCLK); + val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_MAXPCLK); /* TODO: HDMI FRL */ /* DP2.0 10G and 20G rates enable MPLLA*/ @@ -2776,7 +2776,7 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder, intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE | - XELPDP_DDI_CLOCK_SELECT_MASK | XELPDP_SSC_ENABLE_PLLA | + XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_SSC_ENABLE_PLLA | XELPDP_SSC_ENABLE_PLLB, val); } @@ -3099,10 +3099,7 @@ int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder) val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)); - if (DISPLAY_VER(display) >= 30) - clock = REG_FIELD_GET(XE3_DDI_CLOCK_SELECT_MASK, val); - else - clock = REG_FIELD_GET(XELPDP_DDI_CLOCK_SELECT_MASK, val); + clock = XELPDP_DDI_CLOCK_SELECT_GET(display, val); drm_WARN_ON(display->drm, !(val & XELPDP_FORWARD_CLOCK_UNGATE)); drm_WARN_ON(display->drm, !(val & XELPDP_TBT_CLOCK_REQUEST)); @@ -3170,13 +3167,9 @@ static void intel_mtl_tbt_pll_enable(struct intel_encoder *encoder, * clock muxes, gating and SSC */ - if (DISPLAY_VER(display) >= 30) { - mask = XE3_DDI_CLOCK_SELECT_MASK; - val |= XE3_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(display, crtc_state->port_clock)); - } else { - mask = XELPDP_DDI_CLOCK_SELECT_MASK; - val |= XELPDP_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(display, crtc_state->port_clock)); - } + mask = XELPDP_DDI_CLOCK_SELECT_MASK(display); + val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, + intel_mtl_tbt_clock_select(display, crtc_state->port_clock)); mask |= XELPDP_FORWARD_CLOCK_UNGATE; val |= XELPDP_FORWARD_CLOCK_UNGATE; @@ -3289,7 +3282,7 @@ static void intel_cx0pll_disable(struct intel_encoder *encoder) /* 7. Program PORT_CLOCK_CTL register to disable and gate clocks. */ intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), - XELPDP_DDI_CLOCK_SELECT_MASK, 0); + XELPDP_DDI_CLOCK_SELECT_MASK(display), 0); intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), XELPDP_FORWARD_CLOCK_UNGATE, 0); @@ -3338,7 +3331,7 @@ static void intel_mtl_tbt_pll_disable(struct intel_encoder *encoder) * 5. Program PORT CLOCK CTRL register to disable and gate clocks */ intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), - XELPDP_DDI_CLOCK_SELECT_MASK | + XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_FORWARD_CLOCK_UNGATE, 0); /* 6. Program DDI_CLK_VALFREQ to 0. */ @@ -3367,7 +3360,7 @@ intel_mtl_port_pll_type(struct intel_encoder *encoder, * handling is done via the standard shared DPLL framework. */ val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)); - clock = REG_FIELD_GET(XELPDP_DDI_CLOCK_SELECT_MASK, val); + clock = XELPDP_DDI_CLOCK_SELECT_GET(display, val); if (clock == XELPDP_DDI_CLOCK_SELECT_MAXPCLK || clock == XELPDP_DDI_CLOCK_SELECT_DIV18CLK) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h index 960f7f778fb8..59c22beaf1de 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h @@ -192,10 +192,17 @@ #define XELPDP_TBT_CLOCK_REQUEST REG_BIT(19) #define XELPDP_TBT_CLOCK_ACK REG_BIT(18) -#define XELPDP_DDI_CLOCK_SELECT_MASK REG_GENMASK(15, 12) -#define XE3_DDI_CLOCK_SELECT_MASK REG_GENMASK(16, 12) -#define XELPDP_DDI_CLOCK_SELECT(val) REG_FIELD_PREP(XELPDP_DDI_CLOCK_SELECT_MASK, val) -#define XE3_DDI_CLOCK_SELECT(val) REG_FIELD_PREP(XE3_DDI_CLOCK_SELECT_MASK, val) +#define _XELPDP_DDI_CLOCK_SELECT_MASK REG_GENMASK(15, 12) +#define _XE3_DDI_CLOCK_SELECT_MASK REG_GENMASK(16, 12) +#define XELPDP_DDI_CLOCK_SELECT_MASK(display) (DISPLAY_VER(display) >= 30 ? \ + _XE3_DDI_CLOCK_SELECT_MASK : _XELPDP_DDI_CLOCK_SELECT_MASK) +#define XELPDP_DDI_CLOCK_SELECT_PREP(display, val) (DISPLAY_VER(display) >= 30 ? \ + REG_FIELD_PREP(_XE3_DDI_CLOCK_SELECT_MASK, (val)) : \ + REG_FIELD_PREP(_XELPDP_DDI_CLOCK_SELECT_MASK, (val))) +#define XELPDP_DDI_CLOCK_SELECT_GET(display, val) (DISPLAY_VER(display) >= 30 ? \ + REG_FIELD_GET(_XE3_DDI_CLOCK_SELECT_MASK, (val)) : \ + REG_FIELD_GET(_XELPDP_DDI_CLOCK_SELECT_MASK, (val))) + #define XELPDP_DDI_CLOCK_SELECT_NONE 0x0 #define XELPDP_DDI_CLOCK_SELECT_MAXPCLK 0x8 #define XELPDP_DDI_CLOCK_SELECT_DIV18CLK 0x9 diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 74132c1d6385..d58f8fc37326 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3507,9 +3507,6 @@ static void intel_ddi_enable(struct intel_atomic_state *state, intel_vrr_transcoder_enable(crtc_state); - /* Enable/Disable DP2.0 SDP split config before transcoder */ - intel_audio_sdp_split_update(crtc_state); - /* 128b/132b SST */ if (!is_hdmi && intel_dp_is_uhbr(crtc_state)) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 287110e4e435..6f0a0bc71b06 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6030,22 +6030,16 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (!plane->async_flip) continue; - if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->modifier)) { + if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->format->format, + new_plane_state->hw.fb->modifier)) { drm_dbg_kms(display->drm, - "[PLANE:%d:%s] Modifier 0x%llx does not support async flip\n", + "[PLANE:%d:%s] pixel format %p4cc / modifier 0x%llx does not support async flip\n", plane->base.base.id, plane->base.name, + &new_plane_state->hw.fb->format->format, new_plane_state->hw.fb->modifier); return -EINVAL; } - if (intel_format_info_is_yuv_semiplanar(new_plane_state->hw.fb->format, - new_plane_state->hw.fb->modifier)) { - drm_dbg_kms(display->drm, - "[PLANE:%d:%s] Planar formats do not support async flips\n", - plane->base.base.id, plane->base.name); - return -EINVAL; - } - /* * We turn the first async flip request into a sync flip * so that we can reconfigure the plane (eg. change modifier). diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 5c74ab5fd1aa..411fe7b918a7 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -244,31 +244,45 @@ int intel_display_driver_probe_noirq(struct intel_display *display) intel_dmc_init(display); display->wq.modeset = alloc_ordered_workqueue("i915_modeset", 0); + if (!display->wq.modeset) { + ret = -ENOMEM; + goto cleanup_vga_client_pw_domain_dmc; + } + display->wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI | WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE); + if (!display->wq.flip) { + ret = -ENOMEM; + goto cleanup_wq_modeset; + } + display->wq.cleanup = alloc_workqueue("i915_cleanup", WQ_HIGHPRI, 0); + if (!display->wq.cleanup) { + ret = -ENOMEM; + goto cleanup_wq_flip; + } intel_mode_config_init(display); ret = intel_cdclk_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup; ret = intel_color_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup; ret = intel_dbuf_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup; ret = intel_bw_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup; ret = intel_pmdemand_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup; intel_init_quirks(display); @@ -276,6 +290,12 @@ int intel_display_driver_probe_noirq(struct intel_display *display) return 0; +cleanup_wq_cleanup: + destroy_workqueue(display->wq.cleanup); +cleanup_wq_flip: + destroy_workqueue(display->wq.flip); +cleanup_wq_modeset: + destroy_workqueue(display->wq.modeset); cleanup_vga_client_pw_domain_dmc: intel_dmc_fini(display); intel_power_domains_driver_remove(display); diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 593b29b56714..640c43bf62d4 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2524,6 +2524,7 @@ intel_dp_dsc_compute_pipe_bpp_limits(struct intel_dp *intel_dp, bool intel_dp_compute_config_limits(struct intel_dp *intel_dp, + struct intel_connector *connector, struct intel_crtc_state *crtc_state, bool respect_downstream_limits, bool dsc, @@ -2577,7 +2578,7 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp, intel_dp_test_compute_config(intel_dp, crtc_state, limits); return intel_dp_compute_config_link_bpp_limits(intel_dp, - intel_dp->attached_connector, + connector, crtc_state, dsc, limits); @@ -2638,7 +2639,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes); dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || - !intel_dp_compute_config_limits(intel_dp, pipe_config, + !intel_dp_compute_config_limits(intel_dp, connector, pipe_config, respect_downstream_limits, false, &limits); @@ -2672,7 +2673,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, str_yes_no(ret), str_yes_no(joiner_needs_dsc), str_yes_no(intel_dp->force_dsc_en)); - if (!intel_dp_compute_config_limits(intel_dp, pipe_config, + if (!intel_dp_compute_config_limits(intel_dp, connector, pipe_config, respect_downstream_limits, true, &limits)) @@ -4531,6 +4532,23 @@ intel_dp_mst_disconnect(struct intel_dp *intel_dp) static bool intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi) { + struct intel_display *display = to_intel_display(intel_dp); + + /* + * Display WA for HSD #13013007775: mtl/arl/lnl + * Read the sink count and link service IRQ registers in separate + * transactions to prevent disconnecting the sink on a TBT link + * inadvertently. + */ + if (IS_DISPLAY_VER(display, 14, 20) && !display->platform.battlemage) { + if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 3) != 3) + return false; + + /* DP_SINK_COUNT_ESI + 3 == DP_LINK_SERVICE_IRQ_VECTOR_ESI0 */ + return drm_dp_dpcd_readb(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, + &esi[3]) == 1; + } + return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4; } diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index a7cc10800e0b..742ae26ac4a9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -194,6 +194,7 @@ void intel_dp_wait_source_oui(struct intel_dp *intel_dp); int intel_dp_output_bpp(enum intel_output_format output_format, int bpp); bool intel_dp_compute_config_limits(struct intel_dp *intel_dp, + struct intel_connector *connector, struct intel_crtc_state *crtc_state, bool respect_downstream_limits, bool dsc, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index aeda59f5fa7a..7335af92cfb0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -599,12 +599,13 @@ adjust_limits_for_dsc_hblank_expansion_quirk(struct intel_dp *intel_dp, static bool mst_stream_compute_config_limits(struct intel_dp *intel_dp, - const struct intel_connector *connector, + struct intel_connector *connector, struct intel_crtc_state *crtc_state, bool dsc, struct link_config_limits *limits) { - if (!intel_dp_compute_config_limits(intel_dp, crtc_state, false, dsc, + if (!intel_dp_compute_config_limits(intel_dp, connector, + crtc_state, false, dsc, limits)) return false; @@ -1327,8 +1328,6 @@ static void mst_stream_enable(struct intel_atomic_state *state, FECSTALL_DIS_DPTSTREAM_DPTTG, pipe_config->fec_enable ? FECSTALL_DIS_DPTSTREAM_DPTTG : 0); - intel_audio_sdp_split_update(pipe_config); - intel_enable_transcoder(pipe_config); for_each_pipe_crtc_modeset_enable(display, pipe_crtc, pipe_config, i) { diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index ccd66bbc72f7..430ad4ef7146 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -800,6 +800,8 @@ static void _psr_enable_sink(struct intel_dp *intel_dp, static void intel_psr_enable_sink(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + intel_alpm_enable_sink(intel_dp, crtc_state); + crtc_state->has_panel_replay ? _panel_replay_enable_sink(intel_dp, crtc_state) : _psr_enable_sink(intel_dp, crtc_state); @@ -1962,6 +1964,8 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) && !intel_dp->psr.panel_replay_enabled) intel_dmc_block_pkgc(display, intel_dp->psr.pipe, true); + + intel_alpm_configure(intel_dp, crtc_state); } static bool psr_interrupt_error_check(struct intel_dp *intel_dp) @@ -2029,8 +2033,9 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp, intel_dp->psr.sel_update_enabled ? "2" : "1"); /* - * Enabling here only for PSR. Panel Replay enable bit is already - * written at this point. See + * Enabling sink PSR/Panel Replay here only for PSR. Panel Replay enable + * bit is already written at this point. Sink ALPM is enabled here for + * PSR and Panel Replay. See * intel_psr_panel_replay_enable_sink. Modifiers/options: * - Selective Update * - Region Early Transport @@ -2172,6 +2177,9 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) if (intel_dp_is_edp(intel_dp)) intel_snps_phy_update_psr_power_state(&dp_to_dig_port(intel_dp)->base, false); + if (intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) + intel_alpm_disable(intel_dp); + /* Disable PSR on Sink */ if (!intel_dp->psr.panel_replay_enabled) { drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0); @@ -3498,7 +3506,6 @@ static void psr_alpm_check(struct intel_dp *intel_dp) if (intel_alpm_get_error(intel_dp)) { intel_psr_disable_locked(intel_dp); psr->sink_not_reliable = true; - intel_alpm_disable(intel_dp); } } diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 844519286b1c..c7b336359a5e 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -601,7 +601,7 @@ static u32 tgl_plane_min_alignment(struct intel_plane *plane, * Figure out what's going on here... */ if (display->platform.alderlake_p && - intel_plane_can_async_flip(plane, fb->modifier)) + intel_plane_can_async_flip(plane, fb->format->format, fb->modifier)) return mult * 16 * 1024; switch (fb->modifier) { @@ -2666,6 +2666,7 @@ static const struct drm_plane_funcs skl_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = skl_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; static const struct drm_plane_funcs icl_plane_funcs = { @@ -2675,6 +2676,7 @@ static const struct drm_plane_funcs icl_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = icl_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; static const struct drm_plane_funcs tgl_plane_funcs = { @@ -2684,6 +2686,7 @@ static const struct drm_plane_funcs tgl_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = tgl_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; static void diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile index 32a2ed6c0cfe..43afd0a26d14 100644 --- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile @@ -21,10 +21,8 @@ mediatek-drm-y := mtk_crtc.o \ obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o -mediatek-drm-hdmi-objs := mtk_cec.o \ - mtk_hdmi.o \ - mtk_hdmi_ddc.o - -obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o +obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mtk_cec.o +obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mtk_hdmi.o +obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mtk_hdmi_ddc.o obj-$(CONFIG_DRM_MEDIATEK_DP) += mtk_dp.o diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c index b42c0d87eba3..c7be530ca041 100644 --- a/drivers/gpu/drm/mediatek/mtk_cec.c +++ b/drivers/gpu/drm/mediatek/mtk_cec.c @@ -12,7 +12,6 @@ #include <linux/platform_device.h> #include "mtk_cec.h" -#include "mtk_hdmi.h" #include "mtk_drm_drv.h" #define TR_CONFIG 0x00 @@ -102,6 +101,7 @@ void mtk_cec_set_hpd_event(struct device *dev, cec->hpd_event = hpd_event; spin_unlock_irqrestore(&cec->lock, flags); } +EXPORT_SYMBOL_NS_GPL(mtk_cec_set_hpd_event, "DRM_MTK_HDMI_V1"); bool mtk_cec_hpd_high(struct device *dev) { @@ -112,6 +112,7 @@ bool mtk_cec_hpd_high(struct device *dev) return (status & (HDMI_PORD | HDMI_HTPLG)) == (HDMI_PORD | HDMI_HTPLG); } +EXPORT_SYMBOL_NS_GPL(mtk_cec_hpd_high, "DRM_MTK_HDMI_V1"); static void mtk_cec_htplg_irq_init(struct mtk_cec *cec) { @@ -247,3 +248,7 @@ struct platform_driver mtk_cec_driver = { .of_match_table = mtk_cec_of_ids, }, }; +module_platform_driver(mtk_cec_driver); + +MODULE_DESCRIPTION("MediaTek HDMI CEC Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c index fa0e95dd29a0..fe97bb97e004 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c @@ -492,11 +492,6 @@ static const struct of_device_id mtk_ovl_adaptor_comp_dt_ids[] = { { /* sentinel */ } }; -static int compare_of(struct device *dev, void *data) -{ - return dev->of_node == data; -} - static int ovl_adaptor_of_get_ddp_comp_type(struct device_node *node, enum mtk_ovl_adaptor_comp_type *ctype) { @@ -567,7 +562,7 @@ static int ovl_adaptor_comp_init(struct device *dev, struct component_match **ma priv->ovl_adaptor_comp[id] = &comp_pdev->dev; - drm_of_component_match_add(dev, match, compare_of, node); + drm_of_component_match_add(dev, match, component_compare_of, node); dev_dbg(dev, "Adding component match for %pOF\n", node); } diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 0f3b1ef8e497..6fb85bc6487a 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -59,7 +59,8 @@ enum mtk_dpi_out_channel_swap { enum mtk_dpi_out_color_format { MTK_DPI_COLOR_FORMAT_RGB, - MTK_DPI_COLOR_FORMAT_YCBCR_422 + MTK_DPI_COLOR_FORMAT_YCBCR_422, + MTK_DPI_COLOR_FORMAT_YCBCR_444 }; struct mtk_dpi { @@ -450,9 +451,16 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi) static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format) { - mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); + mtk_dpi_config_channel_swap(dpi, dpi->channel_swap); - if (format == MTK_DPI_COLOR_FORMAT_YCBCR_422) { + switch (format) { + case MTK_DPI_COLOR_FORMAT_YCBCR_444: + mtk_dpi_config_yuv422_enable(dpi, false); + mtk_dpi_config_csc_enable(dpi, true); + if (dpi->conf->swap_input_support) + mtk_dpi_config_swap_input(dpi, false); + break; + case MTK_DPI_COLOR_FORMAT_YCBCR_422: mtk_dpi_config_yuv422_enable(dpi, true); mtk_dpi_config_csc_enable(dpi, true); @@ -463,11 +471,14 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, mtk_dpi_mask(dpi, DPI_MATRIX_SET, dpi->mode.hdisplay <= 720 ? MATRIX_SEL_RGB_TO_BT601 : MATRIX_SEL_RGB_TO_JPEG, INT_MATRIX_SEL_MASK); - } else { + break; + default: + case MTK_DPI_COLOR_FORMAT_RGB: mtk_dpi_config_yuv422_enable(dpi, false); mtk_dpi_config_csc_enable(dpi, false); if (dpi->conf->swap_input_support) mtk_dpi_config_swap_input(dpi, false); + break; } } @@ -734,6 +745,65 @@ static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, return input_fmts; } +static unsigned int mtk_dpi_bus_fmt_bit_num(unsigned int out_bus_format) +{ + switch (out_bus_format) { + default: + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_BGR888_1X24: + case MEDIA_BUS_FMT_RGB888_2X12_LE: + case MEDIA_BUS_FMT_RGB888_2X12_BE: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUV8_1X24: + return MTK_DPI_OUT_BIT_NUM_8BITS; + case MEDIA_BUS_FMT_RGB101010_1X30: + case MEDIA_BUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUV10_1X30: + return MTK_DPI_OUT_BIT_NUM_10BITS; + case MEDIA_BUS_FMT_YUYV12_1X24: + return MTK_DPI_OUT_BIT_NUM_12BITS; + } +} + +static unsigned int mtk_dpi_bus_fmt_channel_swap(unsigned int out_bus_format) +{ + switch (out_bus_format) { + default: + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB888_2X12_LE: + case MEDIA_BUS_FMT_RGB888_2X12_BE: + case MEDIA_BUS_FMT_RGB101010_1X30: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV12_1X24: + return MTK_DPI_OUT_CHANNEL_SWAP_RGB; + case MEDIA_BUS_FMT_BGR888_1X24: + case MEDIA_BUS_FMT_YUV8_1X24: + case MEDIA_BUS_FMT_YUV10_1X30: + return MTK_DPI_OUT_CHANNEL_SWAP_BGR; + } +} + +static unsigned int mtk_dpi_bus_fmt_color_format(unsigned int out_bus_format) +{ + switch (out_bus_format) { + default: + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_BGR888_1X24: + case MEDIA_BUS_FMT_RGB888_2X12_LE: + case MEDIA_BUS_FMT_RGB888_2X12_BE: + case MEDIA_BUS_FMT_RGB101010_1X30: + return MTK_DPI_COLOR_FORMAT_RGB; + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV12_1X24: + return MTK_DPI_COLOR_FORMAT_YCBCR_422; + case MEDIA_BUS_FMT_YUV8_1X24: + case MEDIA_BUS_FMT_YUV10_1X30: + return MTK_DPI_COLOR_FORMAT_YCBCR_444; + } +} + static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge, struct drm_bridge_state *bridge_state, struct drm_crtc_state *crtc_state, @@ -753,13 +823,10 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge, bridge_state->output_bus_cfg.format); dpi->output_fmt = out_bus_format; - dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS; - dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB; + dpi->bit_num = mtk_dpi_bus_fmt_bit_num(out_bus_format); + dpi->channel_swap = mtk_dpi_bus_fmt_channel_swap(out_bus_format); dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB; - if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16) - dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422; - else - dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB; + dpi->color_format = mtk_dpi_bus_fmt_color_format(out_bus_format); return 0; } @@ -1027,9 +1094,29 @@ static const u32 mt8183_output_fmts[] = { MEDIA_BUS_FMT_RGB888_2X12_BE, }; -static const u32 mt8195_output_fmts[] = { +static const u32 mt8195_dpi_output_fmts[] = { + MEDIA_BUS_FMT_BGR888_1X24, + MEDIA_BUS_FMT_RGB888_1X24, + MEDIA_BUS_FMT_RGB888_2X12_LE, + MEDIA_BUS_FMT_RGB888_2X12_BE, + MEDIA_BUS_FMT_RGB101010_1X30, + MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_YUYV10_1X20, + MEDIA_BUS_FMT_YUYV12_1X24, + MEDIA_BUS_FMT_YUV8_1X24, + MEDIA_BUS_FMT_YUV10_1X30, +}; + +static const u32 mt8195_dp_intf_output_fmts[] = { + MEDIA_BUS_FMT_BGR888_1X24, MEDIA_BUS_FMT_RGB888_1X24, + MEDIA_BUS_FMT_RGB888_2X12_LE, + MEDIA_BUS_FMT_RGB888_2X12_BE, + MEDIA_BUS_FMT_RGB101010_1X30, MEDIA_BUS_FMT_YUYV8_1X16, + MEDIA_BUS_FMT_YUYV10_1X20, + MEDIA_BUS_FMT_YUV8_1X24, + MEDIA_BUS_FMT_YUV10_1X30, }; static const struct mtk_dpi_factor dpi_factor_mt2701[] = { @@ -1142,8 +1229,8 @@ static const struct mtk_dpi_conf mt8192_conf = { static const struct mtk_dpi_conf mt8195_conf = { .max_clock_khz = 594000, - .output_fmts = mt8183_output_fmts, - .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts), + .output_fmts = mt8195_dpi_output_fmts, + .num_output_fmts = ARRAY_SIZE(mt8195_dpi_output_fmts), .pixels_per_iter = 1, .is_ck_de_pol = true, .swap_input_support = true, @@ -1162,8 +1249,8 @@ static const struct mtk_dpi_conf mt8195_dpintf_conf = { .dpi_factor = dpi_factor_mt8195_dp_intf, .num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8195_dp_intf), .max_clock_khz = 600000, - .output_fmts = mt8195_output_fmts, - .num_output_fmts = ARRAY_SIZE(mt8195_output_fmts), + .output_fmts = mt8195_dp_intf_output_fmts, + .num_output_fmts = ARRAY_SIZE(mt8195_dp_intf_output_fmts), .pixels_per_iter = 4, .dimension_mask = DPINTF_HPW_MASK, .hvsize_mask = DPINTF_HSIZE_MASK, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 74158b9d6503..7c0c12dde488 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -470,7 +470,7 @@ static int mtk_drm_kms_init(struct drm_device *drm) ret = drmm_mode_config_init(drm); if (ret) - goto put_mutex_dev; + return ret; drm->mode_config.min_width = 64; drm->mode_config.min_height = 64; @@ -488,8 +488,11 @@ static int mtk_drm_kms_init(struct drm_device *drm) for (i = 0; i < private->data->mmsys_dev_num; i++) { drm->dev_private = private->all_drm_private[i]; ret = component_bind_all(private->all_drm_private[i]->dev, drm); - if (ret) - goto put_mutex_dev; + if (ret) { + while (--i >= 0) + component_unbind_all(private->all_drm_private[i]->dev, drm); + return ret; + } } /* @@ -582,9 +585,6 @@ static int mtk_drm_kms_init(struct drm_device *drm) err_component_unbind: for (i = 0; i < private->data->mmsys_dev_num; i++) component_unbind_all(private->all_drm_private[i]->dev, drm); -put_mutex_dev: - for (i = 0; i < private->data->mmsys_dev_num; i++) - put_device(private->all_drm_private[i]->mutex_dev); return ret; } @@ -655,8 +655,10 @@ static int mtk_drm_bind(struct device *dev) return 0; drm = drm_dev_alloc(&mtk_drm_driver, dev); - if (IS_ERR(drm)) - return PTR_ERR(drm); + if (IS_ERR(drm)) { + ret = PTR_ERR(drm); + goto err_put_dev; + } private->drm_master = true; drm->dev_private = private; @@ -682,18 +684,31 @@ err_free: drm_dev_put(drm); for (i = 0; i < private->data->mmsys_dev_num; i++) private->all_drm_private[i]->drm = NULL; +err_put_dev: + for (i = 0; i < private->data->mmsys_dev_num; i++) { + /* For device_find_child in mtk_drm_get_all_priv() */ + put_device(private->all_drm_private[i]->dev); + } + put_device(private->mutex_dev); return ret; } static void mtk_drm_unbind(struct device *dev) { struct mtk_drm_private *private = dev_get_drvdata(dev); + int i; /* for multi mmsys dev, unregister drm dev in mmsys master */ if (private->drm_master) { drm_dev_unregister(private->drm); mtk_drm_kms_deinit(private->drm); drm_dev_put(private->drm); + + for (i = 0; i < private->data->mmsys_dev_num; i++) { + /* For device_find_child in mtk_drm_get_all_priv() */ + put_device(private->all_drm_private[i]->dev); + } + put_device(private->mutex_dev); } private->mtk_drm_bound = false; private->drm_master = false; diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index c9d0c335c519..8803cd4a8bc9 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -31,7 +31,6 @@ #include <drm/drm_probe_helper.h> #include "mtk_cec.h" -#include "mtk_hdmi.h" #include "mtk_hdmi_regs.h" #define NCTS_BYTES 7 @@ -165,7 +164,7 @@ struct mtk_hdmi { bool dvi_mode; struct regmap *sys_regmap; unsigned int sys_offset; - void __iomem *regs; + struct regmap *regs; struct platform_device *audio_pdev; struct hdmi_audio_param aud_param; bool audio_enable; @@ -181,50 +180,10 @@ static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b) return container_of(b, struct mtk_hdmi, bridge); } -static u32 mtk_hdmi_read(struct mtk_hdmi *hdmi, u32 offset) -{ - return readl(hdmi->regs + offset); -} - -static void mtk_hdmi_write(struct mtk_hdmi *hdmi, u32 offset, u32 val) -{ - writel(val, hdmi->regs + offset); -} - -static void mtk_hdmi_clear_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits) -{ - void __iomem *reg = hdmi->regs + offset; - u32 tmp; - - tmp = readl(reg); - tmp &= ~bits; - writel(tmp, reg); -} - -static void mtk_hdmi_set_bits(struct mtk_hdmi *hdmi, u32 offset, u32 bits) -{ - void __iomem *reg = hdmi->regs + offset; - u32 tmp; - - tmp = readl(reg); - tmp |= bits; - writel(tmp, reg); -} - -static void mtk_hdmi_mask(struct mtk_hdmi *hdmi, u32 offset, u32 val, u32 mask) -{ - void __iomem *reg = hdmi->regs + offset; - u32 tmp; - - tmp = readl(reg); - tmp = (tmp & ~mask) | (val & mask); - writel(tmp, reg); -} - static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black) { - mtk_hdmi_mask(hdmi, VIDEO_CFG_4, black ? GEN_RGB : NORMAL_PATH, - VIDEO_SOURCE_SEL); + regmap_update_bits(hdmi->regs, VIDEO_SOURCE_SEL, + VIDEO_CFG_4, black ? GEN_RGB : NORMAL_PATH); } static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable) @@ -259,12 +218,12 @@ static void mtk_hdmi_hw_1p4_version_enable(struct mtk_hdmi *hdmi, bool enable) static void mtk_hdmi_hw_aud_mute(struct mtk_hdmi *hdmi) { - mtk_hdmi_set_bits(hdmi, GRL_AUDIO_CFG, AUDIO_ZERO); + regmap_set_bits(hdmi->regs, GRL_AUDIO_CFG, AUDIO_ZERO); } static void mtk_hdmi_hw_aud_unmute(struct mtk_hdmi *hdmi) { - mtk_hdmi_clear_bits(hdmi, GRL_AUDIO_CFG, AUDIO_ZERO); + regmap_clear_bits(hdmi->regs, GRL_AUDIO_CFG, AUDIO_ZERO); } static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi) @@ -273,25 +232,25 @@ static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi) HDMI_RST, HDMI_RST); regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG1C, HDMI_RST, 0); - mtk_hdmi_clear_bits(hdmi, GRL_CFG3, CFG3_CONTROL_PACKET_DELAY); + regmap_clear_bits(hdmi->regs, GRL_CFG3, CFG3_CONTROL_PACKET_DELAY); regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG1C, ANLG_ON, ANLG_ON); } static void mtk_hdmi_hw_enable_notice(struct mtk_hdmi *hdmi, bool enable_notice) { - mtk_hdmi_mask(hdmi, GRL_CFG2, enable_notice ? CFG2_NOTICE_EN : 0, - CFG2_NOTICE_EN); + regmap_update_bits(hdmi->regs, GRL_CFG2, CFG2_NOTICE_EN, + enable_notice ? CFG2_NOTICE_EN : 0); } static void mtk_hdmi_hw_write_int_mask(struct mtk_hdmi *hdmi, u32 int_mask) { - mtk_hdmi_write(hdmi, GRL_INT_MASK, int_mask); + regmap_write(hdmi->regs, GRL_INT_MASK, int_mask); } static void mtk_hdmi_hw_enable_dvi_mode(struct mtk_hdmi *hdmi, bool enable) { - mtk_hdmi_mask(hdmi, GRL_CFG1, enable ? CFG1_DVI : 0, CFG1_DVI); + regmap_update_bits(hdmi->regs, GRL_CFG1, CFG1_DVI, enable ? CFG1_DVI : 0); } static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer, @@ -337,22 +296,22 @@ static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer, dev_err(hdmi->dev, "Unknown infoframe type %d\n", frame_type); return; } - mtk_hdmi_clear_bits(hdmi, ctrl_reg, ctrl_frame_en); - mtk_hdmi_write(hdmi, GRL_INFOFRM_TYPE, frame_type); - mtk_hdmi_write(hdmi, GRL_INFOFRM_VER, frame_ver); - mtk_hdmi_write(hdmi, GRL_INFOFRM_LNG, frame_len); + regmap_clear_bits(hdmi->regs, ctrl_reg, ctrl_frame_en); + regmap_write(hdmi->regs, GRL_INFOFRM_TYPE, frame_type); + regmap_write(hdmi->regs, GRL_INFOFRM_VER, frame_ver); + regmap_write(hdmi->regs, GRL_INFOFRM_LNG, frame_len); - mtk_hdmi_write(hdmi, GRL_IFM_PORT, checksum); + regmap_write(hdmi->regs, GRL_IFM_PORT, checksum); for (i = 0; i < frame_len; i++) - mtk_hdmi_write(hdmi, GRL_IFM_PORT, frame_data[i]); + regmap_write(hdmi->regs, GRL_IFM_PORT, frame_data[i]); - mtk_hdmi_set_bits(hdmi, ctrl_reg, ctrl_frame_en); + regmap_set_bits(hdmi->regs, ctrl_reg, ctrl_frame_en); } static void mtk_hdmi_hw_send_aud_packet(struct mtk_hdmi *hdmi, bool enable) { - mtk_hdmi_mask(hdmi, GRL_SHIFT_R2, enable ? 0 : AUDIO_PACKET_OFF, - AUDIO_PACKET_OFF); + regmap_update_bits(hdmi->regs, AUDIO_PACKET_OFF, + GRL_SHIFT_R2, enable ? 0 : AUDIO_PACKET_OFF); } static void mtk_hdmi_hw_config_sys(struct mtk_hdmi *hdmi) @@ -373,44 +332,44 @@ static void mtk_hdmi_hw_set_deep_color_mode(struct mtk_hdmi *hdmi) static void mtk_hdmi_hw_send_av_mute(struct mtk_hdmi *hdmi) { - mtk_hdmi_clear_bits(hdmi, GRL_CFG4, CTRL_AVMUTE); + regmap_clear_bits(hdmi->regs, GRL_CFG4, CTRL_AVMUTE); usleep_range(2000, 4000); - mtk_hdmi_set_bits(hdmi, GRL_CFG4, CTRL_AVMUTE); + regmap_set_bits(hdmi->regs, GRL_CFG4, CTRL_AVMUTE); } static void mtk_hdmi_hw_send_av_unmute(struct mtk_hdmi *hdmi) { - mtk_hdmi_mask(hdmi, GRL_CFG4, CFG4_AV_UNMUTE_EN, - CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET); + regmap_update_bits(hdmi->regs, GRL_CFG4, CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET, + CFG4_AV_UNMUTE_EN); usleep_range(2000, 4000); - mtk_hdmi_mask(hdmi, GRL_CFG4, CFG4_AV_UNMUTE_SET, - CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET); + regmap_update_bits(hdmi->regs, GRL_CFG4, CFG4_AV_UNMUTE_EN | CFG4_AV_UNMUTE_SET, + CFG4_AV_UNMUTE_SET); } static void mtk_hdmi_hw_ncts_enable(struct mtk_hdmi *hdmi, bool on) { - mtk_hdmi_mask(hdmi, GRL_CTS_CTRL, on ? 0 : CTS_CTRL_SOFT, - CTS_CTRL_SOFT); + regmap_update_bits(hdmi->regs, GRL_CTS_CTRL, CTS_CTRL_SOFT, + on ? 0 : CTS_CTRL_SOFT); } static void mtk_hdmi_hw_ncts_auto_write_enable(struct mtk_hdmi *hdmi, bool enable) { - mtk_hdmi_mask(hdmi, GRL_CTS_CTRL, enable ? NCTS_WRI_ANYTIME : 0, - NCTS_WRI_ANYTIME); + regmap_update_bits(hdmi->regs, GRL_CTS_CTRL, NCTS_WRI_ANYTIME, + enable ? NCTS_WRI_ANYTIME : 0); } static void mtk_hdmi_hw_msic_setting(struct mtk_hdmi *hdmi, struct drm_display_mode *mode) { - mtk_hdmi_clear_bits(hdmi, GRL_CFG4, CFG4_MHL_MODE); + regmap_clear_bits(hdmi->regs, GRL_CFG4, CFG4_MHL_MODE); if (mode->flags & DRM_MODE_FLAG_INTERLACE && mode->clock == 74250 && mode->vdisplay == 1080) - mtk_hdmi_clear_bits(hdmi, GRL_CFG2, CFG2_MHL_DE_SEL); + regmap_clear_bits(hdmi->regs, GRL_CFG2, CFG2_MHL_DE_SEL); else - mtk_hdmi_set_bits(hdmi, GRL_CFG2, CFG2_MHL_DE_SEL); + regmap_set_bits(hdmi->regs, GRL_CFG2, CFG2_MHL_DE_SEL); } static void mtk_hdmi_hw_aud_set_channel_swap(struct mtk_hdmi *hdmi, @@ -438,7 +397,7 @@ static void mtk_hdmi_hw_aud_set_channel_swap(struct mtk_hdmi *hdmi, swap_bit = LFE_CC_SWAP; break; } - mtk_hdmi_mask(hdmi, GRL_CH_SWAP, swap_bit, 0xff); + regmap_update_bits(hdmi->regs, GRL_CH_SWAP, 0xff, swap_bit); } static void mtk_hdmi_hw_aud_set_bit_num(struct mtk_hdmi *hdmi, @@ -459,7 +418,7 @@ static void mtk_hdmi_hw_aud_set_bit_num(struct mtk_hdmi *hdmi, break; } - mtk_hdmi_mask(hdmi, GRL_AOUT_CFG, val, AOUT_BNUM_SEL_MASK); + regmap_update_bits(hdmi->regs, GRL_AOUT_CFG, AOUT_BNUM_SEL_MASK, val); } static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi *hdmi, @@ -467,7 +426,7 @@ static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi *hdmi, { u32 val; - val = mtk_hdmi_read(hdmi, GRL_CFG0); + regmap_read(hdmi->regs, GRL_CFG0, &val); val &= ~(CFG0_W_LENGTH_MASK | CFG0_I2S_MODE_MASK); switch (i2s_fmt) { @@ -491,7 +450,7 @@ static void mtk_hdmi_hw_aud_set_i2s_fmt(struct mtk_hdmi *hdmi, val |= CFG0_I2S_MODE_I2S | CFG0_W_LENGTH_16BIT; break; } - mtk_hdmi_write(hdmi, GRL_CFG0, val); + regmap_write(hdmi->regs, GRL_CFG0, val); } static void mtk_hdmi_hw_audio_config(struct mtk_hdmi *hdmi, bool dst) @@ -500,14 +459,14 @@ static void mtk_hdmi_hw_audio_config(struct mtk_hdmi *hdmi, bool dst) u8 val; /* Disable high bitrate, set DST packet normal/double */ - mtk_hdmi_clear_bits(hdmi, GRL_AOUT_CFG, HIGH_BIT_RATE_PACKET_ALIGN); + regmap_clear_bits(hdmi->regs, GRL_AOUT_CFG, HIGH_BIT_RATE_PACKET_ALIGN); if (dst) val = DST_NORMAL_DOUBLE | SACD_DST; else val = 0; - mtk_hdmi_mask(hdmi, GRL_AUDIO_CFG, val, mask); + regmap_update_bits(hdmi->regs, GRL_AUDIO_CFG, mask, val); } static void mtk_hdmi_hw_aud_set_i2s_chan_num(struct mtk_hdmi *hdmi, @@ -548,10 +507,10 @@ static void mtk_hdmi_hw_aud_set_i2s_chan_num(struct mtk_hdmi *hdmi, i2s_uv = I2S_UV_CH_EN(0); } - mtk_hdmi_write(hdmi, GRL_CH_SW0, ch_switch & 0xff); - mtk_hdmi_write(hdmi, GRL_CH_SW1, (ch_switch >> 8) & 0xff); - mtk_hdmi_write(hdmi, GRL_CH_SW2, (ch_switch >> 16) & 0xff); - mtk_hdmi_write(hdmi, GRL_I2S_UV, i2s_uv); + regmap_write(hdmi->regs, GRL_CH_SW0, ch_switch & 0xff); + regmap_write(hdmi->regs, GRL_CH_SW1, (ch_switch >> 8) & 0xff); + regmap_write(hdmi->regs, GRL_CH_SW2, (ch_switch >> 16) & 0xff); + regmap_write(hdmi->regs, GRL_I2S_UV, i2s_uv); } static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi *hdmi, @@ -559,7 +518,7 @@ static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi *hdmi, { u32 val; - val = mtk_hdmi_read(hdmi, GRL_CFG1); + regmap_read(hdmi->regs, GRL_CFG1, &val); if (input_type == HDMI_AUD_INPUT_I2S && (val & CFG1_SPDIF) == CFG1_SPDIF) { val &= ~CFG1_SPDIF; @@ -567,7 +526,7 @@ static void mtk_hdmi_hw_aud_set_input_type(struct mtk_hdmi *hdmi, (val & CFG1_SPDIF) == 0) { val |= CFG1_SPDIF; } - mtk_hdmi_write(hdmi, GRL_CFG1, val); + regmap_write(hdmi->regs, GRL_CFG1, val); } static void mtk_hdmi_hw_aud_set_channel_status(struct mtk_hdmi *hdmi, @@ -576,13 +535,13 @@ static void mtk_hdmi_hw_aud_set_channel_status(struct mtk_hdmi *hdmi, int i; for (i = 0; i < 5; i++) { - mtk_hdmi_write(hdmi, GRL_I2S_C_STA0 + i * 4, channel_status[i]); - mtk_hdmi_write(hdmi, GRL_L_STATUS_0 + i * 4, channel_status[i]); - mtk_hdmi_write(hdmi, GRL_R_STATUS_0 + i * 4, channel_status[i]); + regmap_write(hdmi->regs, GRL_I2S_C_STA0 + i * 4, channel_status[i]); + regmap_write(hdmi->regs, GRL_L_STATUS_0 + i * 4, channel_status[i]); + regmap_write(hdmi->regs, GRL_R_STATUS_0 + i * 4, channel_status[i]); } for (; i < 24; i++) { - mtk_hdmi_write(hdmi, GRL_L_STATUS_0 + i * 4, 0); - mtk_hdmi_write(hdmi, GRL_R_STATUS_0 + i * 4, 0); + regmap_write(hdmi->regs, GRL_L_STATUS_0 + i * 4, 0); + regmap_write(hdmi->regs, GRL_R_STATUS_0 + i * 4, 0); } } @@ -590,13 +549,13 @@ static void mtk_hdmi_hw_aud_src_reenable(struct mtk_hdmi *hdmi) { u32 val; - val = mtk_hdmi_read(hdmi, GRL_MIX_CTRL); + regmap_read(hdmi->regs, GRL_MIX_CTRL, &val); if (val & MIX_CTRL_SRC_EN) { val &= ~MIX_CTRL_SRC_EN; - mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val); + regmap_write(hdmi->regs, GRL_MIX_CTRL, val); usleep_range(255, 512); val |= MIX_CTRL_SRC_EN; - mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val); + regmap_write(hdmi->regs, GRL_MIX_CTRL, val); } } @@ -604,10 +563,10 @@ static void mtk_hdmi_hw_aud_src_disable(struct mtk_hdmi *hdmi) { u32 val; - val = mtk_hdmi_read(hdmi, GRL_MIX_CTRL); + regmap_read(hdmi->regs, GRL_MIX_CTRL, &val); val &= ~MIX_CTRL_SRC_EN; - mtk_hdmi_write(hdmi, GRL_MIX_CTRL, val); - mtk_hdmi_write(hdmi, GRL_SHIFT_L1, 0x00); + regmap_write(hdmi->regs, GRL_MIX_CTRL, val); + regmap_write(hdmi->regs, GRL_SHIFT_L1, 0x00); } static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi, @@ -615,7 +574,7 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi, { u32 val; - val = mtk_hdmi_read(hdmi, GRL_CFG5); + regmap_read(hdmi->regs, GRL_CFG5, &val); val &= CFG5_CD_RATIO_MASK; switch (mclk) { @@ -638,7 +597,7 @@ static void mtk_hdmi_hw_aud_set_mclk(struct mtk_hdmi *hdmi, val |= CFG5_FS256; break; } - mtk_hdmi_write(hdmi, GRL_CFG5, val); + regmap_write(hdmi->regs, GRL_CFG5, val); } struct hdmi_acr_n { @@ -716,15 +675,22 @@ static unsigned int hdmi_expected_cts(unsigned int audio_sample_rate, 128 * audio_sample_rate); } +static void mtk_hdmi_get_ncts(unsigned int sample_rate, unsigned int clock, + unsigned int *n, unsigned int *cts) +{ + *n = hdmi_recommended_n(sample_rate, clock); + *cts = hdmi_expected_cts(sample_rate, clock, *n); +} + static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n, unsigned int cts) { unsigned char val[NCTS_BYTES]; int i; - mtk_hdmi_write(hdmi, GRL_NCTS, 0); - mtk_hdmi_write(hdmi, GRL_NCTS, 0); - mtk_hdmi_write(hdmi, GRL_NCTS, 0); + regmap_write(hdmi->regs, GRL_NCTS, 0); + regmap_write(hdmi->regs, GRL_NCTS, 0); + regmap_write(hdmi->regs, GRL_NCTS, 0); memset(val, 0, sizeof(val)); val[0] = (cts >> 24) & 0xff; @@ -737,7 +703,7 @@ static void do_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, unsigned int n, val[6] = n & 0xff; for (i = 0; i < NCTS_BYTES; i++) - mtk_hdmi_write(hdmi, GRL_NCTS, val[i]); + regmap_write(hdmi->regs, GRL_NCTS, val[i]); } static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, @@ -746,14 +712,12 @@ static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi, { unsigned int n, cts; - n = hdmi_recommended_n(sample_rate, clock); - cts = hdmi_expected_cts(sample_rate, clock, n); + mtk_hdmi_get_ncts(sample_rate, clock, &n, &cts); dev_dbg(hdmi->dev, "%s: sample_rate=%u, clock=%d, cts=%u, n=%u\n", __func__, sample_rate, clock, n, cts); - mtk_hdmi_mask(hdmi, DUMMY_304, AUDIO_I2S_NCTS_SEL_64, - AUDIO_I2S_NCTS_SEL); + regmap_update_bits(hdmi->regs, DUMMY_304, AUDIO_I2S_NCTS_SEL, AUDIO_I2S_NCTS_SEL_64); do_hdmi_hw_aud_set_ncts(hdmi, n, cts); } @@ -873,7 +837,7 @@ static void mtk_hdmi_aud_set_input(struct mtk_hdmi *hdmi) bool dst; mtk_hdmi_hw_aud_set_channel_swap(hdmi, HDMI_AUD_SWAP_LFE_CC); - mtk_hdmi_set_bits(hdmi, GRL_MIX_CTRL, MIX_CTRL_FLAT); + regmap_set_bits(hdmi->regs, GRL_MIX_CTRL, MIX_CTRL_FLAT); if (hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_SPDIF && hdmi->aud_param.aud_codec == HDMI_AUDIO_CODING_TYPE_DST) { @@ -905,7 +869,7 @@ static int mtk_hdmi_aud_set_src(struct mtk_hdmi *hdmi, mtk_hdmi_hw_ncts_enable(hdmi, false); mtk_hdmi_hw_aud_src_disable(hdmi); - mtk_hdmi_clear_bits(hdmi, GRL_CFG2, CFG2_ACLK_INV); + regmap_clear_bits(hdmi->regs, GRL_CFG2, CFG2_ACLK_INV); if (hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_I2S) { switch (sample_rate) { @@ -1061,20 +1025,6 @@ static int mtk_hdmi_setup_vendor_specific_infoframe(struct mtk_hdmi *hdmi, return 0; } -static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi) -{ - struct hdmi_audio_param *aud_param = &hdmi->aud_param; - - aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM; - aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16; - aud_param->aud_input_type = HDMI_AUD_INPUT_I2S; - aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT; - aud_param->aud_mclk = HDMI_AUD_MCLK_128FS; - aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0; - - return 0; -} - static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi) { mtk_hdmi_hw_send_aud_packet(hdmi, true); @@ -1087,20 +1037,6 @@ static void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi) hdmi->audio_enable = false; } -static int mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi, - struct hdmi_audio_param *param) -{ - if (!hdmi->audio_enable) { - dev_err(hdmi->dev, "hdmi audio is in disable state!\n"); - return -EINVAL; - } - dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n", - param->aud_codec, param->aud_input_type, - param->aud_input_chan_type, param->codec_params.sample_rate); - memcpy(&hdmi->aud_param, param, sizeof(*param)); - return mtk_hdmi_aud_output_config(hdmi, &hdmi->mode); -} - static int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi, struct drm_display_mode *mode) { @@ -1408,30 +1344,20 @@ static const struct drm_bridge_funcs mtk_hdmi_bridge_funcs = { .edid_read = mtk_hdmi_bridge_edid_read, }; -static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, - struct platform_device *pdev) +static int mtk_hdmi_get_cec_dev(struct mtk_hdmi *hdmi, struct device *dev, struct device_node *np) { - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct device_node *cec_np, *remote, *i2c_np; struct platform_device *cec_pdev; - struct regmap *regmap; + struct device_node *cec_np; int ret; ret = mtk_hdmi_get_all_clk(hdmi, np); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get clocks: %d\n", ret); - - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to get clocks\n"); /* The CEC module handles HDMI hotplug detection */ cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-cec"); - if (!cec_np) { - dev_err(dev, "Failed to find CEC node\n"); - return -EINVAL; - } + if (!cec_np) + return dev_err_probe(dev, -EINVAL, "Failed to find CEC node\n"); cec_pdev = of_find_device_by_node(cec_np); if (!cec_pdev) { @@ -1441,82 +1367,77 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, return -EPROBE_DEFER; } of_node_put(cec_np); - hdmi->cec_dev = &cec_pdev->dev; /* * The mediatek,syscon-hdmi property contains a phandle link to the * MMSYS_CONFIG device and the register offset of the HDMI_SYS_CFG * registers it contains. */ - regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi"); - ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1, - &hdmi->sys_offset); - if (IS_ERR(regmap)) - ret = PTR_ERR(regmap); - if (ret) { - dev_err(dev, - "Failed to get system configuration registers: %d\n", - ret); - goto put_device; - } - hdmi->sys_regmap = regmap; + hdmi->sys_regmap = syscon_regmap_lookup_by_phandle_args(np, "mediatek,syscon-hdmi", + 1, &hdmi->sys_offset); + if (IS_ERR(hdmi->sys_regmap)) + return dev_err_probe(dev, PTR_ERR(hdmi->sys_regmap), + "Failed to get system configuration registers\n"); - hdmi->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(hdmi->regs)) { - ret = PTR_ERR(hdmi->regs); - goto put_device; - } + hdmi->cec_dev = &cec_pdev->dev; + return 0; +} + +static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *remote, *i2c_np; + int ret; + + ret = mtk_hdmi_get_all_clk(hdmi, np); + if (ret) + return dev_err_probe(dev, ret, "Failed to get clocks\n"); + + hdmi->regs = device_node_to_regmap(dev->of_node); + if (IS_ERR(hdmi->regs)) + return PTR_ERR(hdmi->regs); remote = of_graph_get_remote_node(np, 1, 0); - if (!remote) { - ret = -EINVAL; - goto put_device; - } + if (!remote) + return -EINVAL; if (!of_device_is_compatible(remote, "hdmi-connector")) { hdmi->next_bridge = of_drm_find_bridge(remote); if (!hdmi->next_bridge) { dev_err(dev, "Waiting for external bridge\n"); of_node_put(remote); - ret = -EPROBE_DEFER; - goto put_device; + return -EPROBE_DEFER; } } i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0); - if (!i2c_np) { - dev_err(dev, "Failed to find ddc-i2c-bus node in %pOF\n", - remote); - of_node_put(remote); - ret = -EINVAL; - goto put_device; - } of_node_put(remote); + if (!i2c_np) + return dev_err_probe(dev, -EINVAL, "No ddc-i2c-bus in connector\n"); hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np); of_node_put(i2c_np); - if (!hdmi->ddc_adpt) { - dev_err(dev, "Failed to get ddc i2c adapter by node\n"); - ret = -EINVAL; - goto put_device; - } + if (!hdmi->ddc_adpt) + return dev_err_probe(dev, -EINVAL, "Failed to get ddc i2c adapter by node\n"); + + ret = mtk_hdmi_get_cec_dev(hdmi, dev, np); + if (ret) + return ret; return 0; -put_device: - put_device(hdmi->cec_dev); - return ret; } /* * HDMI audio codec callbacks */ -static int mtk_hdmi_audio_hw_params(struct device *dev, void *data, - struct hdmi_codec_daifmt *daifmt, - struct hdmi_codec_params *params) +static int mtk_hdmi_audio_params(struct mtk_hdmi *hdmi, + struct hdmi_codec_daifmt *daifmt, + struct hdmi_codec_params *params) { - struct mtk_hdmi *hdmi = dev_get_drvdata(dev); - struct hdmi_audio_param hdmi_params; + struct hdmi_audio_param aud_params = { 0 }; unsigned int chan = params->cea.channels; dev_dbg(hdmi->dev, "%s: %u Hz, %d bit, %d channels\n", __func__, @@ -1527,16 +1448,16 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data, switch (chan) { case 2: - hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0; + aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0; break; case 4: - hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0; + aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_4_0; break; case 6: - hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1; + aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_5_1; break; case 8: - hdmi_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1; + aud_params.aud_input_chan_type = HDMI_AUD_CHAN_TYPE_7_1; break; default: dev_err(hdmi->dev, "channel[%d] not supported!\n", chan); @@ -1560,27 +1481,45 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data, switch (daifmt->fmt) { case HDMI_I2S: - hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM; - hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16; - hdmi_params.aud_input_type = HDMI_AUD_INPUT_I2S; - hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT; - hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS; + aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM; + aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16; + aud_params.aud_input_type = HDMI_AUD_INPUT_I2S; + aud_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT; + aud_params.aud_mclk = HDMI_AUD_MCLK_128FS; break; case HDMI_SPDIF: - hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM; - hdmi_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16; - hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF; + aud_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM; + aud_params.aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16; + aud_params.aud_input_type = HDMI_AUD_INPUT_SPDIF; break; default: dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__, daifmt->fmt); return -EINVAL; } + memcpy(&aud_params.codec_params, params, sizeof(aud_params.codec_params)); + memcpy(&hdmi->aud_param, &aud_params, sizeof(aud_params)); + + dev_dbg(hdmi->dev, "codec:%d, input:%d, channel:%d, fs:%d\n", + aud_params.aud_codec, aud_params.aud_input_type, + aud_params.aud_input_chan_type, aud_params.codec_params.sample_rate); - memcpy(&hdmi_params.codec_params, params, - sizeof(hdmi_params.codec_params)); + return 0; +} + +static int mtk_hdmi_audio_hw_params(struct device *dev, void *data, + struct hdmi_codec_daifmt *daifmt, + struct hdmi_codec_params *params) +{ + struct mtk_hdmi *hdmi = dev_get_drvdata(dev); - mtk_hdmi_audio_set_param(hdmi, &hdmi_params); + if (!hdmi->audio_enable) { + dev_err(hdmi->dev, "hdmi audio is in disable state!\n"); + return -EINVAL; + } + + mtk_hdmi_audio_params(hdmi, daifmt, params); + mtk_hdmi_aud_output_config(hdmi, &hdmi->mode); return 0; } @@ -1626,17 +1565,22 @@ static int mtk_hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, return 0; } -static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data, - hdmi_codec_plugged_cb fn, +static void mtk_hdmi_audio_set_plugged_cb(struct mtk_hdmi *hdmi, hdmi_codec_plugged_cb fn, struct device *codec_dev) { - struct mtk_hdmi *hdmi = data; - mutex_lock(&hdmi->update_plugged_status_lock); hdmi->plugged_cb = fn; hdmi->codec_dev = codec_dev; mutex_unlock(&hdmi->update_plugged_status_lock); +} + +static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data, + hdmi_codec_plugged_cb fn, + struct device *codec_dev) +{ + struct mtk_hdmi *hdmi = data; + mtk_hdmi_audio_set_plugged_cb(hdmi, fn, codec_dev); mtk_hdmi_update_plugged_status(hdmi); return 0; @@ -1659,6 +1603,7 @@ static void mtk_hdmi_unregister_audio_driver(void *data) static int mtk_hdmi_register_audio_driver(struct device *dev) { struct mtk_hdmi *hdmi = dev_get_drvdata(dev); + struct hdmi_audio_param *aud_param = &hdmi->aud_param; struct hdmi_codec_pdata codec_data = { .ops = &mtk_hdmi_audio_codec_ops, .max_i2s_channels = 2, @@ -1668,6 +1613,13 @@ static int mtk_hdmi_register_audio_driver(struct device *dev) }; int ret; + aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM; + aud_param->aud_sample_size = HDMI_AUDIO_SAMPLE_SIZE_16; + aud_param->aud_input_type = HDMI_AUD_INPUT_I2S; + aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT; + aud_param->aud_mclk = HDMI_AUD_MCLK_128FS; + aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0; + hdmi->audio_pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, @@ -1709,11 +1661,6 @@ static int mtk_hdmi_probe(struct platform_device *pdev) mutex_init(&hdmi->update_plugged_status_lock); platform_set_drvdata(pdev, hdmi); - ret = mtk_hdmi_output_init(hdmi); - if (ret) - return dev_err_probe(dev, ret, - "Failed to initialize hdmi output\n"); - ret = mtk_hdmi_register_audio_driver(dev); if (ret) return dev_err_probe(dev, ret, @@ -1790,28 +1737,9 @@ static struct platform_driver mtk_hdmi_driver = { .pm = &mtk_hdmi_pm_ops, }, }; - -static struct platform_driver * const mtk_hdmi_drivers[] = { - &mtk_hdmi_ddc_driver, - &mtk_cec_driver, - &mtk_hdmi_driver, -}; - -static int __init mtk_hdmitx_init(void) -{ - return platform_register_drivers(mtk_hdmi_drivers, - ARRAY_SIZE(mtk_hdmi_drivers)); -} - -static void __exit mtk_hdmitx_exit(void) -{ - platform_unregister_drivers(mtk_hdmi_drivers, - ARRAY_SIZE(mtk_hdmi_drivers)); -} - -module_init(mtk_hdmitx_init); -module_exit(mtk_hdmitx_exit); +module_platform_driver(mtk_hdmi_driver); MODULE_AUTHOR("Jie Qiu <jie.qiu@mediatek.com>"); MODULE_DESCRIPTION("MediaTek HDMI Driver"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS("DRM_MTK_HDMI_V1"); diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.h b/drivers/gpu/drm/mediatek/mtk_hdmi.h deleted file mode 100644 index 472bf141c92b..000000000000 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2014 MediaTek Inc. - * Author: Jie Qiu <jie.qiu@mediatek.com> - */ -#ifndef _MTK_HDMI_CTRL_H -#define _MTK_HDMI_CTRL_H - -struct platform_driver; - -extern struct platform_driver mtk_cec_driver; -extern struct platform_driver mtk_hdmi_ddc_driver; - -#endif /* _MTK_HDMI_CTRL_H */ diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c index 07db68067844..6358e1af69b4 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c @@ -20,7 +20,6 @@ #include <linux/of_platform.h> #include "mtk_drm_drv.h" -#include "mtk_hdmi.h" #define SIF1_CLOK (288) #define DDC_DDCMCTL0 (0x0) @@ -337,6 +336,7 @@ struct platform_driver mtk_hdmi_ddc_driver = { .of_match_table = mtk_hdmi_ddc_match, }, }; +module_platform_driver(mtk_hdmi_ddc_driver); MODULE_AUTHOR("Jie Qiu <jie.qiu@mediatek.com>"); MODULE_DESCRIPTION("MediaTek HDMI DDC Driver"); 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; diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index 7b863355c5c6..385d24530d1e 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -2,6 +2,7 @@ ccflags-y += -I $(src)/include ccflags-y += -I $(src)/include/nvkm ccflags-y += -I $(src)/nvkm +ccflags-y += -I $(src)/nvkm/subdev/gsp ccflags-y += -I $(src) # NVKM - HW resource manager @@ -68,5 +69,6 @@ nouveau-y += nv17_fence.o nouveau-y += nv50_fence.o nouveau-y += nv84_fence.o nouveau-y += nvc0_fence.o +nouveau-y += gv100_fence.o obj-$(CONFIG_DRM_NOUVEAU) += nouveau.o diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 67146f1e8482..c063756eaea3 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -768,9 +768,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc) disp->image[nv_crtc->index] = NULL; } - nouveau_bo_unmap(nv_crtc->cursor.nvbo); - nouveau_bo_unpin(nv_crtc->cursor.nvbo); - nouveau_bo_fini(nv_crtc->cursor.nvbo); + nouveau_bo_unpin_del(&nv_crtc->cursor.nvbo); nvif_event_dtor(&nv_crtc->vblank); nvif_head_dtor(&nv_crtc->head); kfree(nv_crtc); @@ -1303,6 +1301,7 @@ nv04_crtc_vblank_handler(struct nvif_event *event, void *repv, u32 repc) int nv04_crtc_create(struct drm_device *dev, int crtc_num) { + struct nouveau_cli *cli = &nouveau_drm(dev)->client; struct nouveau_display *disp = nouveau_display(dev); struct nouveau_crtc *nv_crtc; struct drm_plane *primary; @@ -1336,20 +1335,9 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs); drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); - ret = nouveau_bo_new(&nouveau_drm(dev)->client, 64*64*4, 0x100, - NOUVEAU_GEM_DOMAIN_VRAM, 0, 0x0000, NULL, NULL, - &nv_crtc->cursor.nvbo); - if (!ret) { - ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, - NOUVEAU_GEM_DOMAIN_VRAM, false); - if (!ret) { - ret = nouveau_bo_map(nv_crtc->cursor.nvbo); - if (ret) - nouveau_bo_unpin(nv_crtc->cursor.nvbo); - } - if (ret) - nouveau_bo_fini(nv_crtc->cursor.nvbo); - } + ret = nouveau_bo_new_map(cli, NOUVEAU_GEM_DOMAIN_VRAM, 64 * 64 * 4, &nv_crtc->cursor.nvbo); + if (ret) + return ret; nv04_cursor_init(nv_crtc); diff --git a/drivers/gpu/drm/nouveau/dispnv50/Kbuild b/drivers/gpu/drm/nouveau/dispnv50/Kbuild index 28be2912ff74..d5049dee4b8c 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/Kbuild +++ b/drivers/gpu/drm/nouveau/dispnv50/Kbuild @@ -9,11 +9,13 @@ nouveau-y += dispnv50/core907d.o nouveau-y += dispnv50/core917d.o nouveau-y += dispnv50/corec37d.o nouveau-y += dispnv50/corec57d.o +nouveau-y += dispnv50/coreca7d.o nouveau-$(CONFIG_DEBUG_FS) += dispnv50/crc.o nouveau-$(CONFIG_DEBUG_FS) += dispnv50/crc907d.o nouveau-$(CONFIG_DEBUG_FS) += dispnv50/crcc37d.o nouveau-$(CONFIG_DEBUG_FS) += dispnv50/crcc57d.o +nouveau-$(CONFIG_DEBUG_FS) += dispnv50/crcca7d.o nouveau-y += dispnv50/dac507d.o nouveau-y += dispnv50/dac907d.o @@ -31,6 +33,7 @@ nouveau-y += dispnv50/head907d.o nouveau-y += dispnv50/head917d.o nouveau-y += dispnv50/headc37d.o nouveau-y += dispnv50/headc57d.o +nouveau-y += dispnv50/headca7d.o nouveau-y += dispnv50/wimm.o nouveau-y += dispnv50/wimmc37b.o @@ -39,6 +42,7 @@ nouveau-y += dispnv50/wndw.o nouveau-y += dispnv50/wndwc37e.o nouveau-y += dispnv50/wndwc57e.o nouveau-y += dispnv50/wndwc67e.o +nouveau-y += dispnv50/wndwca7e.o nouveau-y += dispnv50/base.o nouveau-y += dispnv50/base507c.o diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.c b/drivers/gpu/drm/nouveau/dispnv50/core.c index f045515696cb..c6331bf97582 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core.c @@ -42,6 +42,7 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore) int version; int (*new)(struct nouveau_drm *, s32, struct nv50_core **); } cores[] = { + { GB202_DISP_CORE_CHANNEL_DMA, 0, coreca7d_new }, { AD102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, { GA102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, { TU102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, diff --git a/drivers/gpu/drm/nouveau/dispnv50/core.h b/drivers/gpu/drm/nouveau/dispnv50/core.h index f75088186fba..aa07a3ad5dfd 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core.h +++ b/drivers/gpu/drm/nouveau/dispnv50/core.h @@ -7,7 +7,10 @@ struct nv50_core { const struct nv50_core_func *func; + struct nv50_disp *disp; + struct nv50_dmac chan; + bool assign_windows; }; @@ -18,6 +21,7 @@ struct nv50_core_func { int (*init)(struct nv50_core *); void (*ntfy_init)(struct nouveau_bo *, u32 offset); int (*caps_init)(struct nouveau_drm *, struct nv50_disp *); + u32 caps_class; int (*ntfy_wait_done)(struct nouveau_bo *, u32 offset, struct nvif_device *); int (*update)(struct nv50_core *, u32 *interlock, bool ntfy); @@ -70,4 +74,6 @@ int corec37d_wndw_owner(struct nv50_core *); extern const struct nv50_outp_func sorc37d; int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **); + +int coreca7d_new(struct nouveau_drm *, s32, struct nv50_core **); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c b/drivers/gpu/drm/nouveau/dispnv50/core507d.c index ce2cb78bbdd3..4b947b67a844 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c @@ -165,6 +165,7 @@ core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm, if (!(core = *pcore = kzalloc(sizeof(*core), GFP_KERNEL))) return -ENOMEM; core->func = func; + core->disp = disp; ret = nv50_dmac_create(drm, &oclass, 0, &args, sizeof(args), diff --git a/drivers/gpu/drm/nouveau/dispnv50/corec37d.c b/drivers/gpu/drm/nouveau/dispnv50/corec37d.c index 7f637b8830be..83eec2f091f0 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/corec37d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/corec37d.c @@ -105,7 +105,7 @@ int corec37d_caps_init(struct nouveau_drm *drm, struct nv50_disp *disp) int ret; ret = nvif_object_ctor(&disp->disp->object, "dispCaps", 0, - GV100_DISP_CAPS, NULL, 0, &disp->caps); + disp->core->func->caps_class, NULL, 0, &disp->caps); if (ret) { NV_ERROR(drm, "Failed to init notifier caps region: %d\n", @@ -162,6 +162,7 @@ corec37d = { .init = corec37d_init, .ntfy_init = corec37d_ntfy_init, .caps_init = corec37d_caps_init, + .caps_class = GV100_DISP_CAPS, .ntfy_wait_done = corec37d_ntfy_wait_done, .update = corec37d_update, .wndw.owner = corec37d_wndw_owner, diff --git a/drivers/gpu/drm/nouveau/dispnv50/corec57d.c b/drivers/gpu/drm/nouveau/dispnv50/corec57d.c index 421d0d57e1d8..39be576eadcb 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/corec57d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/corec57d.c @@ -22,6 +22,7 @@ #include "core.h" #include "head.h" +#include <nvif/class.h> #include <nvif/pushc37b.h> #include <nvhw/class/clc57d.h> @@ -63,6 +64,7 @@ corec57d = { .init = corec57d_init, .ntfy_init = corec37d_ntfy_init, .caps_init = corec37d_caps_init, + .caps_class = GV100_DISP_CAPS, .ntfy_wait_done = corec37d_ntfy_wait_done, .update = corec37d_update, .wndw.owner = corec37d_wndw_owner, diff --git a/drivers/gpu/drm/nouveau/dispnv50/coreca7d.c b/drivers/gpu/drm/nouveau/dispnv50/coreca7d.c new file mode 100644 index 000000000000..171727be400e --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/coreca7d.c @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "core.h" +#include "head.h" + +#include <nvif/class.h> +#include <nvif/pushc97b.h> + +#include <nvhw/class/clca7d.h> + +#include <nouveau_bo.h> + +static int +coreca7d_update(struct nv50_core *core, u32 *interlock, bool ntfy) +{ + const u64 ntfy_addr = core->disp->sync->offset + NV50_DISP_CORE_NTFY; + const u32 ntfy_hi = upper_32_bits(ntfy_addr); + const u32 ntfy_lo = lower_32_bits(ntfy_addr); + struct nvif_push *push = &core->chan.push; + int ret; + + ret = PUSH_WAIT(push, 5 + (ntfy ? 5 + 2 : 0)); + if (ret) + return ret; + + if (ntfy) { + PUSH_MTHD(push, NVCA7D, SET_SURFACE_ADDRESS_HI_NOTIFIER, ntfy_hi, + + SET_SURFACE_ADDRESS_LO_NOTIFIER, + NVVAL(NVCA7D, SET_SURFACE_ADDRESS_LO_NOTIFIER, ADDRESS_LO, ntfy_lo >> 4) | + NVDEF(NVCA7D, SET_SURFACE_ADDRESS_LO_NOTIFIER, TARGET, PHYSICAL_NVM) | + NVDEF(NVCA7D, SET_SURFACE_ADDRESS_LO_NOTIFIER, ENABLE, ENABLE)); + + PUSH_MTHD(push, NVCA7D, SET_NOTIFIER_CONTROL, + NVDEF(NVCA7D, SET_NOTIFIER_CONTROL, MODE, WRITE) | + NVDEF(NVCA7D, SET_NOTIFIER_CONTROL, NOTIFY, ENABLE)); + } + + PUSH_MTHD(push, NVCA7D, SET_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_CURS], + SET_WINDOW_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_WNDW]); + + PUSH_MTHD(push, NVCA7D, UPDATE, + NVDEF(NVCA7D, UPDATE, RELEASE_ELV, TRUE) | + NVDEF(NVCA7D, UPDATE, SPECIAL_HANDLING, NONE) | + NVDEF(NVCA7D, UPDATE, INHIBIT_INTERRUPTS, FALSE)); + + if (ntfy) { + PUSH_MTHD(push, NVCA7D, SET_NOTIFIER_CONTROL, + NVDEF(NVCA7D, SET_NOTIFIER_CONTROL, NOTIFY, DISABLE)); + } + + return PUSH_KICK(push); +} + +static int +coreca7d_init(struct nv50_core *core) +{ + struct nvif_push *push = &core->chan.push; + const u32 windows = 8, heads = 4; + int ret, i; + + ret = PUSH_WAIT(push, windows * 6 + heads * 6); + if (ret) + return ret; + + for (i = 0; i < windows; i++) { + PUSH_MTHD(push, NVCA7D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS(i), + NVDEF(NVCA7D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED1BPP, TRUE) | + NVDEF(NVCA7D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED2BPP, TRUE) | + NVDEF(NVCA7D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED4BPP, TRUE) | + NVDEF(NVCA7D, WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS, RGB_PACKED8BPP, TRUE), + + WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS(i), 0x00000000); + + PUSH_MTHD(push, NVCA7D, WINDOW_SET_WINDOW_USAGE_BOUNDS(i), + NVVAL(NVCA7D, WINDOW_SET_WINDOW_USAGE_BOUNDS, MAX_PIXELS_FETCHED_PER_LINE, 0x7fff) | + NVDEF(NVCA7D, WINDOW_SET_WINDOW_USAGE_BOUNDS, ILUT_ALLOWED, TRUE) | + NVDEF(NVCA7D, WINDOW_SET_WINDOW_USAGE_BOUNDS, INPUT_SCALER_TAPS, TAPS_2) | + NVDEF(NVCA7D, WINDOW_SET_WINDOW_USAGE_BOUNDS, UPSCALING_ALLOWED, FALSE), + + WINDOW_SET_PHYSICAL(i), BIT(i)); + } + + for (i = 0; i < heads; i++) { + PUSH_MTHD(push, NVCA7D, HEAD_SET_HEAD_USAGE_BOUNDS(i), + NVDEF(NVCA7D, HEAD_SET_HEAD_USAGE_BOUNDS, CURSOR, USAGE_W256_H256) | + NVDEF(NVCA7D, HEAD_SET_HEAD_USAGE_BOUNDS, OLUT_ALLOWED, TRUE) | + NVDEF(NVCA7D, HEAD_SET_HEAD_USAGE_BOUNDS, OUTPUT_SCALER_TAPS, TAPS_2) | + NVDEF(NVCA7D, HEAD_SET_HEAD_USAGE_BOUNDS, UPSCALING_ALLOWED, TRUE)); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_TILE_MASK(i), BIT(i)); + + PUSH_MTHD(push, NVCA7D, TILE_SET_TILE_SIZE(i), 0); + } + + core->assign_windows = true; + return PUSH_KICK(push); +} + +static const struct nv50_core_func +coreca7d = { + .init = coreca7d_init, + .ntfy_init = corec37d_ntfy_init, + .caps_init = corec37d_caps_init, + .caps_class = GB202_DISP_CAPS, + .ntfy_wait_done = corec37d_ntfy_wait_done, + .update = coreca7d_update, + .wndw.owner = corec37d_wndw_owner, + .head = &headca7d, + .sor = &sorc37d, +#if IS_ENABLED(CONFIG_DEBUG_FS) + .crc = &crcca7d, +#endif +}; + +int +coreca7d_new(struct nouveau_drm *drm, s32 oclass, struct nv50_core **pcore) +{ + return core507d_new_(&coreca7d, drm, oclass, pcore); +} diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.c b/drivers/gpu/drm/nouveau/dispnv50/crc.c index 5936b6b3b15d..deb6af40ef32 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/crc.c +++ b/drivers/gpu/drm/nouveau/dispnv50/crc.c @@ -509,6 +509,10 @@ nv50_crc_ctx_init(struct nv50_head *head, struct nvif_mmu *mmu, if (ret) return ret; + /* No CTXDMAs on Blackwell. */ + if (core->chan.base.user.oclass >= GB202_DISP_CORE_CHANNEL_DMA) + return 0; + ret = nvif_object_ctor(&core->chan.base.user, "kmsCrcNtfyCtxDma", NV50_DISP_HANDLE_CRC_CTX(head, idx), NV_DMA_IN_MEMORY, diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.h b/drivers/gpu/drm/nouveau/dispnv50/crc.h index 4823f1fde2dd..75a2009e8193 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/crc.h +++ b/drivers/gpu/drm/nouveau/dispnv50/crc.h @@ -94,6 +94,7 @@ void nv50_crc_atomic_clr(struct nv50_head *); extern const struct nv50_crc_func crc907d; extern const struct nv50_crc_func crcc37d; extern const struct nv50_crc_func crcc57d; +extern const struct nv50_crc_func crcca7d; #else /* IS_ENABLED(CONFIG_DEBUG_FS) */ struct nv50_crc {}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/crcca7d.c b/drivers/gpu/drm/nouveau/dispnv50/crcca7d.c new file mode 100644 index 000000000000..912f59aebe87 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/crcca7d.c @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "crcc37d.h" +#include "core.h" +#include "head.h" + +#include <nvif/pushc97b.h> + +#include <nvhw/class/clca7d.h> + +static int +crcca7d_set_ctx(struct nv50_head *head, struct nv50_crc_notifier_ctx *ctx) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, ctx ? 3 : 2); + if (ret) + return ret; + + if (ctx) { + const u32 crc_hi = upper_32_bits(ctx->mem.addr); + const u32 crc_lo = lower_32_bits(ctx->mem.addr); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_SURFACE_ADDRESS_HI_CRC(i), crc_hi, + + HEAD_SET_SURFACE_ADDRESS_LO_CRC(i), + NVVAL(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CRC, ADDRESS_LO, crc_lo >> 4) | + NVDEF(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CRC, TARGET, PHYSICAL_NVM) | + NVDEF(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CRC, ENABLE, ENABLE)); + } else { + PUSH_MTHD(push, NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CRC(i), + NVDEF(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CRC, ENABLE, DISABLE)); + } + + return 0; +} + +static int +crcca7d_set_src(struct nv50_head *head, int or, enum nv50_crc_source_type source, + struct nv50_crc_notifier_ctx *ctx) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const int i = head->base.index; + int primary_crc, ret; + + if (!source) { + ret = PUSH_WAIT(push, 1); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_CRC_CONTROL(i), 0); + + return crcca7d_set_ctx(head, NULL); + } + + switch (source) { + case NV50_CRC_SOURCE_TYPE_SOR: + primary_crc = NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR(or); + break; + case NV50_CRC_SOURCE_TYPE_SF: + primary_crc = NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SF; + break; + default: + break; + } + + ret = crcca7d_set_ctx(head, ctx); + if (ret) + return ret; + + ret = PUSH_WAIT(push, 2); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_CRC_CONTROL(i), + NVDEF(NVCA7D, HEAD_SET_CRC_CONTROL, CONTROLLING_CHANNEL, CORE) | + NVDEF(NVCA7D, HEAD_SET_CRC_CONTROL, EXPECT_BUFFER_COLLAPSE, FALSE) | + NVVAL(NVCA7D, HEAD_SET_CRC_CONTROL, PRIMARY_CRC, primary_crc) | + NVDEF(NVCA7D, HEAD_SET_CRC_CONTROL, SECONDARY_CRC, NONE) | + NVDEF(NVCA7D, HEAD_SET_CRC_CONTROL, CRC_DURING_SNOOZE, DISABLE)); + + return 0; +} + +const struct nv50_crc_func +crcca7d = { + .set_src = crcca7d_set_src, + .set_ctx = crcca7d_set_ctx, + .get_entry = crcc37d_get_entry, + .ctx_finished = crcc37d_ctx_finished, + .flip_threshold = CRCC37D_FLIP_THRESHOLD, + .num_entries = CRCC37D_MAX_ENTRIES, + .notifier_len = sizeof(struct crcc37d_notifier), +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs.c b/drivers/gpu/drm/nouveau/dispnv50/curs.c index 31d8b2e4791d..557bd05240fa 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs.c @@ -31,6 +31,7 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) int version; int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); } curses[] = { + { GB202_DISP_CURSOR, 0, cursc37a_new }, { GA102_DISP_CURSOR, 0, cursc37a_new }, { TU102_DISP_CURSOR, 0, cursc37a_new }, { GV100_DISP_CURSOR, 0, cursc37a_new }, diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 9bed728cb00e..e5d37eee4301 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -279,6 +279,16 @@ nv50_dmac_create(struct nouveau_drm *drm, if (syncbuf < 0) return 0; + /* No CTXDMAs on Blackwell. */ + if (disp->oclass >= GB202_DISP) { + /* "handle != NULL_HANDLE" is used to determine enable status + * in a number of places, so fill in some fake object handles. + */ + dmac->sync.handle = NV50_DISP_HANDLE_SYNCBUF; + dmac->vram.handle = NV50_DISP_HANDLE_VRAM; + return 0; + } + ret = nvif_object_ctor(&dmac->base.user, "kmsSyncCtxDma", NV50_DISP_HANDLE_SYNCBUF, NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { @@ -2808,10 +2818,7 @@ nv50_display_destroy(struct drm_device *dev) nvif_object_dtor(&disp->caps); nv50_core_del(&disp->core); - nouveau_bo_unmap(disp->sync); - if (disp->sync) - nouveau_bo_unpin(disp->sync); - nouveau_bo_fini(disp->sync); + nouveau_bo_unpin_del(&disp->sync); nouveau_display(dev)->priv = NULL; kfree(disp); @@ -2843,20 +2850,7 @@ nv50_display_create(struct drm_device *dev) dev->mode_config.normalize_zpos = true; /* small shared memory area we use for notifiers and semaphores */ - ret = nouveau_bo_new(&drm->client, 4096, 0x1000, - NOUVEAU_GEM_DOMAIN_VRAM, - 0, 0x0000, NULL, NULL, &disp->sync); - if (!ret) { - ret = nouveau_bo_pin(disp->sync, NOUVEAU_GEM_DOMAIN_VRAM, true); - if (!ret) { - ret = nouveau_bo_map(disp->sync); - if (ret) - nouveau_bo_unpin(disp->sync); - } - if (ret) - nouveau_bo_fini(disp->sync); - } - + ret = nouveau_bo_new_map(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, PAGE_SIZE, &disp->sync); if (ret) goto out; diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index d7c74cc43ba5..3dd742b4f823 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -577,6 +577,7 @@ nv50_head_create(struct drm_device *dev, int index) return ERR_PTR(-ENOMEM); head->func = disp->core->func->head; + head->disp = disp; head->base.index = index; if (disp->disp->object.oclass < GF110_DISP) diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.h b/drivers/gpu/drm/nouveau/dispnv50/head.h index e9d17037ffcf..8bd2fcb1eff5 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.h +++ b/drivers/gpu/drm/nouveau/dispnv50/head.h @@ -13,6 +13,8 @@ struct nv50_head { const struct nv50_head_func *func; + struct nv50_disp *disp; + struct nouveau_crtc base; struct nv50_crc crc; struct nv50_lut olut; @@ -98,4 +100,7 @@ int headc37d_dither(struct nv50_head *, struct nv50_head_atom *); void headc37d_static_wndw_map(struct nv50_head *, struct nv50_head_atom *); extern const struct nv50_head_func headc57d; +bool headc57d_olut(struct nv50_head *, struct nv50_head_atom *, int size); + +extern const struct nv50_head_func headca7d; #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/headc57d.c b/drivers/gpu/drm/nouveau/dispnv50/headc57d.c index fde4087e7691..3f8ba495de8f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/headc57d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/headc57d.c @@ -182,7 +182,7 @@ headc57d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem) writew(readw(mem - 4), mem + 4); } -static bool +bool headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size) { if (size != 0 && size != 256 && size != 1024) diff --git a/drivers/gpu/drm/nouveau/dispnv50/headca7d.c b/drivers/gpu/drm/nouveau/dispnv50/headca7d.c new file mode 100644 index 000000000000..eeaeb15aa664 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/headca7d.c @@ -0,0 +1,297 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "head.h" +#include "atom.h" +#include "core.h" + +#include <nvif/pushc97b.h> + +#include <nvhw/class/clca7d.h> + +static int +headca7d_display_id(struct nv50_head *head, u32 display_id) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, 2); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_DISPLAY_ID(i, 0), display_id); + + return 0; +} + +static int +headca7d_or(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const int i = head->base.index; + u8 depth; + int ret; + + switch (asyh->or.depth) { + case 6: + depth = NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_30_444; + break; + case 5: + depth = NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_24_444; + break; + case 2: + depth = NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_18_444; + break; + case 0: + depth = NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_24_444; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + ret = PUSH_WAIT(push, 2); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_CONTROL_OUTPUT_RESOURCE(i), + NVVAL(NVCA7D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, CRC_MODE, asyh->or.crc_raster) | + NVVAL(NVCA7D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, HSYNC_POLARITY, asyh->or.nhsync) | + NVVAL(NVCA7D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, VSYNC_POLARITY, asyh->or.nvsync) | + NVVAL(NVCA7D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, PIXEL_DEPTH, depth) | + NVDEF(NVCA7D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, COLOR_SPACE_OVERRIDE, DISABLE) | + NVDEF(NVCA7D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, EXT_PACKET_WIN, NONE)); + + return 0; +} + +static int +headca7d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, 2); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_PROCAMP(i), + NVDEF(NVCA7D, HEAD_SET_PROCAMP, COLOR_SPACE, RGB) | + NVDEF(NVCA7D, HEAD_SET_PROCAMP, CHROMA_LPF, DISABLE) | + NVDEF(NVCA7D, HEAD_SET_PROCAMP, DYNAMIC_RANGE, VESA)); + + return 0; +} + +static int +headca7d_dither(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, 2); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_DITHER_CONTROL(i), + NVVAL(NVCA7D, HEAD_SET_DITHER_CONTROL, ENABLE, asyh->dither.enable) | + NVVAL(NVCA7D, HEAD_SET_DITHER_CONTROL, BITS, asyh->dither.bits) | + NVDEF(NVCA7D, HEAD_SET_DITHER_CONTROL, OFFSET_ENABLE, DISABLE) | + NVVAL(NVCA7D, HEAD_SET_DITHER_CONTROL, MODE, asyh->dither.mode) | + NVVAL(NVCA7D, HEAD_SET_DITHER_CONTROL, PHASE, 0)); + + return 0; +} + +static int +headca7d_curs_clr(struct nv50_head *head) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, 4); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NVCA7D, HEAD_SET_CONTROL_CURSOR, ENABLE, DISABLE) | + NVDEF(NVCA7D, HEAD_SET_CONTROL_CURSOR, FORMAT, A8R8G8B8)); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CURSOR(i, 0), + NVDEF(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CURSOR, ENABLE, DISABLE)); + + return 0; +} + +static int +headca7d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const u32 curs_hi = upper_32_bits(asyh->curs.offset); + const u32 curs_lo = lower_32_bits(asyh->curs.offset); + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, 7); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_SURFACE_ADDRESS_HI_CURSOR(i, 0), curs_hi); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CURSOR(i, 0), + NVVAL(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CURSOR, ADDRESS_LO, curs_lo >> 4) | + NVDEF(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CURSOR, TARGET, PHYSICAL_NVM) | + NVDEF(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_CURSOR, ENABLE, ENABLE)); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_CONTROL_CURSOR(i), + NVDEF(NVCA7D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) | + NVVAL(NVCA7D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) | + NVVAL(NVCA7D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) | + NVVAL(NVCA7D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) | + NVVAL(NVCA7D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0), + + HEAD_SET_CONTROL_CURSOR_COMPOSITION(i), + NVVAL(NVCA7D, HEAD_SET_CONTROL_CURSOR_COMPOSITION, K1, 0xff) | + NVDEF(NVCA7D, HEAD_SET_CONTROL_CURSOR_COMPOSITION, CURSOR_COLOR_FACTOR_SELECT, + K1) | + NVDEF(NVCA7D, HEAD_SET_CONTROL_CURSOR_COMPOSITION, VIEWPORT_COLOR_FACTOR_SELECT, + NEG_K1_TIMES_SRC) | + NVDEF(NVCA7D, HEAD_SET_CONTROL_CURSOR_COMPOSITION, MODE, BLEND)); + + return 0; +} + +static int +headca7d_olut_clr(struct nv50_head *head) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, 2); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_OLUT(i), + NVDEF(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_OLUT, ENABLE, DISABLE)); + + return 0; +} + +static int +headca7d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const u32 olut_hi = upper_32_bits(asyh->olut.offset); + const u32 olut_lo = lower_32_bits(asyh->olut.offset); + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, 6); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_SURFACE_ADDRESS_HI_OLUT(i), olut_hi, + + HEAD_SET_SURFACE_ADDRESS_LO_OLUT(i), + NVVAL(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_OLUT, ADDRESS_LO, olut_lo >> 4) | + NVDEF(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_OLUT, TARGET, PHYSICAL_NVM) | + NVDEF(NVCA7D, HEAD_SET_SURFACE_ADDRESS_LO_OLUT, ENABLE, ENABLE)); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_OLUT_CONTROL(i), + NVVAL(NVCA7D, HEAD_SET_OLUT_CONTROL, INTERPOLATE, asyh->olut.output_mode) | + NVDEF(NVCA7D, HEAD_SET_OLUT_CONTROL, MIRROR, DISABLE) | + NVVAL(NVCA7D, HEAD_SET_OLUT_CONTROL, MODE, asyh->olut.mode) | + NVVAL(NVCA7D, HEAD_SET_OLUT_CONTROL, SIZE, asyh->olut.size), + + HEAD_SET_OLUT_FP_NORM_SCALE(i), 0xffffffff); + + return 0; +} + +static int +headca7d_mode(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nvif_push *push = &head->disp->core->chan.push; + struct nv50_head_mode *m = &asyh->mode; + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, 11); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_RASTER_SIZE(i), + NVVAL(NVCA7D, HEAD_SET_RASTER_SIZE, WIDTH, m->h.active) | + NVVAL(NVCA7D, HEAD_SET_RASTER_SIZE, HEIGHT, m->v.active), + + HEAD_SET_RASTER_SYNC_END(i), + NVVAL(NVCA7D, HEAD_SET_RASTER_SYNC_END, X, m->h.synce) | + NVVAL(NVCA7D, HEAD_SET_RASTER_SYNC_END, Y, m->v.synce), + + HEAD_SET_RASTER_BLANK_END(i), + NVVAL(NVCA7D, HEAD_SET_RASTER_BLANK_END, X, m->h.blanke) | + NVVAL(NVCA7D, HEAD_SET_RASTER_BLANK_END, Y, m->v.blanke), + + HEAD_SET_RASTER_BLANK_START(i), + NVVAL(NVCA7D, HEAD_SET_RASTER_BLANK_START, X, m->h.blanks) | + NVVAL(NVCA7D, HEAD_SET_RASTER_BLANK_START, Y, m->v.blanks)); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_CONTROL(i), + NVDEF(NVCA7D, HEAD_SET_CONTROL, STRUCTURE, PROGRESSIVE)); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY(i), + NVVAL(NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, HERTZ, m->clock * 1000)); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX(i), + NVVAL(NVCA7D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, HERTZ, m->clock * 1000)); + + return 0; +} + +static int +headca7d_view(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + struct nvif_push *push = &head->disp->core->chan.push; + const int i = head->base.index; + int ret; + + ret = PUSH_WAIT(push, 4); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7D, HEAD_SET_VIEWPORT_SIZE_IN(i), + NVVAL(NVCA7D, HEAD_SET_VIEWPORT_SIZE_IN, WIDTH, asyh->view.iW) | + NVVAL(NVCA7D, HEAD_SET_VIEWPORT_SIZE_IN, HEIGHT, asyh->view.iH)); + + PUSH_MTHD(push, NVCA7D, HEAD_SET_VIEWPORT_SIZE_OUT(i), + NVVAL(NVCA7D, HEAD_SET_VIEWPORT_SIZE_OUT, WIDTH, asyh->view.oW) | + NVVAL(NVCA7D, HEAD_SET_VIEWPORT_SIZE_OUT, HEIGHT, asyh->view.oH)); + return 0; +} + +const struct nv50_head_func +headca7d = { + .view = headca7d_view, + .mode = headca7d_mode, + .olut = headc57d_olut, + .ilut_check = head907d_ilut_check, + .olut_identity = true, + .olut_size = 1024, + .olut_set = headca7d_olut_set, + .olut_clr = headca7d_olut_clr, + .curs_layout = head917d_curs_layout, + .curs_format = headc37d_curs_format, + .curs_set = headca7d_curs_set, + .curs_clr = headca7d_curs_clr, + .dither = headca7d_dither, + .procamp = headca7d_procamp, + .or = headca7d_or, + .static_wndw_map = headc37d_static_wndw_map, + .display_id = headca7d_display_id, +}; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wimm.c b/drivers/gpu/drm/nouveau/dispnv50/wimm.c index 566fbddfc8d7..53c9ab6c138b 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wimm.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wimm.c @@ -31,6 +31,7 @@ nv50_wimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw) int version; int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *); } wimms[] = { + { GB202_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, { GA102_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, { TU102_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, { GV100_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index f6be426dd525..11d5b923d6e7 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -556,14 +556,24 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) return ret; if (wndw->ctxdma.parent) { - ctxdma = nv50_wndw_ctxdma_new(wndw, fb); - if (IS_ERR(ctxdma)) { - nouveau_bo_unpin(nvbo); - return PTR_ERR(ctxdma); + if (wndw->wndw.base.user.oclass < GB202_DISP_WINDOW_CHANNEL_DMA) { + ctxdma = nv50_wndw_ctxdma_new(wndw, fb); + if (IS_ERR(ctxdma)) { + nouveau_bo_unpin(nvbo); + return PTR_ERR(ctxdma); + } + + if (asyw->visible) + asyw->image.handle[0] = ctxdma->object.handle; + } else { + /* No CTXDMAs on Blackwell. */ + if (asyw->visible) { + /* "handle != NULL_HANDLE" is used to determine enable status + * in a number of places, so fill in a fake object handle. + */ + asyw->image.handle[0] = NV50_DISP_HANDLE_WNDW_CTX(0); + } } - - if (asyw->visible) - asyw->image.handle[0] = ctxdma->object.handle; } ret = drm_gem_plane_helper_prepare_fb(plane, state); @@ -901,6 +911,7 @@ nv50_wndw_new(struct nouveau_drm *drm, enum drm_plane_type type, int index, int (*new)(struct nouveau_drm *, enum drm_plane_type, int, s32, struct nv50_wndw **); } wndws[] = { + { GB202_DISP_WINDOW_CHANNEL_DMA, 0, wndwca7e_new }, { GA102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc67e_new }, { TU102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc57e_new }, { GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new }, diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index 76a6ae5d5652..90d100514bef 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -134,6 +134,9 @@ int wndwc57e_csc_clr(struct nv50_wndw *); int wndwc67e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, struct nv50_wndw **); +int wndwca7e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, + struct nv50_wndw **); + int nv50_wndw_new(struct nouveau_drm *, enum drm_plane_type, int index, struct nv50_wndw **); #endif diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c index 50a7b97d37a2..554c4f91f8be 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c @@ -25,6 +25,7 @@ #include <drm/drm_atomic_helper.h> #include <nouveau_bo.h> +#include <nvif/class.h> #include <nvif/if0014.h> #include <nvif/pushc37b.h> diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c b/drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c new file mode 100644 index 000000000000..0d8e9a9d1a57 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv50/wndwca7e.c @@ -0,0 +1,209 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "wndw.h" +#include "atom.h" + +#include <nvif/pushc97b.h> + +#include <nvhw/class/clca7e.h> + +#include <nouveau_bo.h> + +static int +wndwca7e_image_clr(struct nv50_wndw *wndw) +{ + struct nvif_push *push = &wndw->wndw.push; + int ret; + + ret = PUSH_WAIT(push, 4); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7E, SET_PRESENT_CONTROL, + NVVAL(NVCA7E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, 0) | + NVDEF(NVCA7E, SET_PRESENT_CONTROL, BEGIN_MODE, NON_TEARING)); + + PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_ISO(0), + NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, ENABLE, DISABLE)); + + return 0; +} + +static int +wndwca7e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + const u32 iso0_hi = upper_32_bits(asyw->image.offset[0]); + const u32 iso0_lo = lower_32_bits(asyw->image.offset[0]); + struct nvif_push *push = &wndw->wndw.push; + int ret, kind; + + if (asyw->image.kind) + kind = NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_KIND_BLOCKLINEAR; + else + kind = NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_KIND_PITCH; + + ret = PUSH_WAIT(push, 17); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_HI_ISO(0), iso0_hi); + + PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_ISO(0), + NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, ADDRESS_LO, iso0_lo >> 4) | + NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, TARGET, PHYSICAL_NVM) | + NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, KIND, kind) | + NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ISO, ENABLE, ENABLE)); + + PUSH_MTHD(push, NVCA7E, SET_PRESENT_CONTROL, + NVVAL(NVCA7E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) | + NVVAL(NVCA7E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) | + NVDEF(NVCA7E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE)); + + PUSH_MTHD(push, NVCA7E, SET_SIZE, + NVVAL(NVCA7E, SET_SIZE, WIDTH, asyw->image.w) | + NVVAL(NVCA7E, SET_SIZE, HEIGHT, asyw->image.h), + + SET_STORAGE, + NVVAL(NVCA7E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh), + + SET_PARAMS, + NVVAL(NVCA7E, SET_PARAMS, FORMAT, asyw->image.format) | + NVDEF(NVCA7E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) | + NVDEF(NVCA7E, SET_PARAMS, SWAP_UV, DISABLE) | + NVDEF(NVCA7E, SET_PARAMS, FMT_ROUNDING_MODE, ROUND_TO_NEAREST), + + SET_PLANAR_STORAGE(0), + NVVAL(NVCA7E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) | + NVVAL(NVCA7E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6)); + + PUSH_MTHD(push, NVCA7E, SET_POINT_IN(0), + NVVAL(NVCA7E, SET_POINT_IN, X, asyw->state.src_x >> 16) | + NVVAL(NVCA7E, SET_POINT_IN, Y, asyw->state.src_y >> 16)); + + PUSH_MTHD(push, NVCA7E, SET_SIZE_IN, + NVVAL(NVCA7E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) | + NVVAL(NVCA7E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16)); + + PUSH_MTHD(push, NVCA7E, SET_SIZE_OUT, + NVVAL(NVCA7E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) | + NVVAL(NVCA7E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h)); + + return 0; +} + +static int +wndwca7e_ilut_clr(struct nv50_wndw *wndw) +{ + struct nvif_push *push = &wndw->wndw.push; + int ret; + + ret = PUSH_WAIT(push, 2); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, + NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, ENABLE, DISABLE)); + + return 0; +} + +static int +wndwca7e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + const u32 ilut_hi = upper_32_bits(asyw->xlut.i.offset); + const u32 ilut_lo = lower_32_bits(asyw->xlut.i.offset); + struct nvif_push *push = &wndw->wndw.push; + int ret; + + ret = PUSH_WAIT(push, 5); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_HI_ILUT, ilut_hi, + + SET_SURFACE_ADDRESS_LO_ILUT, + NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, ADDRESS_LO, ilut_lo >> 4) | + NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, TARGET, PHYSICAL_NVM) | + NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_ILUT, ENABLE, ENABLE)); + + PUSH_MTHD(push, NVCA7E, SET_ILUT_CONTROL, + NVVAL(NVCA7E, SET_ILUT_CONTROL, SIZE, asyw->xlut.i.size) | + NVVAL(NVCA7E, SET_ILUT_CONTROL, MODE, asyw->xlut.i.mode) | + NVVAL(NVCA7E, SET_ILUT_CONTROL, INTERPOLATE, asyw->xlut.i.output_mode)); + + return 0; +} + +static int +wndwca7e_ntfy_clr(struct nv50_wndw *wndw) +{ + struct nvif_push *push = &wndw->wndw.push; + int ret; + + ret = PUSH_WAIT(push, 2); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, + NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, ENABLE, DISABLE)); + + return 0; +} + +static int +wndwca7e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) +{ + struct nv50_disp *disp = nv50_disp(wndw->plane.dev); + const u64 ntfy_addr = disp->sync->offset + asyw->ntfy.offset; + const u32 ntfy_hi = upper_32_bits(ntfy_addr); + const u32 ntfy_lo = lower_32_bits(ntfy_addr); + struct nvif_push *push = &wndw->wndw.push; + int ret; + + ret = PUSH_WAIT(push, 5); + if (ret) + return ret; + + PUSH_MTHD(push, NVCA7E, SET_SURFACE_ADDRESS_HI_NOTIFIER, ntfy_hi, + + SET_SURFACE_ADDRESS_LO_NOTIFIER, + NVVAL(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, ADDRESS_LO, ntfy_lo >> 4) | + NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, TARGET, PHYSICAL_NVM) | + NVDEF(NVCA7E, SET_SURFACE_ADDRESS_LO_NOTIFIER, ENABLE, ENABLE)); + + PUSH_MTHD(push, NVCA7E, SET_NOTIFIER_CONTROL, + NVVAL(NVCA7E, SET_NOTIFIER_CONTROL, MODE, asyw->ntfy.awaken)); + + return 0; +} + +static const struct nv50_wndw_func +wndwca7e = { + .acquire = wndwc37e_acquire, + .release = wndwc37e_release, + .ntfy_set = wndwca7e_ntfy_set, + .ntfy_clr = wndwca7e_ntfy_clr, + .ntfy_reset = corec37d_ntfy_init, + .ntfy_wait_begun = base507c_ntfy_wait_begun, + .ilut = wndwc57e_ilut, + .ilut_identity = true, + .ilut_size = 1024, + .xlut_set = wndwca7e_ilut_set, + .xlut_clr = wndwca7e_ilut_clr, + .csc = base907c_csc, + .csc_set = wndwc57e_csc_set, + .csc_clr = wndwc57e_csc_clr, + .image_set = wndwca7e_image_set, + .image_clr = wndwca7e_image_clr, + .blend_set = wndwc37e_blend_set, + .update = wndwc37e_update, +}; + +int +wndwca7e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index, + s32 oclass, struct nv50_wndw **pwndw) +{ + return wndwc37e_new_(&wndwca7e, drm, type, index, oclass, BIT(index >> 1), pwndw); +} diff --git a/drivers/gpu/drm/nouveau/gv100_fence.c b/drivers/gpu/drm/nouveau/gv100_fence.c new file mode 100644 index 000000000000..cccdeca72002 --- /dev/null +++ b/drivers/gpu/drm/nouveau/gv100_fence.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "nouveau_drv.h" +#include "nouveau_dma.h" +#include "nouveau_fence.h" + +#include "nv50_display.h" + +#include <nvif/push906f.h> + +#include <nvhw/class/clc36f.h> + +static int +gv100_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence) +{ + struct nvif_push *push = &chan->chan.push; + int ret; + + ret = PUSH_WAIT(push, 8); + if (ret) + return ret; + + PUSH_MTHD(push, NVC36F, SEM_ADDR_LO, lower_32_bits(virtual), + SEM_ADDR_HI, upper_32_bits(virtual), + SEM_PAYLOAD_LO, sequence); + + PUSH_MTHD(push, NVC36F, SEM_EXECUTE, + NVDEF(NVC36F, SEM_EXECUTE, OPERATION, RELEASE) | + NVDEF(NVC36F, SEM_EXECUTE, RELEASE_WFI, EN) | + NVDEF(NVC36F, SEM_EXECUTE, PAYLOAD_SIZE, 32BIT) | + NVDEF(NVC36F, SEM_EXECUTE, RELEASE_TIMESTAMP, DIS)); + + PUSH_MTHD(push, NVC36F, NON_STALL_INTERRUPT, 0); + + PUSH_KICK(push); + return 0; +} + +static int +gv100_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence) +{ + struct nvif_push *push = &chan->chan.push; + int ret; + + ret = PUSH_WAIT(push, 6); + if (ret) + return ret; + + PUSH_MTHD(push, NVC36F, SEM_ADDR_LO, lower_32_bits(virtual), + SEM_ADDR_HI, upper_32_bits(virtual), + SEM_PAYLOAD_LO, sequence); + + PUSH_MTHD(push, NVC36F, SEM_EXECUTE, + NVDEF(NVC36F, SEM_EXECUTE, OPERATION, ACQ_CIRC_GEQ) | + NVDEF(NVC36F, SEM_EXECUTE, ACQUIRE_SWITCH_TSG, EN) | + NVDEF(NVC36F, SEM_EXECUTE, PAYLOAD_SIZE, 32BIT)); + + PUSH_KICK(push); + return 0; +} + +static int +gv100_fence_context_new(struct nouveau_channel *chan) +{ + struct nv84_fence_chan *fctx; + int ret; + + ret = nv84_fence_context_new(chan); + if (ret) + return ret; + + fctx = chan->fence; + fctx->base.emit32 = gv100_fence_emit32; + fctx->base.sync32 = gv100_fence_sync32; + return 0; +} + +int +gv100_fence_create(struct nouveau_drm *drm) +{ + struct nv84_fence_priv *priv; + int ret; + + ret = nv84_fence_create(drm); + if (ret) + return ret; + + priv = drm->fence; + priv->base.context_new = gv100_fence_context_new; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/include/nvhw/class/clc36f.h b/drivers/gpu/drm/nouveau/include/nvhw/class/clc36f.h new file mode 100644 index 000000000000..8735dda4c8a7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/class/clc36f.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef _clc36f_h_ +#define _clc36f_h_ + +#define NVC36F_NON_STALL_INTERRUPT (0x00000020) +#define NVC36F_NON_STALL_INTERRUPT_HANDLE 31:0 +#define NVC36F_SEM_ADDR_LO (0x0000005c) +#define NVC36F_SEM_ADDR_LO_OFFSET 31:2 +#define NVC36F_SEM_ADDR_HI (0x00000060) +#define NVC36F_SEM_ADDR_HI_OFFSET 7:0 +#define NVC36F_SEM_PAYLOAD_LO (0x00000064) +#define NVC36F_SEM_PAYLOAD_LO_PAYLOAD 31:0 +#define NVC36F_SEM_PAYLOAD_HI (0x00000068) +#define NVC36F_SEM_PAYLOAD_HI_PAYLOAD 31:0 +#define NVC36F_SEM_EXECUTE (0x0000006c) +#define NVC36F_SEM_EXECUTE_OPERATION 2:0 +#define NVC36F_SEM_EXECUTE_OPERATION_ACQUIRE 0x00000000 +#define NVC36F_SEM_EXECUTE_OPERATION_RELEASE 0x00000001 +#define NVC36F_SEM_EXECUTE_OPERATION_ACQ_STRICT_GEQ 0x00000002 +#define NVC36F_SEM_EXECUTE_OPERATION_ACQ_CIRC_GEQ 0x00000003 +#define NVC36F_SEM_EXECUTE_OPERATION_ACQ_AND 0x00000004 +#define NVC36F_SEM_EXECUTE_OPERATION_ACQ_NOR 0x00000005 +#define NVC36F_SEM_EXECUTE_OPERATION_REDUCTION 0x00000006 +#define NVC36F_SEM_EXECUTE_ACQUIRE_SWITCH_TSG 12:12 +#define NVC36F_SEM_EXECUTE_ACQUIRE_SWITCH_TSG_DIS 0x00000000 +#define NVC36F_SEM_EXECUTE_ACQUIRE_SWITCH_TSG_EN 0x00000001 +#define NVC36F_SEM_EXECUTE_RELEASE_WFI 20:20 +#define NVC36F_SEM_EXECUTE_RELEASE_WFI_DIS 0x00000000 +#define NVC36F_SEM_EXECUTE_RELEASE_WFI_EN 0x00000001 +#define NVC36F_SEM_EXECUTE_PAYLOAD_SIZE 24:24 +#define NVC36F_SEM_EXECUTE_PAYLOAD_SIZE_32BIT 0x00000000 +#define NVC36F_SEM_EXECUTE_PAYLOAD_SIZE_64BIT 0x00000001 +#define NVC36F_SEM_EXECUTE_RELEASE_TIMESTAMP 25:25 +#define NVC36F_SEM_EXECUTE_RELEASE_TIMESTAMP_DIS 0x00000000 +#define NVC36F_SEM_EXECUTE_RELEASE_TIMESTAMP_EN 0x00000001 +#define NVC36F_SEM_EXECUTE_REDUCTION 30:27 +#define NVC36F_SEM_EXECUTE_REDUCTION_IMIN 0x00000000 +#define NVC36F_SEM_EXECUTE_REDUCTION_IMAX 0x00000001 +#define NVC36F_SEM_EXECUTE_REDUCTION_IXOR 0x00000002 +#define NVC36F_SEM_EXECUTE_REDUCTION_IAND 0x00000003 +#define NVC36F_SEM_EXECUTE_REDUCTION_IOR 0x00000004 +#define NVC36F_SEM_EXECUTE_REDUCTION_IADD 0x00000005 +#define NVC36F_SEM_EXECUTE_REDUCTION_INC 0x00000006 +#define NVC36F_SEM_EXECUTE_REDUCTION_DEC 0x00000007 +#define NVC36F_SEM_EXECUTE_REDUCTION_FORMAT 31:31 +#define NVC36F_SEM_EXECUTE_REDUCTION_FORMAT_SIGNED 0x00000000 +#define NVC36F_SEM_EXECUTE_REDUCTION_FORMAT_UNSIGNED 0x00000001 + +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvhw/class/clc97b.h b/drivers/gpu/drm/nouveau/include/nvhw/class/clc97b.h new file mode 100644 index 000000000000..092aebe9551c --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/class/clc97b.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef _clc97b_h_ +#define _clc97b_h_ + +// dma opcode instructions +#define NVC97B_DMA +#define NVC97B_DMA_OPCODE 31:29 +#define NVC97B_DMA_OPCODE_METHOD 0x00000000 +#define NVC97B_DMA_OPCODE_JUMP 0x00000001 +#define NVC97B_DMA_OPCODE_NONINC_METHOD 0x00000002 +#define NVC97B_DMA_OPCODE_SET_SUBDEVICE_MASK 0x00000003 +#define NVC97B_DMA_METHOD_COUNT 27:18 +#define NVC97B_DMA_METHOD_OFFSET 15:2 +#define NVC97B_DMA_DATA 31:0 +#define NVC97B_DMA_DATA_NOP 0x00000000 +#define NVC97B_DMA_JUMP_OFFSET 15:2 +#define NVC97B_DMA_SET_SUBDEVICE_MASK_VALUE 11:0 + +#endif // _clc97b_h diff --git a/drivers/gpu/drm/nouveau/include/nvhw/class/clca7d.h b/drivers/gpu/drm/nouveau/include/nvhw/class/clca7d.h new file mode 100644 index 000000000000..0fec6fc21d44 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/class/clca7d.h @@ -0,0 +1,868 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef _clca7d_h_ +#define _clca7d_h_ + +// class methods +#define NVCA7D_UPDATE (0x00000200) +#define NVCA7D_UPDATE_SPECIAL_HANDLING 21:20 +#define NVCA7D_UPDATE_SPECIAL_HANDLING_NONE (0x00000000) +#define NVCA7D_UPDATE_SPECIAL_HANDLING_INTERRUPT_RM (0x00000001) +#define NVCA7D_UPDATE_SPECIAL_HANDLING_MODE_SWITCH (0x00000002) +#define NVCA7D_UPDATE_SPECIAL_HANDLING_REASON 19:12 +#define NVCA7D_UPDATE_INHIBIT_INTERRUPTS 24:24 +#define NVCA7D_UPDATE_INHIBIT_INTERRUPTS_FALSE (0x00000000) +#define NVCA7D_UPDATE_INHIBIT_INTERRUPTS_TRUE (0x00000001) +#define NVCA7D_UPDATE_RELEASE_ELV 0:0 +#define NVCA7D_UPDATE_RELEASE_ELV_FALSE (0x00000000) +#define NVCA7D_UPDATE_RELEASE_ELV_TRUE (0x00000001) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN 8:4 +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_NONE (0x00000000) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN(i) (0x00000001 +(i)) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN__SIZE_1 16 +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_0 (0x00000001) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_1 (0x00000002) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_2 (0x00000003) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_3 (0x00000004) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_4 (0x00000005) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_5 (0x00000006) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_6 (0x00000007) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_7 (0x00000008) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_8 (0x00000009) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_9 (0x0000000A) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_A (0x0000000B) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_B (0x0000000C) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_C (0x0000000D) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_D (0x0000000E) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_E (0x0000000F) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_LOCK_PIN_F (0x00000010) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_FLIP_LOCK_0 (0x00000014) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_FLIP_LOCK_1 (0x00000015) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_FLIP_LOCK_2 (0x00000016) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_FLIP_LOCK_3 (0x00000017) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_SCAN_LOCK(i) (0x00000018 +(i)) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_SCAN_LOCK__SIZE_1 8 +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_SCAN_LOCK_0 (0x00000018) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_SCAN_LOCK_1 (0x00000019) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_SCAN_LOCK_2 (0x0000001A) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_SCAN_LOCK_3 (0x0000001B) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_SCAN_LOCK_4 (0x0000001C) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_SCAN_LOCK_5 (0x0000001D) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_SCAN_LOCK_6 (0x0000001E) +#define NVCA7D_UPDATE_FLIP_LOCK_PIN_INTERNAL_SCAN_LOCK_7 (0x0000001F) +#define NVCA7D_UPDATE_FORCE_FULLSCREEN 28:28 +#define NVCA7D_UPDATE_FORCE_FULLSCREEN_FALSE (0x00000000) +#define NVCA7D_UPDATE_FORCE_FULLSCREEN_TRUE (0x00000001) +#define NVCA7D_SET_NOTIFIER_CONTROL (0x0000020C) +#define NVCA7D_SET_NOTIFIER_CONTROL_MODE 0:0 +#define NVCA7D_SET_NOTIFIER_CONTROL_MODE_WRITE (0x00000000) +#define NVCA7D_SET_NOTIFIER_CONTROL_MODE_WRITE_AWAKEN (0x00000001) +#define NVCA7D_SET_NOTIFIER_CONTROL_NOTIFY 12:12 +#define NVCA7D_SET_NOTIFIER_CONTROL_NOTIFY_DISABLE (0x00000000) +#define NVCA7D_SET_NOTIFIER_CONTROL_NOTIFY_ENABLE (0x00000001) +#define NVCA7D_SET_INTERLOCK_FLAGS (0x00000218) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR(i) ((i)+0):((i)+0) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR__SIZE_1 8 +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR_DISABLE (0x00000000) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR_ENABLE (0x00000001) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR0 0:0 +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR0_DISABLE (0x00000000) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR0_ENABLE (0x00000001) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR1 1:1 +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR1_DISABLE (0x00000000) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR1_ENABLE (0x00000001) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR2 2:2 +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR2_DISABLE (0x00000000) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR2_ENABLE (0x00000001) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR3 3:3 +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR3_DISABLE (0x00000000) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR3_ENABLE (0x00000001) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR4 4:4 +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR4_DISABLE (0x00000000) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR4_ENABLE (0x00000001) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR5 5:5 +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR5_DISABLE (0x00000000) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR5_ENABLE (0x00000001) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR6 6:6 +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR6_DISABLE (0x00000000) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR6_ENABLE (0x00000001) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR7 7:7 +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR7_DISABLE (0x00000000) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CURSOR7_ENABLE (0x00000001) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CORE 16:16 +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CORE_DISABLE (0x00000000) +#define NVCA7D_SET_INTERLOCK_FLAGS_INTERLOCK_WITH_CORE_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS (0x0000021C) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW(i) ((i)+0):((i)+0) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW__SIZE_1 32 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW0 0:0 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW0_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW0_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW1 1:1 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW1_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW1_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW2 2:2 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW2_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW2_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW3 3:3 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW3_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW3_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW4 4:4 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW4_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW4_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW5 5:5 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW5_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW5_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW6 6:6 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW6_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW6_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW7 7:7 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW7_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW7_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW8 8:8 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW8_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW8_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW9 9:9 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW9_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW9_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW10 10:10 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW10_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW10_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW11 11:11 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW11_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW11_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW12 12:12 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW12_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW12_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW13 13:13 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW13_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW13_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW14 14:14 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW14_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW14_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW15 15:15 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW15_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW15_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW16 16:16 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW16_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW16_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW17 17:17 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW17_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW17_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW18 18:18 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW18_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW18_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW19 19:19 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW19_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW19_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW20 20:20 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW20_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW20_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW21 21:21 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW21_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW21_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW22 22:22 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW22_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW22_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW23 23:23 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW23_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW23_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW24 24:24 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW24_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW24_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW25 25:25 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW25_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW25_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW26 26:26 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW26_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW26_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW27 27:27 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW27_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW27_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW28 28:28 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW28_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW28_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW29 29:29 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW29_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW29_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW30 30:30 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW30_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW30_ENABLE (0x00000001) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW31 31:31 +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW31_DISABLE (0x00000000) +#define NVCA7D_SET_WINDOW_INTERLOCK_FLAGS_INTERLOCK_WITH_WINDOW31_ENABLE (0x00000001) +#define NVCA7D_SET_SURFACE_ADDRESS_HI_NOTIFIER (0x00000260) +#define NVCA7D_SET_SURFACE_ADDRESS_HI_NOTIFIER_ADDRESS_HI 31:0 +#define NVCA7D_SET_SURFACE_ADDRESS_LO_NOTIFIER (0x00000264) +#define NVCA7D_SET_SURFACE_ADDRESS_LO_NOTIFIER_ADDRESS_LO 31:4 +#define NVCA7D_SET_SURFACE_ADDRESS_LO_NOTIFIER_TARGET 3:2 +#define NVCA7D_SET_SURFACE_ADDRESS_LO_NOTIFIER_TARGET_IOVA (0x00000000) +#define NVCA7D_SET_SURFACE_ADDRESS_LO_NOTIFIER_TARGET_PHYSICAL_NVM (0x00000001) +#define NVCA7D_SET_SURFACE_ADDRESS_LO_NOTIFIER_TARGET_PHYSICAL_PCI (0x00000002) +#define NVCA7D_SET_SURFACE_ADDRESS_LO_NOTIFIER_TARGET_PHYSICAL_PCI_COHERENT (0x00000003) +#define NVCA7D_SET_SURFACE_ADDRESS_LO_NOTIFIER_ENABLE 0:0 +#define NVCA7D_SET_SURFACE_ADDRESS_LO_NOTIFIER_ENABLE_DISABLE (0x00000000) +#define NVCA7D_SET_SURFACE_ADDRESS_LO_NOTIFIER_ENABLE_ENABLE (0x00000001) + +#define NVCA7D_SOR_SET_CONTROL(a) (0x00000300 + (a)*0x00000020) +#define NVCA7D_SOR_SET_CONTROL_OWNER_MASK 7:0 +#define NVCA7D_SOR_SET_CONTROL_OWNER_MASK_NONE (0x00000000) +#define NVCA7D_SOR_SET_CONTROL_OWNER_MASK_HEAD0 (0x00000001) +#define NVCA7D_SOR_SET_CONTROL_OWNER_MASK_HEAD1 (0x00000002) +#define NVCA7D_SOR_SET_CONTROL_OWNER_MASK_HEAD2 (0x00000004) +#define NVCA7D_SOR_SET_CONTROL_OWNER_MASK_HEAD3 (0x00000008) +#define NVCA7D_SOR_SET_CONTROL_OWNER_MASK_HEAD4 (0x00000010) +#define NVCA7D_SOR_SET_CONTROL_OWNER_MASK_HEAD5 (0x00000020) +#define NVCA7D_SOR_SET_CONTROL_OWNER_MASK_HEAD6 (0x00000040) +#define NVCA7D_SOR_SET_CONTROL_OWNER_MASK_HEAD7 (0x00000080) +#define NVCA7D_SOR_SET_CONTROL_PROTOCOL 11:8 +#define NVCA7D_SOR_SET_CONTROL_PROTOCOL_LVDS_CUSTOM (0x00000000) +#define NVCA7D_SOR_SET_CONTROL_PROTOCOL_SINGLE_TMDS_A (0x00000001) +#define NVCA7D_SOR_SET_CONTROL_PROTOCOL_SINGLE_TMDS_B (0x00000002) +#define NVCA7D_SOR_SET_CONTROL_PROTOCOL_DUAL_TMDS (0x00000005) +#define NVCA7D_SOR_SET_CONTROL_PROTOCOL_DP_A (0x00000008) +#define NVCA7D_SOR_SET_CONTROL_PROTOCOL_DP_B (0x00000009) +#define NVCA7D_SOR_SET_CONTROL_PROTOCOL_HDMI_FRL (0x0000000C) +#define NVCA7D_SOR_SET_CONTROL_PROTOCOL_CUSTOM (0x0000000F) +#define NVCA7D_SOR_SET_CONTROL_DE_SYNC_POLARITY 16:16 +#define NVCA7D_SOR_SET_CONTROL_DE_SYNC_POLARITY_POSITIVE_TRUE (0x00000000) +#define NVCA7D_SOR_SET_CONTROL_DE_SYNC_POLARITY_NEGATIVE_TRUE (0x00000001) +#define NVCA7D_SOR_SET_CONTROL_PIXEL_REPLICATE_MODE 21:20 +#define NVCA7D_SOR_SET_CONTROL_PIXEL_REPLICATE_MODE_OFF (0x00000000) +#define NVCA7D_SOR_SET_CONTROL_PIXEL_REPLICATE_MODE_X2 (0x00000001) +#define NVCA7D_SOR_SET_CONTROL_PIXEL_REPLICATE_MODE_X4 (0x00000002) + +#define NVCA7D_WINDOW_SET_CONTROL(a) (0x00001000 + (a)*0x00000080) +#define NVCA7D_WINDOW_SET_CONTROL_OWNER 3:0 +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_HEAD(i) (0x00000000 +(i)) +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_HEAD__SIZE_1 8 +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_HEAD0 (0x00000000) +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_HEAD1 (0x00000001) +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_HEAD2 (0x00000002) +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_HEAD3 (0x00000003) +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_HEAD4 (0x00000004) +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_HEAD5 (0x00000005) +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_HEAD6 (0x00000006) +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_HEAD7 (0x00000007) +#define NVCA7D_WINDOW_SET_CONTROL_OWNER_NONE (0x0000000F) +#define NVCA7D_WINDOW_SET_CONTROL_HIDE 8:8 +#define NVCA7D_WINDOW_SET_CONTROL_HIDE_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_CONTROL_HIDE_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_CONTROL_DISABLE_PHYSICAL_FLIPS 9:9 +#define NVCA7D_WINDOW_SET_CONTROL_DISABLE_PHYSICAL_FLIPS_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_CONTROL_DISABLE_PHYSICAL_FLIPS_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_CONTROL_ALLOW_SUPERFRAME 10:10 +#define NVCA7D_WINDOW_SET_CONTROL_ALLOW_SUPERFRAME_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_CONTROL_ALLOW_SUPERFRAME_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS(a) (0x00001004 + (a)*0x00000080) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED1BPP 0:0 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED1BPP_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED1BPP_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED2BPP 1:1 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED2BPP_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED2BPP_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED4BPP 2:2 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED4BPP_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED4BPP_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED8BPP 3:3 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED8BPP_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_RGB_PACKED8BPP_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_PACKED422 4:4 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_PACKED422_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_PACKED422_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_PLANAR420 5:5 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_PLANAR420_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_PLANAR420_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_PLANAR444 6:6 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_PLANAR444_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_PLANAR444_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR420 7:7 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR420_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR420_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422 8:8 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422R 9:9 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422R_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422R_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR444 10:10 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR444_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR444_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR420 11:11 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR420_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR420_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR444 12:12 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR444_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR444_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR420 13:13 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR420_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR420_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422 14:14 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422R 15:15 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422R_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422R_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR444 16:16 +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR444_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR444_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS(a) (0x00001008 + (a)*0x00000080) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED1BPP 0:0 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED1BPP_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED1BPP_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED2BPP 1:1 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED2BPP_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED2BPP_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED4BPP 2:2 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED4BPP_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED4BPP_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED8BPP 3:3 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED8BPP_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_RGB_PACKED8BPP_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_PACKED422 4:4 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_PACKED422_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_PACKED422_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_PLANAR420 5:5 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_PLANAR420_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_PLANAR420_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_PLANAR444 6:6 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_PLANAR444_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_PLANAR444_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR420 7:7 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR420_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR420_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422 8:8 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422R 9:9 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422R_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR422R_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR444 10:10 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR444_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_YUV_SEMI_PLANAR444_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR420 11:11 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR420_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR420_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR444 12:12 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR444_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_PLANAR444_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR420 13:13 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR420_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR420_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422 14:14 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422R 15:15 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422R_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR422R_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR444 16:16 +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR444_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_ROTATED_FORMAT_USAGE_BOUNDS_EXT_YUV_SEMI_PLANAR444_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS(a) (0x00001010 + (a)*0x00000080) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_MAX_PIXELS_FETCHED_PER_LINE 14:0 +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_ILUT_ALLOWED 16:16 +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_ILUT_ALLOWED_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_ILUT_ALLOWED_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_TMO_LUT_ALLOWED 28:28 +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_TMO_LUT_ALLOWED_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_TMO_LUT_ALLOWED_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_INPUT_SCALER_TAPS 22:20 +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_INPUT_SCALER_TAPS_TAPS_2 (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_INPUT_SCALER_TAPS_TAPS_5 (0x00000004) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_UPSCALING_ALLOWED 24:24 +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_UPSCALING_ALLOWED_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_UPSCALING_ALLOWED_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_OVERFETCH_ENABLED 30:30 +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_OVERFETCH_ENABLED_FALSE (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_OVERFETCH_ENABLED_TRUE (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_LAYOUT 26:25 +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_LAYOUT_PITCH_BLOCKLINEAR (0x00000000) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_LAYOUT_PITCH (0x00000001) +#define NVCA7D_WINDOW_SET_WINDOW_USAGE_BOUNDS_LAYOUT_BLOCKLINEAR (0x00000002) +#define NVCA7D_WINDOW_SET_PHYSICAL(a) (0x00001014 + (a)*0x00000080) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW 31:0 +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_NONE (0x00000000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW0 (0x00000001) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW1 (0x00000002) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW2 (0x00000004) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW3 (0x00000008) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW4 (0x00000010) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW5 (0x00000020) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW6 (0x00000040) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW7 (0x00000080) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW8 (0x00000100) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW9 (0x00000200) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW10 (0x00000400) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW11 (0x00000800) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW12 (0x00001000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW13 (0x00002000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW14 (0x00004000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW15 (0x00008000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW16 (0x00010000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW17 (0x00020000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW18 (0x00040000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW19 (0x00080000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW20 (0x00100000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW21 (0x00200000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW22 (0x00400000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW23 (0x00800000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW24 (0x01000000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW25 (0x02000000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW26 (0x04000000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW27 (0x08000000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW28 (0x10000000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW29 (0x20000000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW30 (0x40000000) +#define NVCA7D_WINDOW_SET_PHYSICAL_WINDOW_WINDOW31 (0x80000000) + +#define NVCA7D_HEAD_SET_PROCAMP(a) (0x00002000 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_PROCAMP_COLOR_SPACE 1:0 +#define NVCA7D_HEAD_SET_PROCAMP_COLOR_SPACE_RGB (0x00000000) +#define NVCA7D_HEAD_SET_PROCAMP_COLOR_SPACE_YUV_601 (0x00000001) +#define NVCA7D_HEAD_SET_PROCAMP_COLOR_SPACE_YUV_709 (0x00000002) +#define NVCA7D_HEAD_SET_PROCAMP_COLOR_SPACE_YUV_2020 (0x00000003) +#define NVCA7D_HEAD_SET_PROCAMP_CHROMA_LPF 3:3 +#define NVCA7D_HEAD_SET_PROCAMP_CHROMA_LPF_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_PROCAMP_CHROMA_LPF_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_PROCAMP_CHROMA_DOWN_V 4:4 +#define NVCA7D_HEAD_SET_PROCAMP_CHROMA_DOWN_V_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_PROCAMP_CHROMA_DOWN_V_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_PROCAMP_DYNAMIC_RANGE 28:28 +#define NVCA7D_HEAD_SET_PROCAMP_DYNAMIC_RANGE_VESA (0x00000000) +#define NVCA7D_HEAD_SET_PROCAMP_DYNAMIC_RANGE_CEA (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE(a) (0x00002004 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE 1:0 +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_ACTIVE_RASTER (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_COMPLETE_RASTER (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_NON_ACTIVE_RASTER (0x00000002) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_HSYNC_POLARITY 2:2 +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_HSYNC_POLARITY_POSITIVE_TRUE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_HSYNC_POLARITY_NEGATIVE_TRUE (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_VSYNC_POLARITY 3:3 +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_VSYNC_POLARITY_POSITIVE_TRUE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_VSYNC_POLARITY_NEGATIVE_TRUE (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH 7:4 +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_16_422 (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_18_444 (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_20_422 (0x00000002) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_24_422 (0x00000003) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_24_444 (0x00000004) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_30_444 (0x00000005) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_32_422 (0x00000006) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_36_444 (0x00000007) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_48_444 (0x00000008) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_16_444 (0x00000009) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_PIXEL_DEPTH_BPP_18_444NP (0x0000000A) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_COLOR_SPACE_OVERRIDE 24:24 +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_COLOR_SPACE_OVERRIDE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_COLOR_SPACE_OVERRIDE_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_COLOR_SPACE_FLAG 23:12 +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN 31:26 +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN0 (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN1 (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN2 (0x00000002) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN3 (0x00000003) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN4 (0x00000004) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN5 (0x00000005) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN6 (0x00000006) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN7 (0x00000007) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN8 (0x00000008) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN9 (0x00000009) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN10 (0x0000000A) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN11 (0x0000000B) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN12 (0x0000000C) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN13 (0x0000000D) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN14 (0x0000000E) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN15 (0x0000000F) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN16 (0x00000010) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN17 (0x00000011) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN18 (0x00000012) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN19 (0x00000013) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN20 (0x00000014) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN21 (0x00000015) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN22 (0x00000016) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN23 (0x00000017) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN24 (0x00000018) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN25 (0x00000019) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN26 (0x0000001A) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN27 (0x0000001B) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN28 (0x0000001C) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN29 (0x0000001D) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN30 (0x0000001E) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_WIN31 (0x0000001F) +#define NVCA7D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_EXT_PACKET_WIN_NONE (0x0000003F) +#define NVCA7D_HEAD_SET_CONTROL(a) (0x00002008 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_CONTROL_STRUCTURE 1:0 +#define NVCA7D_HEAD_SET_CONTROL_STRUCTURE_PROGRESSIVE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_STEREO3D_STRUCTURE 2:2 +#define NVCA7D_HEAD_SET_CONTROL_STEREO3D_STRUCTURE_NORMAL (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_STEREO3D_STRUCTURE_FRAME_PACKED (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_YUV420PACKER 3:3 +#define NVCA7D_HEAD_SET_CONTROL_YUV420PACKER_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_YUV420PACKER_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_MODE 11:10 +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_MODE_NO_LOCK (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_MODE_FRAME_LOCK (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_MODE_RASTER_LOCK (0x00000003) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN 8:4 +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_NONE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN(i) (0x00000001 +(i)) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN__SIZE_1 16 +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_0 (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_1 (0x00000002) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_2 (0x00000003) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_3 (0x00000004) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_4 (0x00000005) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_5 (0x00000006) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_6 (0x00000007) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_7 (0x00000008) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_8 (0x00000009) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_9 (0x0000000A) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_A (0x0000000B) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_B (0x0000000C) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_C (0x0000000D) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_D (0x0000000E) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_E (0x0000000F) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_LOCK_PIN_F (0x00000010) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_FLIP_LOCK_0 (0x00000014) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_FLIP_LOCK_1 (0x00000015) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_FLIP_LOCK_2 (0x00000016) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_FLIP_LOCK_3 (0x00000017) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_SCAN_LOCK(i) (0x00000018 +(i)) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_SCAN_LOCK__SIZE_1 8 +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_SCAN_LOCK_0 (0x00000018) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_SCAN_LOCK_1 (0x00000019) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_SCAN_LOCK_2 (0x0000001A) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_SCAN_LOCK_3 (0x0000001B) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_SCAN_LOCK_4 (0x0000001C) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_SCAN_LOCK_5 (0x0000001D) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_SCAN_LOCK_6 (0x0000001E) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCK_PIN_INTERNAL_SCAN_LOCK_7 (0x0000001F) +#define NVCA7D_HEAD_SET_CONTROL_SINK_LOCKOUT_WINDOW 15:12 +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_MODE 23:22 +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_MODE_NO_LOCK (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_MODE_FRAME_LOCK (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_MODE_RASTER_LOCK (0x00000003) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN 20:16 +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_NONE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN(i) (0x00000001 +(i)) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN__SIZE_1 16 +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_0 (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_1 (0x00000002) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_2 (0x00000003) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_3 (0x00000004) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_4 (0x00000005) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_5 (0x00000006) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_6 (0x00000007) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_7 (0x00000008) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_8 (0x00000009) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_9 (0x0000000A) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_A (0x0000000B) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_B (0x0000000C) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_C (0x0000000D) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_D (0x0000000E) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_E (0x0000000F) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_LOCK_PIN_F (0x00000010) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_FLIP_LOCK_0 (0x00000014) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_FLIP_LOCK_1 (0x00000015) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_FLIP_LOCK_2 (0x00000016) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_FLIP_LOCK_3 (0x00000017) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_SCAN_LOCK(i) (0x00000018 +(i)) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_SCAN_LOCK__SIZE_1 8 +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_SCAN_LOCK_0 (0x00000018) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_SCAN_LOCK_1 (0x00000019) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_SCAN_LOCK_2 (0x0000001A) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_SCAN_LOCK_3 (0x0000001B) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_SCAN_LOCK_4 (0x0000001C) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_SCAN_LOCK_5 (0x0000001D) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_SCAN_LOCK_6 (0x0000001E) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_LOCK_PIN_INTERNAL_SCAN_LOCK_7 (0x0000001F) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN 28:24 +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_NONE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN(i) (0x00000001 +(i)) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN__SIZE_1 16 +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_0 (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_1 (0x00000002) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_2 (0x00000003) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_3 (0x00000004) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_4 (0x00000005) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_5 (0x00000006) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_6 (0x00000007) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_7 (0x00000008) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_8 (0x00000009) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_9 (0x0000000A) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_A (0x0000000B) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_B (0x0000000C) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_C (0x0000000D) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_D (0x0000000E) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_E (0x0000000F) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_LOCK_PIN_F (0x00000010) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_FLIP_LOCK_0 (0x00000014) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_FLIP_LOCK_1 (0x00000015) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_FLIP_LOCK_2 (0x00000016) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_FLIP_LOCK_3 (0x00000017) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_SCAN_LOCK(i) (0x00000018 +(i)) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_SCAN_LOCK__SIZE_1 8 +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_SCAN_LOCK_0 (0x00000018) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_SCAN_LOCK_1 (0x00000019) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_SCAN_LOCK_2 (0x0000001A) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_SCAN_LOCK_3 (0x0000001B) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_SCAN_LOCK_4 (0x0000001C) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_SCAN_LOCK_5 (0x0000001D) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_SCAN_LOCK_6 (0x0000001E) +#define NVCA7D_HEAD_SET_CONTROL_STEREO_PIN_INTERNAL_SCAN_LOCK_7 (0x0000001F) +#define NVCA7D_HEAD_SET_CONTROL_SINK_STEREO_LOCK_MODE 30:30 +#define NVCA7D_HEAD_SET_CONTROL_SINK_STEREO_LOCK_MODE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_SINK_STEREO_LOCK_MODE_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_STEREO_LOCK_MODE 31:31 +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_STEREO_LOCK_MODE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_SOURCE_STEREO_LOCK_MODE_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY(a) (0x0000200C + (a)*0x00000800) +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_HERTZ 30:0 +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_ADJ1000DIV1001 31:31 +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_ADJ1000DIV1001_FALSE (0x00000000) +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_ADJ1000DIV1001_TRUE (0x00000001) +#define NVCA7D_HEAD_SET_DITHER_CONTROL(a) (0x00002018 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_ENABLE 0:0 +#define NVCA7D_HEAD_SET_DITHER_CONTROL_ENABLE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_ENABLE_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_BITS 5:4 +#define NVCA7D_HEAD_SET_DITHER_CONTROL_BITS_TO_6_BITS (0x00000000) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_BITS_TO_8_BITS (0x00000001) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_BITS_TO_10_BITS (0x00000002) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_BITS_TO_12_BITS (0x00000003) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_OFFSET_ENABLE 2:2 +#define NVCA7D_HEAD_SET_DITHER_CONTROL_OFFSET_ENABLE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_OFFSET_ENABLE_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_MODE 10:8 +#define NVCA7D_HEAD_SET_DITHER_CONTROL_MODE_DYNAMIC_ERR_ACC (0x00000000) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_MODE_STATIC_ERR_ACC (0x00000001) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_MODE_DYNAMIC_2X2 (0x00000002) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_MODE_STATIC_2X2 (0x00000003) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_MODE_TEMPORAL (0x00000004) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_MODE_ROUND (0x00000005) +#define NVCA7D_HEAD_SET_DITHER_CONTROL_PHASE 13:12 +#define NVCA7D_HEAD_SET_DISPLAY_ID(a,b) (0x00002020 + (a)*0x00000800 + (b)*0x00000004) +#define NVCA7D_HEAD_SET_DISPLAY_ID_CODE 31:0 +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX(a) (0x00002028 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX_HERTZ 30:0 +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX_ADJ1000DIV1001 31:31 +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX_ADJ1000DIV1001_FALSE (0x00000000) +#define NVCA7D_HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX_ADJ1000DIV1001_TRUE (0x00000001) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS(a) (0x00002030 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_CURSOR 2:0 +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_CURSOR_USAGE_NONE (0x00000000) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_CURSOR_USAGE_W32_H32 (0x00000001) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_CURSOR_USAGE_W64_H64 (0x00000002) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_CURSOR_USAGE_W128_H128 (0x00000003) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_CURSOR_USAGE_W256_H256 (0x00000004) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_OLUT_ALLOWED 4:4 +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_OLUT_ALLOWED_FALSE (0x00000000) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_OLUT_ALLOWED_TRUE (0x00000001) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_LTM_ALLOWED 5:5 +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_LTM_ALLOWED_FALSE (0x00000000) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_LTM_ALLOWED_TRUE (0x00000001) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_OUTPUT_SCALER_TAPS 14:12 +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_OUTPUT_SCALER_TAPS_TAPS_2 (0x00000001) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_OUTPUT_SCALER_TAPS_TAPS_5 (0x00000004) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_UPSCALING_ALLOWED 8:8 +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_UPSCALING_ALLOWED_FALSE (0x00000000) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_UPSCALING_ALLOWED_TRUE (0x00000001) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_OVERFETCH_ENABLED 16:16 +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_OVERFETCH_ENABLED_FALSE (0x00000000) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_OVERFETCH_ENABLED_TRUE (0x00000001) +#define NVCA7D_HEAD_SET_HEAD_USAGE_BOUNDS_ELV_START 31:17 +#define NVCA7D_HEAD_SET_VIEWPORT_SIZE_IN(a) (0x0000204C + (a)*0x00000800) +#define NVCA7D_HEAD_SET_VIEWPORT_SIZE_IN_WIDTH 14:0 +#define NVCA7D_HEAD_SET_VIEWPORT_SIZE_IN_HEIGHT 30:16 +#define NVCA7D_HEAD_SET_VIEWPORT_SIZE_OUT(a) (0x00002058 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_VIEWPORT_SIZE_OUT_WIDTH 14:0 +#define NVCA7D_HEAD_SET_VIEWPORT_SIZE_OUT_HEIGHT 30:16 +#define NVCA7D_HEAD_SET_TILE_MASK(a) (0x00002060 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_TILE_MASK_TILE 7:0 +#define NVCA7D_HEAD_SET_TILE_MASK_TILE_NONE (0x00000000) +#define NVCA7D_HEAD_SET_TILE_MASK_TILE_TILE0 (0x00000001) +#define NVCA7D_HEAD_SET_TILE_MASK_TILE_TILE1 (0x00000002) +#define NVCA7D_HEAD_SET_TILE_MASK_TILE_TILE2 (0x00000004) +#define NVCA7D_HEAD_SET_TILE_MASK_TILE_TILE3 (0x00000008) +#define NVCA7D_HEAD_SET_TILE_MASK_TILE_TILE4 (0x00000010) +#define NVCA7D_HEAD_SET_TILE_MASK_TILE_TILE5 (0x00000020) +#define NVCA7D_HEAD_SET_TILE_MASK_TILE_TILE6 (0x00000040) +#define NVCA7D_HEAD_SET_TILE_MASK_TILE_TILE7 (0x00000080) +#define NVCA7D_HEAD_SET_RASTER_SIZE(a) (0x00002064 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_RASTER_SIZE_WIDTH 15:0 +#define NVCA7D_HEAD_SET_RASTER_SIZE_HEIGHT 31:16 +#define NVCA7D_HEAD_SET_RASTER_SYNC_END(a) (0x00002068 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_RASTER_SYNC_END_X 14:0 +#define NVCA7D_HEAD_SET_RASTER_SYNC_END_Y 30:16 +#define NVCA7D_HEAD_SET_RASTER_BLANK_END(a) (0x0000206C + (a)*0x00000800) +#define NVCA7D_HEAD_SET_RASTER_BLANK_END_X 14:0 +#define NVCA7D_HEAD_SET_RASTER_BLANK_END_Y 30:16 +#define NVCA7D_HEAD_SET_RASTER_BLANK_START(a) (0x00002070 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_RASTER_BLANK_START_X 14:0 +#define NVCA7D_HEAD_SET_RASTER_BLANK_START_Y 30:16 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR(a) (0x0000209C + (a)*0x00000800) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_ENABLE 31:31 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_ENABLE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_ENABLE_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_FORMAT 7:0 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_FORMAT_A1R5G5B5 (0x000000E9) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_FORMAT_A8R8G8B8 (0x000000CF) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_SIZE 9:8 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_SIZE_W32_H32 (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_SIZE_W64_H64 (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_SIZE_W128_H128 (0x00000002) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_SIZE_W256_H256 (0x00000003) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_HOT_SPOT_X 19:12 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_HOT_SPOT_Y 27:20 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION(a) (0x000020A0 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_K1 7:0 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_CURSOR_COLOR_FACTOR_SELECT 11:8 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_CURSOR_COLOR_FACTOR_SELECT_K1 (0x00000002) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_CURSOR_COLOR_FACTOR_SELECT_K1_TIMES_SRC (0x00000005) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_VIEWPORT_COLOR_FACTOR_SELECT 15:12 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_VIEWPORT_COLOR_FACTOR_SELECT_ZERO (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_VIEWPORT_COLOR_FACTOR_SELECT_K1 (0x00000002) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_VIEWPORT_COLOR_FACTOR_SELECT_NEG_K1_TIMES_SRC (0x00000007) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_MODE 16:16 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_MODE_BLEND (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_MODE_XOR (0x00000001) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_BYPASS 20:20 +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_BYPASS_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_CONTROL_CURSOR_COMPOSITION_BYPASS_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_HI_CRC(a) (0x00002150 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_HI_CRC_ADDRESS_HI 31:0 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC(a) (0x00002154 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC_ADDRESS_LO 31:4 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC_TARGET 3:2 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC_TARGET_IOVA (0x00000000) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC_TARGET_PHYSICAL_NVM (0x00000001) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC_TARGET_PHYSICAL_PCI (0x00000002) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC_TARGET_PHYSICAL_PCI_COHERENT (0x00000003) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC_ENABLE 0:0 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC_ENABLE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CRC_ENABLE_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_HI_OLUT(a) (0x00002158 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_HI_OLUT_ADDRESS_HI 31:0 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_OLUT(a) (0x0000215C + (a)*0x00000800) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_OLUT_ADDRESS_LO 31:4 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_OLUT_TARGET 3:2 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_OLUT_TARGET_IOVA (0x00000000) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_OLUT_TARGET_PHYSICAL_NVM (0x00000001) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_OLUT_TARGET_PHYSICAL_PCI (0x00000002) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_OLUT_TARGET_PHYSICAL_PCI_COHERENT (0x00000003) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_OLUT_ENABLE 0:0 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_OLUT_ENABLE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_OLUT_ENABLE_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_HI_CURSOR(a,b) (0x00002170 + (a)*0x00000800 + (b)*0x00000004) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_HI_CURSOR_ADDRESS_HI 31:0 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR(a,b) (0x00002178 + (a)*0x00000800 + (b)*0x00000004) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_ADDRESS_LO 31:4 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_TARGET 3:2 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_TARGET_IOVA (0x00000000) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_TARGET_PHYSICAL_NVM (0x00000001) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_TARGET_PHYSICAL_PCI (0x00000002) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_TARGET_PHYSICAL_PCI_COHERENT (0x00000003) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_KIND 1:1 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_KIND_PITCH (0x00000000) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_KIND_BLOCKLINEAR (0x00000001) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_ENABLE 0:0 +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_ENABLE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_SURFACE_ADDRESS_LO_CURSOR_ENABLE_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_CRC_CONTROL(a) (0x00002184 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL 5:0 +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_0 (0x00000000) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_1 (0x00000001) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_2 (0x00000002) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_3 (0x00000003) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_4 (0x00000004) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_5 (0x00000005) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_6 (0x00000006) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_7 (0x00000007) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_8 (0x00000008) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_9 (0x00000009) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_10 (0x0000000A) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_11 (0x0000000B) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_12 (0x0000000C) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_13 (0x0000000D) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_14 (0x0000000E) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_15 (0x0000000F) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_16 (0x00000010) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_17 (0x00000011) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_18 (0x00000012) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_19 (0x00000013) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_20 (0x00000014) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_21 (0x00000015) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_22 (0x00000016) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_23 (0x00000017) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_24 (0x00000018) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_25 (0x00000019) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_26 (0x0000001A) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_27 (0x0000001B) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_28 (0x0000001C) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_29 (0x0000001D) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_30 (0x0000001E) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_WIN_31 (0x0000001F) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CONTROLLING_CHANNEL_CORE (0x00000020) +#define NVCA7D_HEAD_SET_CRC_CONTROL_EXPECT_BUFFER_COLLAPSE 8:8 +#define NVCA7D_HEAD_SET_CRC_CONTROL_EXPECT_BUFFER_COLLAPSE_FALSE (0x00000000) +#define NVCA7D_HEAD_SET_CRC_CONTROL_EXPECT_BUFFER_COLLAPSE_TRUE (0x00000001) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC 19:12 +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_NONE (0x00000000) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SF (0x00000030) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR(i) (0x00000050 +(i)) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR__SIZE_1 8 +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR0 (0x00000050) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR1 (0x00000051) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR2 (0x00000052) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR3 (0x00000053) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR4 (0x00000054) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR5 (0x00000055) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR6 (0x00000056) +#define NVCA7D_HEAD_SET_CRC_CONTROL_PRIMARY_CRC_SOR7 (0x00000057) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC 27:20 +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_NONE (0x00000000) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SF (0x00000030) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SOR(i) (0x00000050 +(i)) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SOR__SIZE_1 8 +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SOR0 (0x00000050) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SOR1 (0x00000051) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SOR2 (0x00000052) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SOR3 (0x00000053) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SOR4 (0x00000054) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SOR5 (0x00000055) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SOR6 (0x00000056) +#define NVCA7D_HEAD_SET_CRC_CONTROL_SECONDARY_CRC_SOR7 (0x00000057) +#define NVCA7D_HEAD_SET_CRC_CONTROL_CRC_DURING_SNOOZE 9:9 +#define NVCA7D_HEAD_SET_CRC_CONTROL_CRC_DURING_SNOOZE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_OLUT_CONTROL(a) (0x00002280 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_INTERPOLATE 0:0 +#define NVCA7D_HEAD_SET_OLUT_CONTROL_INTERPOLATE_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_INTERPOLATE_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_MIRROR 1:1 +#define NVCA7D_HEAD_SET_OLUT_CONTROL_MIRROR_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_MIRROR_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_MODE 3:2 +#define NVCA7D_HEAD_SET_OLUT_CONTROL_MODE_SEGMENTED (0x00000000) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_MODE_DIRECT8 (0x00000001) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_MODE_DIRECT10 (0x00000002) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_SIZE 18:8 +#define NVCA7D_HEAD_SET_OLUT_CONTROL_DIRECT_ROUND 4:4 +#define NVCA7D_HEAD_SET_OLUT_CONTROL_DIRECT_ROUND_DISABLE (0x00000000) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_DIRECT_ROUND_ENABLE (0x00000001) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_LEVEL 25:20 +#define NVCA7D_HEAD_SET_OLUT_CONTROL_SEGMENT_SIZE_BITS 5:5 +#define NVCA7D_HEAD_SET_OLUT_CONTROL_SEGMENT_SIZE_BITS_SIZE_3BITS (0x00000000) +#define NVCA7D_HEAD_SET_OLUT_CONTROL_SEGMENT_SIZE_BITS_SIZE_4BITS (0x00000001) +#define NVCA7D_HEAD_SET_OLUT_FP_NORM_SCALE(a) (0x00002284 + (a)*0x00000800) +#define NVCA7D_HEAD_SET_OLUT_FP_NORM_SCALE_VALUE 31:0 + +#define NVCA7D_TILE_SET_TILE_SIZE(a) (0x00006000 + (a)*0x00000200) +#define NVCA7D_TILE_SET_TILE_SIZE_START 14:0 +#define NVCA7D_TILE_SET_TILE_SIZE_WIDTH 30:16 + +#endif // _clca7d_h diff --git a/drivers/gpu/drm/nouveau/include/nvhw/class/clca7e.h b/drivers/gpu/drm/nouveau/include/nvhw/class/clca7e.h new file mode 100644 index 000000000000..ebfb2e48a4f4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/class/clca7e.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef _clca7e_h_ +#define _clca7e_h_ + +// class methods +#define NVCA7E_SET_NOTIFIER_CONTROL (0x00000220) +#define NVCA7E_SET_NOTIFIER_CONTROL_MODE 0:0 +#define NVCA7E_SET_NOTIFIER_CONTROL_MODE_WRITE (0x00000000) +#define NVCA7E_SET_NOTIFIER_CONTROL_MODE_WRITE_AWAKEN (0x00000001) +#define NVCA7E_SET_SIZE (0x00000224) +#define NVCA7E_SET_SIZE_WIDTH 15:0 +#define NVCA7E_SET_SIZE_HEIGHT 31:16 +#define NVCA7E_SET_STORAGE (0x00000228) +#define NVCA7E_SET_STORAGE_BLOCK_HEIGHT 3:0 +#define NVCA7E_SET_STORAGE_BLOCK_HEIGHT_NVD_BLOCK_HEIGHT_ONE_GOB (0x00000000) +#define NVCA7E_SET_STORAGE_BLOCK_HEIGHT_NVD_BLOCK_HEIGHT_TWO_GOBS (0x00000001) +#define NVCA7E_SET_STORAGE_BLOCK_HEIGHT_NVD_BLOCK_HEIGHT_FOUR_GOBS (0x00000002) +#define NVCA7E_SET_STORAGE_BLOCK_HEIGHT_NVD_BLOCK_HEIGHT_EIGHT_GOBS (0x00000003) +#define NVCA7E_SET_STORAGE_BLOCK_HEIGHT_NVD_BLOCK_HEIGHT_SIXTEEN_GOBS (0x00000004) +#define NVCA7E_SET_STORAGE_BLOCK_HEIGHT_NVD_BLOCK_HEIGHT_THIRTYTWO_GOBS (0x00000005) +#define NVCA7E_SET_PARAMS (0x0000022C) +#define NVCA7E_SET_PARAMS_FORMAT 7:0 +#define NVCA7E_SET_PARAMS_FORMAT_I8 (0x0000001E) +#define NVCA7E_SET_PARAMS_FORMAT_R4G4B4A4 (0x0000002F) +#define NVCA7E_SET_PARAMS_FORMAT_R5G6B5 (0x000000E8) +#define NVCA7E_SET_PARAMS_FORMAT_A1R5G5B5 (0x000000E9) +#define NVCA7E_SET_PARAMS_FORMAT_R5G5B5A1 (0x0000002E) +#define NVCA7E_SET_PARAMS_FORMAT_A8R8G8B8 (0x000000CF) +#define NVCA7E_SET_PARAMS_FORMAT_X8R8G8B8 (0x000000E6) +#define NVCA7E_SET_PARAMS_FORMAT_A8B8G8R8 (0x000000D5) +#define NVCA7E_SET_PARAMS_FORMAT_X8B8G8R8 (0x000000F9) +#define NVCA7E_SET_PARAMS_FORMAT_A2R10G10B10 (0x000000DF) +#define NVCA7E_SET_PARAMS_FORMAT_A2B10G10R10 (0x000000D1) +#define NVCA7E_SET_PARAMS_FORMAT_R16_G16_B16_A16_NVBIAS (0x00000023) +#define NVCA7E_SET_PARAMS_FORMAT_R16_G16_B16_A16 (0x000000C6) +#define NVCA7E_SET_PARAMS_FORMAT_RF16_GF16_BF16_AF16 (0x000000CA) +#define NVCA7E_SET_PARAMS_FORMAT_Y8_U8__Y8_V8_N422 (0x00000028) +#define NVCA7E_SET_PARAMS_FORMAT_U8_Y8__V8_Y8_N422 (0x00000029) +#define NVCA7E_SET_PARAMS_FORMAT_Y8___U8V8_N444 (0x00000035) +#define NVCA7E_SET_PARAMS_FORMAT_Y8___U8V8_N422 (0x00000036) +#define NVCA7E_SET_PARAMS_FORMAT_Y8___V8U8_N420 (0x00000038) +#define NVCA7E_SET_PARAMS_FORMAT_Y8___U8___V8_N444 (0x0000003A) +#define NVCA7E_SET_PARAMS_FORMAT_Y8___U8___V8_N420 (0x0000003B) +#define NVCA7E_SET_PARAMS_FORMAT_Y10___U10V10_N444 (0x00000055) +#define NVCA7E_SET_PARAMS_FORMAT_Y10___U10V10_N422 (0x00000056) +#define NVCA7E_SET_PARAMS_FORMAT_Y10___V10U10_N420 (0x00000058) +#define NVCA7E_SET_PARAMS_FORMAT_Y12___U12V12_N444 (0x00000075) +#define NVCA7E_SET_PARAMS_FORMAT_Y12___U12V12_N422 (0x00000076) +#define NVCA7E_SET_PARAMS_FORMAT_Y12___V12U12_N420 (0x00000078) +#define NVCA7E_SET_PARAMS_CLAMP_BEFORE_BLEND 18:18 +#define NVCA7E_SET_PARAMS_CLAMP_BEFORE_BLEND_DISABLE (0x00000000) +#define NVCA7E_SET_PARAMS_CLAMP_BEFORE_BLEND_ENABLE (0x00000001) +#define NVCA7E_SET_PARAMS_SWAP_UV 19:19 +#define NVCA7E_SET_PARAMS_SWAP_UV_DISABLE (0x00000000) +#define NVCA7E_SET_PARAMS_SWAP_UV_ENABLE (0x00000001) +#define NVCA7E_SET_PARAMS_FMT_ROUNDING_MODE 22:22 +#define NVCA7E_SET_PARAMS_FMT_ROUNDING_MODE_ROUND_TO_NEAREST (0x00000000) +#define NVCA7E_SET_PARAMS_FMT_ROUNDING_MODE_ROUND_DOWN (0x00000001) +#define NVCA7E_SET_PLANAR_STORAGE(b) (0x00000230 + (b)*0x00000004) +#define NVCA7E_SET_PLANAR_STORAGE_PITCH 12:0 +#define NVCA7E_SET_POINT_IN(b) (0x00000290 + (b)*0x00000004) +#define NVCA7E_SET_POINT_IN_X 15:0 +#define NVCA7E_SET_POINT_IN_Y 31:16 +#define NVCA7E_SET_SIZE_IN (0x00000298) +#define NVCA7E_SET_SIZE_IN_WIDTH 15:0 +#define NVCA7E_SET_SIZE_IN_HEIGHT 31:16 +#define NVCA7E_SET_SIZE_OUT (0x000002A4) +#define NVCA7E_SET_SIZE_OUT_WIDTH 15:0 +#define NVCA7E_SET_SIZE_OUT_HEIGHT 31:16 +#define NVCA7E_SET_PRESENT_CONTROL (0x00000308) +#define NVCA7E_SET_PRESENT_CONTROL_MIN_PRESENT_INTERVAL 3:0 +#define NVCA7E_SET_PRESENT_CONTROL_BEGIN_MODE 6:4 +#define NVCA7E_SET_PRESENT_CONTROL_BEGIN_MODE_NON_TEARING (0x00000000) +#define NVCA7E_SET_PRESENT_CONTROL_BEGIN_MODE_IMMEDIATE (0x00000001) +#define NVCA7E_SET_PRESENT_CONTROL_TIMESTAMP_MODE 8:8 +#define NVCA7E_SET_PRESENT_CONTROL_TIMESTAMP_MODE_DISABLE (0x00000000) +#define NVCA7E_SET_PRESENT_CONTROL_TIMESTAMP_MODE_ENABLE (0x00000001) +#define NVCA7E_SET_PRESENT_CONTROL_STEREO_MODE 13:12 +#define NVCA7E_SET_PRESENT_CONTROL_STEREO_MODE_MONO (0x00000000) +#define NVCA7E_SET_PRESENT_CONTROL_STEREO_MODE_PAIR_FLIP (0x00000001) +#define NVCA7E_SET_PRESENT_CONTROL_STEREO_MODE_AT_ANY_FRAME (0x00000002) +#define NVCA7E_SET_ILUT_CONTROL (0x00000440) +#define NVCA7E_SET_ILUT_CONTROL_INTERPOLATE 0:0 +#define NVCA7E_SET_ILUT_CONTROL_INTERPOLATE_DISABLE (0x00000000) +#define NVCA7E_SET_ILUT_CONTROL_INTERPOLATE_ENABLE (0x00000001) +#define NVCA7E_SET_ILUT_CONTROL_MIRROR 1:1 +#define NVCA7E_SET_ILUT_CONTROL_MIRROR_DISABLE (0x00000000) +#define NVCA7E_SET_ILUT_CONTROL_MIRROR_ENABLE (0x00000001) +#define NVCA7E_SET_ILUT_CONTROL_MODE 3:2 +#define NVCA7E_SET_ILUT_CONTROL_MODE_SEGMENTED (0x00000000) +#define NVCA7E_SET_ILUT_CONTROL_MODE_DIRECT8 (0x00000001) +#define NVCA7E_SET_ILUT_CONTROL_MODE_DIRECT10 (0x00000002) +#define NVCA7E_SET_ILUT_CONTROL_SIZE 18:8 +#define NVCA7E_SET_SURFACE_ADDRESS_HI_NOTIFIER (0x00000650) +#define NVCA7E_SET_SURFACE_ADDRESS_HI_NOTIFIER_ADDRESS_HI 31:0 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_NOTIFIER (0x00000654) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_NOTIFIER_ADDRESS_LO 31:4 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_NOTIFIER_TARGET 3:2 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_NOTIFIER_TARGET_IOVA (0x00000000) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_NOTIFIER_TARGET_PHYSICAL_NVM (0x00000001) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_NOTIFIER_TARGET_PHYSICAL_PCI (0x00000002) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_NOTIFIER_TARGET_PHYSICAL_PCI_COHERENT (0x00000003) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_NOTIFIER_ENABLE 0:0 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_NOTIFIER_ENABLE_DISABLE (0x00000000) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_NOTIFIER_ENABLE_ENABLE (0x00000001) +#define NVCA7E_SET_SURFACE_ADDRESS_HI_ISO(b) (0x00000658 + (b)*0x00000004) +#define NVCA7E_SET_SURFACE_ADDRESS_HI_ISO_ADDRESS_HI 31:0 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO(b) (0x00000670 + (b)*0x00000004) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_ADDRESS_LO 31:4 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_TARGET 3:2 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_TARGET_IOVA (0x00000000) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_TARGET_PHYSICAL_NVM (0x00000001) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_TARGET_PHYSICAL_PCI (0x00000002) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_TARGET_PHYSICAL_PCI_COHERENT (0x00000003) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_KIND 1:1 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_KIND_PITCH (0x00000000) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_KIND_BLOCKLINEAR (0x00000001) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_ENABLE 0:0 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_ENABLE_DISABLE (0x00000000) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ISO_ENABLE_ENABLE (0x00000001) +#define NVCA7E_SET_SURFACE_ADDRESS_HI_ILUT (0x00000688) +#define NVCA7E_SET_SURFACE_ADDRESS_HI_ILUT_ADDRESS_HI 31:0 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ILUT (0x0000068C) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ILUT_ADDRESS_LO 31:4 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ILUT_TARGET 3:2 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ILUT_TARGET_IOVA (0x00000000) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ILUT_TARGET_PHYSICAL_NVM (0x00000001) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ILUT_TARGET_PHYSICAL_PCI (0x00000002) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ILUT_TARGET_PHYSICAL_PCI_COHERENT (0x00000003) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ILUT_ENABLE 0:0 +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ILUT_ENABLE_DISABLE (0x00000000) +#define NVCA7E_SET_SURFACE_ADDRESS_LO_ILUT_ENABLE_ENABLE (0x00000001) + +#endif // _clca7e_h diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gb100/dev_hshub_base.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb100/dev_hshub_base.h new file mode 100644 index 000000000000..c9d74bd95e0b --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb100/dev_hshub_base.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gb100_dev_hshub_base_h__ +#define __gb100_dev_hshub_base_h__ + +#define NV_PFB_HSHUB0 0x00870fff:0x00870000 + +#define NV_PFB_HSHUB 0x00000FFF:0x00000000 /* RW--D */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO 0x00000E50 /* RW-4R */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR 31:0 /* RWIVF */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_MASK 0xFFFFFF00 /* ----V */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI 0x00000E54 /* RW-4R */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR 31:0 /* RWIVF */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_MASK 0x000FFFFF /* ----V */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO 0x000006C0 /* RW-4R */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR 31:0 /* RWIVF */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_MASK 0xFFFFFF00 /* ----V */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI 0x000006C4 /* RW-4R */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR 31:0 /* RWIVF */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_MASK 0x000FFFFF /* ----V */ + +#endif // __gb100_dev_hshub_base_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gb10b/dev_fbhub.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb10b/dev_fbhub.h new file mode 100644 index 000000000000..4d0bb8e14298 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb10b/dev_fbhub.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gb10b_dev_fb_h__ +#define __gb10b_dev_fb_h__ + +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO 0x008a1d58 /* RW-4R */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR 31:0 /* RWIVF */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR_MASK 0xffffff00 /* RW--V */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI 0x008a1d5c /* RW-4R */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR 31:0 /* RWIVF */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_INIT 0x00000000 /* RWI-V */ +#define NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_MASK 0x000fffff /* RW--V */ + +#endif // __gb10b_dev_fb_h__ + diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_ce.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_ce.h new file mode 100644 index 000000000000..b09f04b31738 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_ce.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gb202_dev_ce_h__ +#define __gb202_dev_ce_h__ + +#define NV_CE_GRCE_MASK 0x001040d8 /* C--4R */ +#define NV_CE_GRCE_MASK_VALUE 9:0 /* C--VF */ +#define NV_CE_GRCE_MASK_VALUE_INIT 0x00f /* C---V */ + +#endif // __gb202_dev_ce_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_therm.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_therm.h new file mode 100644 index 000000000000..ed359cb528fb --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gb202/dev_therm.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gb202_dev_therm_h__ +#define __gb202_dev_therm_h__ + +#define NV_THERM_I2CS_SCRATCH 0x00ad00bc /* RW-4R */ +#define NV_THERM_I2CS_SCRATCH_DATA 31:0 /* RWIVF */ +#define NV_THERM_I2CS_SCRATCH_DATA_INIT 0x00000000 /* RWI-V */ +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE NV_THERM_I2CS_SCRATCH +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS 31:0 +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_SUCCESS 0x000000FF +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_FAILED 0x00000000 + +#endif // __gb202_dev_therm_h__ + diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_falcon_v4.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_falcon_v4.h new file mode 100644 index 000000000000..52171b412aa1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_falcon_v4.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_falcon_v4_h__ +#define __gh100_dev_falcon_v4_h__ + +#define NV_PFALCON_FALCON_MAILBOX0 0x00000040 /* RW-4R */ +#define NV_PFALCON_FALCON_MAILBOX0_DATA 31:0 /* RWIVF */ +#define NV_PFALCON_FALCON_MAILBOX0_DATA_INIT 0x00000000 /* RWI-V */ +#define NV_PFALCON_FALCON_MAILBOX1 0x00000044 /* RW-4R */ +#define NV_PFALCON_FALCON_MAILBOX1_DATA 31:0 /* RWIVF */ +#define NV_PFALCON_FALCON_MAILBOX1_DATA_INIT 0x00000000 /* RWI-V */ + +#define NV_PFALCON_FALCON_HWCFG2 0x000000f4 /* R--4R */ +#define NV_PFALCON_FALCON_HWCFG2_RISCV_BR_PRIV_LOCKDOWN 13:13 /* R--VF */ +#define NV_PFALCON_FALCON_HWCFG2_RISCV_BR_PRIV_LOCKDOWN_LOCK 0x00000001 /* R---V */ +#define NV_PFALCON_FALCON_HWCFG2_RISCV_BR_PRIV_LOCKDOWN_UNLOCK 0x00000000 /* R---V */ + +#endif // __gh100_dev_falcon_v4_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fb.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fb.h new file mode 100644 index 000000000000..819f09465952 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fb.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_fb_h_ +#define __gh100_dev_fb_h_ + +#define NV_PFB_NISO_FLUSH_SYSMEM_ADDR_SHIFT 8 /* */ +#define NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_LO 0x00100A34 /* RW-4R */ +#define NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_LO_ADR 31:0 /* RWIVF */ +#define NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI 0x00100A38 /* RW-4R */ +#define NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR 31:0 /* RWIVF */ +#define NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI_ADR_MASK 0x000FFFFF /* ----V */ + +#endif // __gh100_dev_fb_h_ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fsp_pri.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fsp_pri.h new file mode 100644 index 000000000000..e9507242cae5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_fsp_pri.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_fsp_pri_h__ +#define __gh100_dev_fsp_pri_h__ + +#define NV_PFSP 0x8F3FFF:0x8F0000 /* RW--D */ + +#define NV_PFSP_MSGQ_HEAD(i) (0x008F2c80+(i)*8) /* RW-4A */ +#define NV_PFSP_MSGQ_HEAD__SIZE_1 8 /* */ +#define NV_PFSP_MSGQ_HEAD_VAL 31:0 /* RWIUF */ +#define NV_PFSP_MSGQ_HEAD_VAL_INIT 0x00000000 /* RWI-V */ +#define NV_PFSP_MSGQ_TAIL(i) (0x008F2c84+(i)*8) /* RW-4A */ +#define NV_PFSP_MSGQ_TAIL__SIZE_1 8 /* */ +#define NV_PFSP_MSGQ_TAIL_VAL 31:0 /* RWIUF */ +#define NV_PFSP_MSGQ_TAIL_VAL_INIT 0x00000000 /* RWI-V */ + +#define NV_PFSP_QUEUE_HEAD(i) (0x008F2c00+(i)*8) /* RW-4A */ +#define NV_PFSP_QUEUE_HEAD__SIZE_1 8 /* */ +#define NV_PFSP_QUEUE_HEAD_ADDRESS 31:0 /* RWIVF */ +#define NV_PFSP_QUEUE_HEAD_ADDRESS_INIT 0x00000000 /* RWI-V */ +#define NV_PFSP_QUEUE_TAIL(i) (0x008F2c04+(i)*8) /* RW-4A */ +#define NV_PFSP_QUEUE_TAIL__SIZE_1 8 /* */ +#define NV_PFSP_QUEUE_TAIL_ADDRESS 31:0 /* RWIVF */ +#define NV_PFSP_QUEUE_TAIL_ADDRESS_INIT 0x00000000 /* RWI-V */ + +#endif // __gh100_dev_fsp_pri_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_mmu.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_mmu.h new file mode 100644 index 000000000000..6707e0e3b96b --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_mmu.h @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_mmu_h__ +#define __gh100_dev_mmu_h__ + +#define NV_MMU_PTE /* ----G */ +#define NV_MMU_PTE_APERTURE (1*32+2):(1*32+1) /* RWXVF */ +#define NV_MMU_PTE_APERTURE_VIDEO_MEMORY 0x00000000 /* RW--V */ +#define NV_MMU_PTE_APERTURE_PEER_MEMORY 0x00000001 /* RW--V */ +#define NV_MMU_PTE_APERTURE_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */ +#define NV_MMU_PTE_APERTURE_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */ +#define NV_MMU_PTE_KIND (1*32+7):(1*32+4) /* RWXVF */ +#define NV_MMU_PTE_KIND_INVALID 0x07 /* R---V */ +#define NV_MMU_PTE_KIND_PITCH 0x00 /* R---V */ +#define NV_MMU_PTE_KIND_GENERIC_MEMORY 0x6 /* R---V */ +#define NV_MMU_PTE_KIND_Z16 0x1 /* R---V */ +#define NV_MMU_PTE_KIND_S8 0x2 /* R---V */ +#define NV_MMU_PTE_KIND_S8Z24 0x3 /* R---V */ +#define NV_MMU_PTE_KIND_ZF32_X24S8 0x4 /* R---V */ +#define NV_MMU_PTE_KIND_Z24S8 0x5 /* R---V */ +#define NV_MMU_PTE_KIND_GENERIC_MEMORY_COMPRESSIBLE 0x8 /* R---V */ +#define NV_MMU_PTE_KIND_GENERIC_MEMORY_COMPRESSIBLE_DISABLE_PLC 0x9 /* R---V */ +#define NV_MMU_PTE_KIND_S8_COMPRESSIBLE_DISABLE_PLC 0xA /* R---V */ +#define NV_MMU_PTE_KIND_Z16_COMPRESSIBLE_DISABLE_PLC 0xB /* R---V */ +#define NV_MMU_PTE_KIND_S8Z24_COMPRESSIBLE_DISABLE_PLC 0xC /* R---V */ +#define NV_MMU_PTE_KIND_ZF32_X24S8_COMPRESSIBLE_DISABLE_PLC 0xD /* R---V */ +#define NV_MMU_PTE_KIND_Z24S8_COMPRESSIBLE_DISABLE_PLC 0xE /* R---V */ +#define NV_MMU_PTE_KIND_SMSKED_MESSAGE 0xF /* R---V */ + +#define NV_MMU_VER3_PDE /* ----G */ +#define NV_MMU_VER3_PDE_IS_PTE 0:0 /* RWXVF */ +#define NV_MMU_VER3_PDE_IS_PTE_TRUE 0x1 /* RW--V */ +#define NV_MMU_VER3_PDE_IS_PTE_FALSE 0x0 /* RW--V */ +#define NV_MMU_VER3_PDE_VALID 0:0 /* RWXVF */ +#define NV_MMU_VER3_PDE_VALID_TRUE 0x1 /* RW--V */ +#define NV_MMU_VER3_PDE_VALID_FALSE 0x0 /* RW--V */ +#define NV_MMU_VER3_PDE_APERTURE 2:1 /* RWXVF */ +#define NV_MMU_VER3_PDE_APERTURE_INVALID 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PDE_APERTURE_VIDEO_MEMORY 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PDE_APERTURE_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PDE_APERTURE_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF 5:3 /* RWXVF */ +#define NV_MMU_VER3_PDE_PCF_VALID_CACHED_ATS_ALLOWED__OR__INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_CACHED_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_UNCACHED_ATS_ALLOWED__OR__SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_UNCACHED_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_CACHED_ATS_NOT_ALLOWED__OR__INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_CACHED_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_UNCACHED_ATS_NOT_ALLOWED__OR__SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_VALID_UNCACHED_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PDE_PCF_SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PDE_ADDRESS 51:12 /* RWXVF */ +#define NV_MMU_VER3_PDE_ADDRESS_SHIFT 0x0000000c /* */ +#define NV_MMU_VER3_PDE__SIZE 8 + +#define NV_MMU_VER3_DUAL_PDE /* ----G */ +#define NV_MMU_VER3_DUAL_PDE_IS_PTE 0:0 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_IS_PTE_TRUE 0x1 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_IS_PTE_FALSE 0x0 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_VALID 0:0 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_VALID_TRUE 0x1 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_VALID_FALSE 0x0 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_BIG 2:1 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_BIG_INVALID 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_BIG_VIDEO_MEMORY 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_BIG_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_BIG_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG 5:3 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_CACHED_ATS_ALLOWED__OR__INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_CACHED_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_UNCACHED_ATS_ALLOWED__OR__SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_UNCACHED_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_CACHED_ATS_NOT_ALLOWED__OR__INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_CACHED_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_UNCACHED_ATS_NOT_ALLOWED__OR__SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_VALID_UNCACHED_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_BIG_SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_ADDRESS_BIG 51:8 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_SMALL 66:65 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_SMALL_INVALID 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_SMALL_VIDEO_MEMORY 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_SMALL_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_APERTURE_SMALL_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL 69:67 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_CACHED_ATS_ALLOWED__OR__INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_CACHED_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_INVALID_ATS_ALLOWED 0x00000000 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_UNCACHED_ATS_ALLOWED__OR__SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_UNCACHED_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_SPARSE_ATS_ALLOWED 0x00000001 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_CACHED_ATS_NOT_ALLOWED__OR__INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_CACHED_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_INVALID_ATS_NOT_ALLOWED 0x00000002 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_UNCACHED_ATS_NOT_ALLOWED__OR__SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_VALID_UNCACHED_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_PCF_SMALL_SPARSE_ATS_NOT_ALLOWED 0x00000003 /* RW--V */ +#define NV_MMU_VER3_DUAL_PDE_ADDRESS_SMALL 115:76 /* RWXVF */ +#define NV_MMU_VER3_DUAL_PDE_ADDRESS_SHIFT 0x0000000c /* */ +#define NV_MMU_VER3_DUAL_PDE_ADDRESS_BIG_SHIFT 8 /* */ +#define NV_MMU_VER3_DUAL_PDE__SIZE 16 + +#define NV_MMU_VER3_PTE /* ----G */ +#define NV_MMU_VER3_PTE_VALID 0:0 /* RWXVF */ +#define NV_MMU_VER3_PTE_VALID_TRUE 0x1 /* RW--V */ +#define NV_MMU_VER3_PTE_VALID_FALSE 0x0 /* RW--V */ +#define NV_MMU_VER3_PTE_APERTURE 2:1 /* RWXVF */ +#define NV_MMU_VER3_PTE_APERTURE_VIDEO_MEMORY 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PTE_APERTURE_PEER_MEMORY 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PTE_APERTURE_SYSTEM_COHERENT_MEMORY 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PTE_APERTURE_SYSTEM_NON_COHERENT_MEMORY 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF 7:3 /* RWXVF */ +#define NV_MMU_VER3_PTE_PCF_INVALID 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_SPARSE 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_MAPPING_NOWHERE 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_NO_VALID_4KB_PAGE 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_CACHED_ACE 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_UNCACHED_ACE 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_CACHED_ACE 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_UNCACHED_ACE 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_CACHED_ACE 0x00000004 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_UNCACHED_ACE 0x00000005 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_CACHED_ACE 0x00000006 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_UNCACHED_ACE 0x00000007 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_NO_ATOMIC_CACHED_ACE 0x00000008 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_NO_ATOMIC_UNCACHED_ACE 0x00000009 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_CACHED_ACE 0x0000000A /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_UNCACHED_ACE 0x0000000B /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_NO_ATOMIC_CACHED_ACE 0x0000000C /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_NO_ATOMIC_UNCACHED_ACE 0x0000000D /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_CACHED_ACE 0x0000000E /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_UNCACHED_ACE 0x0000000F /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_CACHED_ACD 0x00000010 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_UNCACHED_ACD 0x00000011 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_CACHED_ACD 0x00000012 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_UNCACHED_ACD 0x00000013 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_CACHED_ACD 0x00000014 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_UNCACHED_ACD 0x00000015 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_CACHED_ACD 0x00000016 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_UNCACHED_ACD 0x00000017 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_NO_ATOMIC_CACHED_ACD 0x00000018 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RW_NO_ATOMIC_UNCACHED_ACD 0x00000019 /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_CACHED_ACD 0x0000001A /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_UNCACHED_ACD 0x0000001B /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_NO_ATOMIC_CACHED_ACD 0x0000001C /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_REGULAR_RO_NO_ATOMIC_UNCACHED_ACD 0x0000001D /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_CACHED_ACD 0x0000001E /* RW--V */ +#define NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_UNCACHED_ACD 0x0000001F /* RW--V */ +#define NV_MMU_VER3_PTE_KIND 11:8 /* RWXVF */ +#define NV_MMU_VER3_PTE_ADDRESS 51:12 /* RWXVF */ +#define NV_MMU_VER3_PTE_ADDRESS_SYS 51:12 /* RWXVF */ +#define NV_MMU_VER3_PTE_ADDRESS_PEER 51:12 /* RWXVF */ +#define NV_MMU_VER3_PTE_ADDRESS_VID 39:12 /* RWXVF */ +#define NV_MMU_VER3_PTE_PEER_ID 63:(64-3) /* RWXVF */ +#define NV_MMU_VER3_PTE_PEER_ID_0 0x00000000 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_1 0x00000001 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_2 0x00000002 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_3 0x00000003 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_4 0x00000004 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_5 0x00000005 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_6 0x00000006 /* RW--V */ +#define NV_MMU_VER3_PTE_PEER_ID_7 0x00000007 /* RW--V */ +#define NV_MMU_VER3_PTE_ADDRESS_SHIFT 0x0000000c /* */ +#define NV_MMU_VER3_PTE__SIZE 8 + +#endif // __gh100_dev_mmu_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_riscv_pri.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_riscv_pri.h new file mode 100644 index 000000000000..8ff4663168d2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_riscv_pri.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_riscv_pri_h__ +#define __gh100_dev_riscv_pri_h__ + +#define NV_PRISCV_RISCV_CPUCTL 0x00000388 /* RW-4R */ +#define NV_PRISCV_RISCV_CPUCTL_HALTED 4:4 /* R-IVF */ +#define NV_PRISCV_RISCV_CPUCTL_HALTED_INIT 0x00000001 /* R-I-V */ +#define NV_PRISCV_RISCV_CPUCTL_HALTED_TRUE 0x00000001 /* R---V */ +#define NV_PRISCV_RISCV_CPUCTL_HALTED_FALSE 0x00000000 /* R---V */ + +#endif // __gh100_dev_riscv_pri_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_therm.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_therm.h new file mode 100644 index 000000000000..49b4816cb00b --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_therm.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_therm_h__ +#define __gh100_dev_therm_h__ + +#define NV_THERM_I2CS_SCRATCH 0x000200bc /* RW-4R */ +#define NV_THERM_I2CS_SCRATCH_DATA 31:0 /* RWIVF */ +#define NV_THERM_I2CS_SCRATCH_DATA_INIT 0x00000000 /* RWI-V */ + +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE NV_THERM_I2CS_SCRATCH +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS 31:0 +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_SUCCESS 0x000000FF +#define NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_FAILED 0x00000000 + +#endif // __gh100_dev_therm_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_xtl_ep_pri.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_xtl_ep_pri.h new file mode 100644 index 000000000000..12b49e9894a2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/dev_xtl_ep_pri.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_dev_xtl_ep_pri_h__ +#define __gh100_dev_xtl_ep_pri_h__ + +#define NV_EP_PCFGM 0x92FFF:0x92000 /* RW--D */ + +#endif // __gh100_dev_xtl_ep_pri_h__ diff --git a/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/pri_nv_xal_ep.h b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/pri_nv_xal_ep.h new file mode 100644 index 000000000000..1a891bd33fa3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/ref/gh100/pri_nv_xal_ep.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __gh100_pri_nv_xal_ep_h__ +#define __gh100_pri_nv_xal_ep_h__ + +#define NV_XAL_EP_BAR0_WINDOW_BASE_SHIFT 0x000010 +#define NV_XAL_EP_BAR0_WINDOW_BASE 21:0 +#define NV_XAL_EP_BAR0_WINDOW 0x0010fd40 + +#endif // __gh100_pri_nv_xal_ep_h__ + diff --git a/drivers/gpu/drm/nouveau/include/nvif/chan.h b/drivers/gpu/drm/nouveau/include/nvif/chan.h new file mode 100644 index 000000000000..c329a29068d5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/chan.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVIF_CHAN_H__ +#define __NVIF_CHAN_H__ +#include "push.h" + +struct nvif_chan { + const struct nvif_chan_func { + struct { + u32 (*read_get)(struct nvif_chan *); + } push; + + struct { + u32 (*read_get)(struct nvif_chan *); + void (*push)(struct nvif_chan *, bool main, u64 addr, u32 size, + bool no_prefetch); + void (*kick)(struct nvif_chan *); + int (*post)(struct nvif_chan *, u32 gpptr, u32 pbptr); + u32 post_size; + } gpfifo; + + struct { + int (*release)(struct nvif_chan *, u64 addr, u32 data); + } sem; + } *func; + + struct { + struct nvif_map map; + } userd; + + struct { + struct nvif_map map; + u32 cur; + u32 max; + int free; + } gpfifo; + + struct { + struct nvif_map map; + u64 addr; + } sema; + + struct nvif_push push; + + struct nvif_user *usermode; + u32 doorbell_token; +}; + +int nvif_chan_dma_wait(struct nvif_chan *, u32 push_nr); + +void nvif_chan_gpfifo_ctor(const struct nvif_chan_func *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, struct nvif_chan *); +int nvif_chan_gpfifo_wait(struct nvif_chan *, u32 gpfifo_nr, u32 push_nr); +void nvif_chan_gpfifo_push(struct nvif_chan *, u64 addr, u32 size, bool no_prefetch); +int nvif_chan_gpfifo_post(struct nvif_chan *); + +void nvif_chan506f_gpfifo_push(struct nvif_chan *, bool main, u64 addr, u32 size, bool no_prefetch); +void nvif_chan506f_gpfifo_kick(struct nvif_chan *); + +int nvif_chan906f_ctor_(const struct nvif_chan_func *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr, + struct nvif_chan *); +u32 nvif_chan906f_read_get(struct nvif_chan *); +u32 nvif_chan906f_gpfifo_read_get(struct nvif_chan *); +int nvif_chan906f_gpfifo_post(struct nvif_chan *, u32 gpptr, u32 pbptr); + +int nvif_chan506f_ctor(struct nvif_chan *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size); +int nvif_chan906f_ctor(struct nvif_chan *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr); +int nvif_chanc36f_ctor(struct nvif_chan *, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr, + struct nvif_user *usermode, u32 doorbell_token); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h index ea937fa7bc55..ea8267e0d8da 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cl0080.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cl0080.h @@ -29,6 +29,8 @@ struct nv_device_info_v0 { #define NV_DEVICE_INFO_V0_TURING 0x0c #define NV_DEVICE_INFO_V0_AMPERE 0x0d #define NV_DEVICE_INFO_V0_ADA 0x0e +#define NV_DEVICE_INFO_V0_HOPPER 0x0f +#define NV_DEVICE_INFO_V0_BLACKWELL 0x10 __u8 family; __u8 pad06[2]; __u64 ram_size; diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index 824e052dcc25..ff6823cb2cd8 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -57,12 +57,15 @@ #define KEPLER_INLINE_TO_MEMORY_A 0x0000a040 #define KEPLER_INLINE_TO_MEMORY_B 0x0000a140 +#define BLACKWELL_INLINE_TO_MEMORY_A 0x0000cd40 #define NV04_DISP /* cl0046.h */ 0x00000046 #define VOLTA_USERMODE_A 0x0000c361 #define TURING_USERMODE_A 0x0000c461 #define AMPERE_USERMODE_A 0x0000c561 +#define HOPPER_USERMODE_A 0x0000c661 +#define BLACKWELL_USERMODE_A 0x0000c761 #define MAXWELL_FAULT_BUFFER_A /* clb069.h */ 0x0000b069 #define VOLTA_FAULT_BUFFER_A /* clb069.h */ 0x0000c369 @@ -85,6 +88,9 @@ #define TURING_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c46f #define AMPERE_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c56f #define AMPERE_CHANNEL_GPFIFO_B /* if0020.h */ 0x0000c76f +#define HOPPER_CHANNEL_GPFIFO_A 0x0000c86f +#define BLACKWELL_CHANNEL_GPFIFO_A 0x0000c96f +#define BLACKWELL_CHANNEL_GPFIFO_B 0x0000ca6f #define NV50_DISP /* if0010.h */ 0x00005070 #define G82_DISP /* if0010.h */ 0x00008270 @@ -102,8 +108,10 @@ #define TU102_DISP /* if0010.h */ 0x0000c570 #define GA102_DISP /* if0010.h */ 0x0000c670 #define AD102_DISP /* if0010.h */ 0x0000c770 +#define GB202_DISP 0x0000ca70 #define GV100_DISP_CAPS 0x0000c373 +#define GB202_DISP_CAPS 0x0000ca73 #define NV31_MPEG 0x00003174 #define G82_MPEG 0x00008274 @@ -118,6 +126,7 @@ #define GV100_DISP_CURSOR /* if0014.h */ 0x0000c37a #define TU102_DISP_CURSOR /* if0014.h */ 0x0000c57a #define GA102_DISP_CURSOR /* if0014.h */ 0x0000c67a +#define GB202_DISP_CURSOR 0x0000ca7a #define NV50_DISP_OVERLAY /* if0014.h */ 0x0000507b #define G82_DISP_OVERLAY /* if0014.h */ 0x0000827b @@ -128,6 +137,7 @@ #define GV100_DISP_WINDOW_IMM_CHANNEL_DMA /* if0014.h */ 0x0000c37b #define TU102_DISP_WINDOW_IMM_CHANNEL_DMA /* if0014.h */ 0x0000c57b #define GA102_DISP_WINDOW_IMM_CHANNEL_DMA /* if0014.h */ 0x0000c67b +#define GB202_DISP_WINDOW_IMM_CHANNEL_DMA 0x0000ca7b #define NV50_DISP_BASE_CHANNEL_DMA /* if0014.h */ 0x0000507c #define G82_DISP_BASE_CHANNEL_DMA /* if0014.h */ 0x0000827c @@ -153,6 +163,7 @@ #define TU102_DISP_CORE_CHANNEL_DMA /* if0014.h */ 0x0000c57d #define GA102_DISP_CORE_CHANNEL_DMA /* if0014.h */ 0x0000c67d #define AD102_DISP_CORE_CHANNEL_DMA /* if0014.h */ 0x0000c77d +#define GB202_DISP_CORE_CHANNEL_DMA 0x0000ca7d #define NV50_DISP_OVERLAY_CHANNEL_DMA /* if0014.h */ 0x0000507e #define G82_DISP_OVERLAY_CHANNEL_DMA /* if0014.h */ 0x0000827e @@ -164,6 +175,7 @@ #define GV100_DISP_WINDOW_CHANNEL_DMA /* if0014.h */ 0x0000c37e #define TU102_DISP_WINDOW_CHANNEL_DMA /* if0014.h */ 0x0000c57e #define GA102_DISP_WINDOW_CHANNEL_DMA /* if0014.h */ 0x0000c67e +#define GB202_DISP_WINDOW_CHANNEL_DMA 0x0000ca7e #define NV50_TESLA 0x00005097 #define G82_TESLA 0x00008297 @@ -189,16 +201,25 @@ #define TURING_A /* cl9097.h */ 0x0000c597 +#define AMPERE_A 0x0000c697 #define AMPERE_B /* cl9097.h */ 0x0000c797 #define ADA_A /* cl9097.h */ 0x0000c997 +#define HOPPER_A 0x0000cb97 + +#define BLACKWELL_A 0x0000cd97 +#define BLACKWELL_B 0x0000ce97 + #define NV74_BSP 0x000074b0 +#define NVB8B0_VIDEO_DECODER 0x0000b8b0 #define NVC4B0_VIDEO_DECODER 0x0000c4b0 #define NVC6B0_VIDEO_DECODER 0x0000c6b0 #define NVC7B0_VIDEO_DECODER 0x0000c7b0 #define NVC9B0_VIDEO_DECODER 0x0000c9b0 +#define NVCDB0_VIDEO_DECODER 0x0000cdb0 +#define NVCFB0_VIDEO_DECODER 0x0000cfb0 #define GT212_MSVLD 0x000085b1 #define IGT21A_MSVLD 0x000086b1 @@ -227,10 +248,14 @@ #define TURING_DMA_COPY_A 0x0000c5b5 #define AMPERE_DMA_COPY_A 0x0000c6b5 #define AMPERE_DMA_COPY_B 0x0000c7b5 +#define HOPPER_DMA_COPY_A 0x0000c8b5 +#define BLACKWELL_DMA_COPY_A 0x0000c9b5 +#define BLACKWELL_DMA_COPY_B 0x0000cab5 #define NVC4B7_VIDEO_ENCODER 0x0000c4b7 #define NVC7B7_VIDEO_ENCODER 0x0000c7b7 #define NVC9B7_VIDEO_ENCODER 0x0000c9b7 +#define NVCFB7_VIDEO_ENCODER 0x0000cfb7 #define FERMI_DECOMPRESS 0x000090b8 @@ -246,15 +271,25 @@ #define PASCAL_COMPUTE_B 0x0000c1c0 #define VOLTA_COMPUTE_A 0x0000c3c0 #define TURING_COMPUTE_A 0x0000c5c0 +#define AMPERE_COMPUTE_A 0x0000c6c0 #define AMPERE_COMPUTE_B 0x0000c7c0 #define ADA_COMPUTE_A 0x0000c9c0 +#define HOPPER_COMPUTE_A 0x0000cbc0 +#define BLACKWELL_COMPUTE_A 0x0000cdc0 +#define BLACKWELL_COMPUTE_B 0x0000cec0 #define NV74_CIPHER 0x000074c1 +#define NVB8D1_VIDEO_NVJPG 0x0000b8d1 #define NVC4D1_VIDEO_NVJPG 0x0000c4d1 #define NVC9D1_VIDEO_NVJPG 0x0000c9d1 +#define NVCDD1_VIDEO_NVJPG 0x0000cdd1 +#define NVCFD1_VIDEO_NVJPG 0x0000cfd1 +#define NVB8FA_VIDEO_OFA 0x0000b8fa #define NVC6FA_VIDEO_OFA 0x0000c6fa #define NVC7FA_VIDEO_OFA 0x0000c7fa #define NVC9FA_VIDEO_OFA 0x0000c9fa +#define NVCDFA_VIDEO_OFA 0x0000cdfa +#define NVCFFA_VIDEO_OFA 0x0000cffa #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/object.h b/drivers/gpu/drm/nouveau/include/nvif/object.h index 8d205b6af46a..1b32dc701f61 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/object.h +++ b/drivers/gpu/drm/nouveau/include/nvif/object.h @@ -16,7 +16,7 @@ struct nvif_object { u32 handle; s32 oclass; void *priv; /*XXX: hack */ - struct { + struct nvif_map { void __iomem *ptr; u64 size; } map; diff --git a/drivers/gpu/drm/nouveau/include/nvif/push.h b/drivers/gpu/drm/nouveau/include/nvif/push.h index 6d3a8a3d2087..a493fababe3c 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/push.h +++ b/drivers/gpu/drm/nouveau/include/nvif/push.h @@ -31,6 +31,12 @@ struct nvif_push { void (*kick)(struct nvif_push *push); struct nvif_mem mem; + u64 addr; + + struct { + u32 get; + u32 max; + } hw; u32 *bgn; u32 *cur; @@ -41,7 +47,7 @@ struct nvif_push { static inline __must_check int PUSH_WAIT(struct nvif_push *push, u32 size) { - if (push->cur + size >= push->end) { + if (push->cur + size > push->end) { int ret = push->wait(push, size); if (ret) return ret; @@ -55,7 +61,11 @@ PUSH_WAIT(struct nvif_push *push, u32 size) static inline int PUSH_KICK(struct nvif_push *push) { - push->kick(push); + if (push->cur != push->bgn) { + push->kick(push); + push->bgn = push->cur; + } + return 0; } diff --git a/drivers/gpu/drm/nouveau/include/nvif/push906f.h b/drivers/gpu/drm/nouveau/include/nvif/push906f.h index cc2866bc8b0a..79df71de98d2 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/push906f.h +++ b/drivers/gpu/drm/nouveau/include/nvif/push906f.h @@ -7,6 +7,7 @@ #ifndef PUSH906F_SUBC // Host methods #define PUSH906F_SUBC_NV906F 0 +#define PUSH906F_SUBC_NVC36F 0 // Twod #define PUSH906F_SUBC_NV902D 3 diff --git a/drivers/gpu/drm/nouveau/include/nvif/pushc97b.h b/drivers/gpu/drm/nouveau/include/nvif/pushc97b.h new file mode 100644 index 000000000000..c8d6b6319134 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/pushc97b.h @@ -0,0 +1,18 @@ +#ifndef __NVIF_PUSHC97B_H__ +#define __NVIF_PUSHC97B_H__ +#include <nvif/push.h> + +#include <nvhw/class/clc97b.h> + +#define PUSH_HDR(p,m,c) do { \ + PUSH_ASSERT(!((m) & ~DRF_SMASK(NVC97B_DMA_METHOD_OFFSET)), "mthd"); \ + PUSH_ASSERT(!((c) & ~DRF_MASK(NVC97B_DMA_METHOD_COUNT)), "size"); \ + PUSH_DATA__((p), NVDEF(NVC97B, DMA, OPCODE, METHOD) | \ + NVVAL(NVC97B, DMA, METHOD_COUNT, (c)) | \ + NVVAL(NVC97B, DMA, METHOD_OFFSET, (m) >> 2), \ + " mthd 0x%04x size %d - %s", (u32)(m), (u32)(c), __func__); \ +} while(0) + +#define PUSH_MTHD_HDR(p,s,m,c) PUSH_HDR(p,m,c) +#define PUSH_MTHD_INC 4:4 +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index 46afb877a296..99579e7b9376 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -46,7 +46,10 @@ struct nvkm_device { GV100 = 0x140, TU100 = 0x160, GA100 = 0x170, + GH100 = 0x180, AD100 = 0x190, + GB10x = 0x1a0, + GB20x = 0x1b0, } card_type; u32 chipset; u8 chiprev; @@ -77,6 +80,13 @@ struct nvkm_device { struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int type, int inst); struct nvkm_engine *nvkm_device_engine(struct nvkm_device *, int type, int inst); +enum nvkm_bar_id { + NVKM_BAR_INVALID = 0, + NVKM_BAR0_PRI, + NVKM_BAR1_FB, + NVKM_BAR2_INST, +}; + struct nvkm_device_func { struct nvkm_device_pci *(*pci)(struct nvkm_device *); struct nvkm_device_tegra *(*tegra)(struct nvkm_device *); @@ -85,8 +95,8 @@ struct nvkm_device_func { int (*init)(struct nvkm_device *); void (*fini)(struct nvkm_device *, bool suspend); int (*irq)(struct nvkm_device *); - resource_size_t (*resource_addr)(struct nvkm_device *, unsigned bar); - resource_size_t (*resource_size)(struct nvkm_device *, unsigned bar); + resource_size_t (*resource_addr)(struct nvkm_device *, enum nvkm_bar_id); + resource_size_t (*resource_size)(struct nvkm_device *, enum nvkm_bar_id); bool cpu_coherent; }; @@ -124,6 +134,9 @@ struct nvkm_device *nvkm_device_find(u64 name); _temp; \ }) +#define NVKM_RD32_(p,o,dr) nvkm_rd32((p), (o) + (dr)) +#define NVKM_RD32(p,A...) DRF_RV(NVKM_RD32_, (p), 0, ##A) + void nvkm_device_del(struct nvkm_device **); struct nvkm_device_oclass { diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h index 9d2a1abf64f9..d92ffd17b729 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/layout.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: MIT */ +NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FSP , struct nvkm_fsp , fsp) NVKM_LAYOUT_ONCE(NVKM_SUBDEV_GSP , struct nvkm_gsp , gsp) NVKM_LAYOUT_ONCE(NVKM_SUBDEV_TOP , struct nvkm_top , top) NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VFN , struct nvkm_vfn , vfn) @@ -29,7 +30,7 @@ NVKM_LAYOUT_INST(NVKM_SUBDEV_IOCTRL , struct nvkm_subdev , ioctrl, 3) NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FLA , struct nvkm_subdev , fla) NVKM_LAYOUT_ONCE(NVKM_ENGINE_BSP , struct nvkm_engine , bsp) -NVKM_LAYOUT_INST(NVKM_ENGINE_CE , struct nvkm_engine , ce, 10) +NVKM_LAYOUT_INST(NVKM_ENGINE_CE , struct nvkm_engine , ce, 20) NVKM_LAYOUT_ONCE(NVKM_ENGINE_CIPHER , struct nvkm_engine , cipher) NVKM_LAYOUT_ONCE(NVKM_ENGINE_DISP , struct nvkm_disp , disp) NVKM_LAYOUT_ONCE(NVKM_ENGINE_DMAOBJ , struct nvkm_dma , dma) @@ -43,9 +44,9 @@ NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSPDEC , struct nvkm_engine , mspdec) NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSPPP , struct nvkm_engine , msppp) NVKM_LAYOUT_ONCE(NVKM_ENGINE_MSVLD , struct nvkm_engine , msvld) NVKM_LAYOUT_INST(NVKM_ENGINE_NVDEC , struct nvkm_nvdec , nvdec, 8) -NVKM_LAYOUT_INST(NVKM_ENGINE_NVENC , struct nvkm_nvenc , nvenc, 3) +NVKM_LAYOUT_INST(NVKM_ENGINE_NVENC , struct nvkm_nvenc , nvenc, 4) NVKM_LAYOUT_INST(NVKM_ENGINE_NVJPG , struct nvkm_engine , nvjpg, 8) -NVKM_LAYOUT_ONCE(NVKM_ENGINE_OFA , struct nvkm_engine , ofa) +NVKM_LAYOUT_INST(NVKM_ENGINE_OFA , struct nvkm_engine , ofa, 2) NVKM_LAYOUT_ONCE(NVKM_ENGINE_SEC , struct nvkm_engine , sec) NVKM_LAYOUT_ONCE(NVKM_ENGINE_SEC2 , struct nvkm_sec2 , sec2) NVKM_LAYOUT_ONCE(NVKM_ENGINE_SW , struct nvkm_sw , sw) diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h index 3e8db8280e2a..7903d7470d19 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h @@ -87,5 +87,4 @@ int gp102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct int gv100_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **); int tu102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **); int ga102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **); -int ad102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index be508f65b280..96c16cfccf16 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -78,9 +78,6 @@ struct nvkm_fifo { struct { struct nvkm_memory *mem; struct nvkm_vma *bar1; - - struct mutex mutex; - struct list_head list; } userd; struct { diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h index 8145796ffc61..a2333cfe6955 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h @@ -55,5 +55,4 @@ int gp10b_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct n int gv100_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **); int tu102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **); int ga102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **); -int ad102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvdec.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvdec.h index 8d2e170883e1..ca83caa55157 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvdec.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvdec.h @@ -13,7 +13,5 @@ struct nvkm_nvdec { int gm107_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **); int tu102_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **); -int ga100_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **); int ga102_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **); -int ad102_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvenc.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvenc.h index 018c58fc32ba..1f6eef13f872 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvenc.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvenc.h @@ -13,6 +13,4 @@ struct nvkm_nvenc { int gm107_nvenc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvenc **); int tu102_nvenc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvenc **); -int ga102_nvenc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvenc **); -int ad102_nvenc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvenc **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvjpg.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/nvjpg.h deleted file mode 100644 index 80b7933a789e..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/nvjpg.h +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVKM_NVJPG_H__ -#define __NVKM_NVJPG_H__ -#include <core/engine.h> - -int ga100_nvjpg_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **); -int ad102_nvjpg_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **); -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/ofa.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/ofa.h deleted file mode 100644 index e72e2115333b..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/ofa.h +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVKM_OFA_H__ -#define __NVKM_OFA_H__ -#include <core/engine.h> - -int ga100_ofa_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **); -int ga102_ofa_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **); -int ad102_ofa_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **); -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 5b798a1a313d..e0d777a933e1 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -102,6 +102,9 @@ int gv100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct n int tu102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int ga100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); int ga102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); +int gh100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); +int gb100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); +int gb202_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fb **); #include <subdev/bios.h> #include <subdev/bios/ramcfg.h> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h new file mode 100644 index 000000000000..8a3dbb1cbb46 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fsp.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_FSP_H__ +#define __NVKM_FSP_H__ +#include <core/subdev.h> +#include <core/falcon.h> + +struct nvkm_fsp { + const struct nvkm_fsp_func *func; + struct nvkm_subdev subdev; + + struct nvkm_falcon falcon; +}; + +bool nvkm_fsp_verify_gsp_fmc(struct nvkm_fsp *, u32 hash_size, u32 pkey_size, u32 sig_size); +int nvkm_fsp_boot_gsp_fmc(struct nvkm_fsp *, u64 args_addr, u32 rsvd_size, bool resume, + u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig); + +int gh100_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); +int gb100_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); +int gb202_fsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h index 1c12854a8550..226c7ec56b8e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -17,6 +17,9 @@ struct nvkm_gsp_mem { dma_addr_t addr; }; +int nvkm_gsp_mem_ctor(struct nvkm_gsp *, size_t size, struct nvkm_gsp_mem *); +void nvkm_gsp_mem_dtor(struct nvkm_gsp_mem *); + struct nvkm_gsp_radix3 { struct nvkm_gsp_mem lvl0; struct nvkm_gsp_mem lvl1; @@ -65,6 +68,9 @@ struct nvkm_gsp { const struct firmware *load; const struct firmware *unload; } booter; + + const struct firmware *fmc; + const struct firmware *bl; const struct firmware *rm; } fws; @@ -112,6 +118,15 @@ struct nvkm_gsp { struct { struct nvkm_gsp_mem fw; + u8 *hash; + u8 *pkey; + u8 *sig; + + struct nvkm_gsp_mem args; + } fmc; + + struct { + struct nvkm_gsp_mem fw; u32 code_offset; u32 data_offset; u32 manifest_offset; @@ -130,6 +145,7 @@ struct nvkm_gsp { struct sg_table sgt; struct nvkm_gsp_radix3 radix3; struct nvkm_gsp_mem meta; + struct sg_table fbsr; } sr; struct { @@ -209,32 +225,7 @@ struct nvkm_gsp { u8 tpcs; } gr; - const struct nvkm_gsp_rm { - void *(*rpc_get)(struct nvkm_gsp *, u32 fn, u32 argc); - void *(*rpc_push)(struct nvkm_gsp *gsp, void *argv, - enum nvkm_gsp_rpc_reply_policy policy, u32 repc); - void (*rpc_done)(struct nvkm_gsp *gsp, void *repv); - - void *(*rm_ctrl_get)(struct nvkm_gsp_object *, u32 cmd, u32 argc); - int (*rm_ctrl_push)(struct nvkm_gsp_object *, void **argv, u32 repc); - void (*rm_ctrl_done)(struct nvkm_gsp_object *, void *repv); - - void *(*rm_alloc_get)(struct nvkm_gsp_object *, u32 oclass, u32 argc); - void *(*rm_alloc_push)(struct nvkm_gsp_object *, void *argv); - void (*rm_alloc_done)(struct nvkm_gsp_object *, void *repv); - - int (*rm_free)(struct nvkm_gsp_object *); - - int (*client_ctor)(struct nvkm_gsp *, struct nvkm_gsp_client *); - void (*client_dtor)(struct nvkm_gsp_client *); - - int (*device_ctor)(struct nvkm_gsp_client *, struct nvkm_gsp_device *); - void (*device_dtor)(struct nvkm_gsp_device *); - - int (*event_ctor)(struct nvkm_gsp_device *, u32 handle, u32 id, - nvkm_gsp_event_func, struct nvkm_gsp_event *); - void (*event_dtor)(struct nvkm_gsp_event *); - } *rm; + struct nvkm_rm *rm; struct { struct mutex mutex; @@ -272,17 +263,19 @@ nvkm_gsp_rm(struct nvkm_gsp *gsp) return gsp && (gsp->fws.rm || gsp->fw.img); } +#include <rm/rm.h> + static inline void * nvkm_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 argc) { - return gsp->rm->rpc_get(gsp, fn, argc); + return gsp->rm->api->rpc->get(gsp, fn, argc); } static inline void * nvkm_gsp_rpc_push(struct nvkm_gsp *gsp, void *argv, enum nvkm_gsp_rpc_reply_policy policy, u32 repc) { - return gsp->rm->rpc_push(gsp, argv, policy, repc); + return gsp->rm->api->rpc->push(gsp, argv, policy, repc); } static inline void * @@ -311,19 +304,19 @@ nvkm_gsp_rpc_wr(struct nvkm_gsp *gsp, void *argv, static inline void nvkm_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv) { - gsp->rm->rpc_done(gsp, repv); + gsp->rm->api->rpc->done(gsp, repv); } static inline void * nvkm_gsp_rm_ctrl_get(struct nvkm_gsp_object *object, u32 cmd, u32 argc) { - return object->client->gsp->rm->rm_ctrl_get(object, cmd, argc); + return object->client->gsp->rm->api->ctrl->get(object, cmd, argc); } static inline int nvkm_gsp_rm_ctrl_push(struct nvkm_gsp_object *object, void *argv, u32 repc) { - return object->client->gsp->rm->rm_ctrl_push(object, argv, repc); + return object->client->gsp->rm->api->ctrl->push(object, argv, repc); } static inline void * @@ -354,7 +347,7 @@ nvkm_gsp_rm_ctrl_wr(struct nvkm_gsp_object *object, void *argv) static inline void nvkm_gsp_rm_ctrl_done(struct nvkm_gsp_object *object, void *repv) { - object->client->gsp->rm->rm_ctrl_done(object, repv); + object->client->gsp->rm->api->ctrl->done(object, repv); } static inline void * @@ -369,7 +362,7 @@ nvkm_gsp_rm_alloc_get(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u3 object->parent = parent; object->handle = handle; - argv = gsp->rm->rm_alloc_get(object, oclass, argc); + argv = gsp->rm->api->alloc->get(object, oclass, argc); if (IS_ERR_OR_NULL(argv)) { object->client = NULL; return argv; @@ -381,7 +374,7 @@ nvkm_gsp_rm_alloc_get(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u3 static inline void * nvkm_gsp_rm_alloc_push(struct nvkm_gsp_object *object, void *argv) { - void *repv = object->client->gsp->rm->rm_alloc_push(object, argv); + void *repv = object->client->gsp->rm->api->alloc->push(object, argv); if (IS_ERR(repv)) object->client = NULL; @@ -403,7 +396,7 @@ nvkm_gsp_rm_alloc_wr(struct nvkm_gsp_object *object, void *argv) static inline void nvkm_gsp_rm_alloc_done(struct nvkm_gsp_object *object, void *repv) { - object->client->gsp->rm->rm_alloc_done(object, repv); + object->client->gsp->rm->api->alloc->done(object, repv); } static inline int @@ -421,39 +414,29 @@ nvkm_gsp_rm_alloc(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 ar static inline int nvkm_gsp_rm_free(struct nvkm_gsp_object *object) { - if (object->client) - return object->client->gsp->rm->rm_free(object); + if (object->client) { + int ret = object->client->gsp->rm->api->alloc->free(object); + object->client = NULL; + return ret; + } return 0; } -static inline int -nvkm_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client) -{ - if (WARN_ON(!gsp->rm)) - return -ENOSYS; - - return gsp->rm->client_ctor(gsp, client); -} - -static inline void -nvkm_gsp_client_dtor(struct nvkm_gsp_client *client) -{ - if (client->gsp) - client->gsp->rm->client_dtor(client); -} +int nvkm_gsp_client_ctor(struct nvkm_gsp *, struct nvkm_gsp_client *); +void nvkm_gsp_client_dtor(struct nvkm_gsp_client *); static inline int nvkm_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device) { - return client->gsp->rm->device_ctor(client, device); + return client->gsp->rm->api->device->ctor(client, device); } static inline void nvkm_gsp_device_dtor(struct nvkm_gsp_device *device) { if (device->object.client) - device->object.client->gsp->rm->device_dtor(device); + device->object.client->gsp->rm->api->device->dtor(device); } static inline int @@ -485,7 +468,9 @@ static inline int nvkm_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id, nvkm_gsp_event_func func, struct nvkm_gsp_event *event) { - return device->object.client->gsp->rm->event_ctor(device, handle, id, func, event); + struct nvkm_rm *rm = device->object.client->gsp->rm; + + return rm->api->device->event.ctor(device, handle, id, func, event); } static inline void @@ -494,7 +479,7 @@ nvkm_gsp_event_dtor(struct nvkm_gsp_event *event) struct nvkm_gsp_device *device = event->device; if (device) - device->object.client->gsp->rm->event_dtor(event); + device->object.client->gsp->rm->api->device->event.dtor(event); } int nvkm_gsp_intr_stall(struct nvkm_gsp *, enum nvkm_subdev_type, int); @@ -505,5 +490,8 @@ int tu102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_ int tu116_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); int ga100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); int ga102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); +int gh100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); int ad102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); +int gb100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); +int gb202_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h index e10cbd9203ec..db835cf7b8ac 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h @@ -24,11 +24,6 @@ struct nvkm_instmem { struct nvkm_ramht *ramht; struct nvkm_memory *ramro; struct nvkm_memory *ramfc; - - struct { - struct sg_table fbsr; - bool fbsr_valid; - } rm; }; u32 nvkm_instmem_rd32(struct nvkm_instmem *, u32 addr); @@ -41,4 +36,5 @@ int nv04_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nv int nv40_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **); int nv50_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **); int gk20a_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **); +int gh100_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 935b1cacd528..abcb0dbcde70 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -8,7 +8,7 @@ struct nvkm_vma { struct list_head head; struct rb_node tree; u64 addr; - u64 size:50; + u64 size; bool mapref:1; /* PTs (de)referenced on (un)map (vs pre-allocated). */ bool sparse:1; /* Unmapped PDEs/PTEs will not trigger MMU faults. */ #define NVKM_VMA_PAGE_NONE 7 @@ -73,6 +73,7 @@ struct nvkm_vmm { struct nvkm_gsp_object object; struct nvkm_vma *rsvd; + bool external; } rm; }; @@ -165,4 +166,5 @@ int gp100_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct int gp10b_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **); int gv100_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **); int tu102_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **); +int gh100_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h index 3c103101d5fc..112b674ed9c8 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h @@ -50,6 +50,7 @@ int gf100_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct int gf106_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **); int gk104_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **); int gp100_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **); +int gh100_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **); /* pcie functions */ int nvkm_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8 width); diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0000.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0000.h deleted file mode 100644 index 7a3fc023072d..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0000.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_class_cl0000_h__ -#define __src_common_sdk_nvidia_inc_class_cl0000_h__ -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvlimits.h> - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2001-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV01_ROOT (0x0U) /* finn: Evaluated from "NV0000_ALLOC_PARAMETERS_MESSAGE_ID" */ - -typedef struct NV0000_ALLOC_PARAMETERS { - NvHandle hClient; /* CORERM-2934: hClient must remain the first member until all allocations use these params */ - NvU32 processID; - char processName[NV_PROC_NAME_MAX_LENGTH]; -} NV0000_ALLOC_PARAMETERS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0005.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0005.h deleted file mode 100644 index e4de36d63666..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0005.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_class_cl0005_h__ -#define __src_common_sdk_nvidia_inc_class_cl0005_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2001-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct NV0005_ALLOC_PARAMETERS { - NvHandle hParentClient; - NvHandle hSrcResource; - - NvV32 hClass; - NvV32 notifyIndex; - NV_DECLARE_ALIGNED(NvP64 data, 8); -} NV0005_ALLOC_PARAMETERS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0080.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0080.h deleted file mode 100644 index 8868118e47d6..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0080.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_class_cl0080_h__ -#define __src_common_sdk_nvidia_inc_class_cl0080_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2001-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV01_DEVICE_0 (0x80U) /* finn: Evaluated from "NV0080_ALLOC_PARAMETERS_MESSAGE_ID" */ - -typedef struct NV0080_ALLOC_PARAMETERS { - NvU32 deviceId; - NvHandle hClientShare; - NvHandle hTargetClient; - NvHandle hTargetDevice; - NvV32 flags; - NV_DECLARE_ALIGNED(NvU64 vaSpaceSize, 8); - NV_DECLARE_ALIGNED(NvU64 vaStartInternal, 8); - NV_DECLARE_ALIGNED(NvU64 vaLimitInternal, 8); - NvV32 vaMode; -} NV0080_ALLOC_PARAMETERS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080.h deleted file mode 100644 index 9040ea5608a0..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_class_cl2080_h__ -#define __src_common_sdk_nvidia_inc_class_cl2080_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2002-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV20_SUBDEVICE_0 (0x2080U) /* finn: Evaluated from "NV2080_ALLOC_PARAMETERS_MESSAGE_ID" */ - -typedef struct NV2080_ALLOC_PARAMETERS { - NvU32 subDeviceId; -} NV2080_ALLOC_PARAMETERS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080_notification.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080_notification.h deleted file mode 100644 index ba659d6477d3..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080_notification.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_class_cl2080_notification_h__ -#define __src_common_sdk_nvidia_inc_class_cl2080_notification_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV2080_NOTIFIERS_HOTPLUG (1) - -#define NV2080_NOTIFIERS_DP_IRQ (7) - -#define NV2080_ENGINE_TYPE_GRAPHICS (0x00000001) -#define NV2080_ENGINE_TYPE_GR0 NV2080_ENGINE_TYPE_GRAPHICS - -#define NV2080_ENGINE_TYPE_COPY0 (0x00000009) - -#define NV2080_ENGINE_TYPE_BSP (0x00000013) -#define NV2080_ENGINE_TYPE_NVDEC0 NV2080_ENGINE_TYPE_BSP - -#define NV2080_ENGINE_TYPE_MSENC (0x0000001b) -#define NV2080_ENGINE_TYPE_NVENC0 NV2080_ENGINE_TYPE_MSENC /* Mutually exclusive alias */ - -#define NV2080_ENGINE_TYPE_SW (0x00000022) - -#define NV2080_ENGINE_TYPE_SEC2 (0x00000026) - -#define NV2080_ENGINE_TYPE_NVJPG (0x0000002b) -#define NV2080_ENGINE_TYPE_NVJPEG0 NV2080_ENGINE_TYPE_NVJPG - -#define NV2080_ENGINE_TYPE_OFA (0x00000033) - -typedef struct { - NvU32 plugDisplayMask; - NvU32 unplugDisplayMask; -} Nv2080HotplugNotification; - -typedef struct Nv2080DpIrqNotificationRec { - NvU32 displayId; -} Nv2080DpIrqNotification; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl84a0.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl84a0.h deleted file mode 100644 index 9eb780a1ac72..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl84a0.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_class_cl84a0_h__ -#define __src_common_sdk_nvidia_inc_class_cl84a0_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2001-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV01_MEMORY_LIST_SYSTEM (0x00000081) - -#define NV01_MEMORY_LIST_FBMEM (0x00000082) - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl90f1.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl90f1.h deleted file mode 100644 index f1d21776e395..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/cl90f1.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_class_cl90f1_h__ -#define __src_common_sdk_nvidia_inc_class_cl90f1_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2011 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define FERMI_VASPACE_A (0x000090f1) - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/clc0b5sw.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/clc0b5sw.h deleted file mode 100644 index b8f32576cfaa..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/class/clc0b5sw.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_class_clc0b5sw_h__ -#define __src_common_sdk_nvidia_inc_class_clc0b5sw_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct NVC0B5_ALLOCATION_PARAMETERS { - NvU32 version; - NvU32 engineType; -} NVC0B5_ALLOCATION_PARAMETERS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073common.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073common.h deleted file mode 100644 index 58b3ba7badf1..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073common.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073common_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073common_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct NV0073_CTRL_CMD_DSC_CAP_PARAMS { - NvBool bDscSupported; - NvU32 encoderColorFormatMask; - NvU32 lineBufferSizeKB; - NvU32 rateBufferSizeKB; - NvU32 bitsPerPixelPrecision; - NvU32 maxNumHztSlices; - NvU32 lineBufferBitDepth; -} NV0073_CTRL_CMD_DSC_CAP_PARAMS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dfp.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dfp.h deleted file mode 100644 index 596f2ea8344e..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dfp.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073dfp_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073dfp_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2005-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV0073_CTRL_CMD_DFP_GET_INFO (0x731140U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DFP_INTERFACE_ID << 8) | NV0073_CTRL_DFP_GET_INFO_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_DFP_GET_INFO_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 flags; - NvU32 flags2; -} NV0073_CTRL_DFP_GET_INFO_PARAMS; - -#define NV0073_CTRL_DFP_FLAGS_SIGNAL 2:0 -#define NV0073_CTRL_DFP_FLAGS_SIGNAL_TMDS (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_SIGNAL_LVDS (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_SIGNAL_SDI (0x00000002U) -#define NV0073_CTRL_DFP_FLAGS_SIGNAL_DISPLAYPORT (0x00000003U) -#define NV0073_CTRL_DFP_FLAGS_SIGNAL_DSI (0x00000004U) -#define NV0073_CTRL_DFP_FLAGS_SIGNAL_WRBK (0x00000005U) -#define NV0073_CTRL_DFP_FLAGS_LANE 5:3 -#define NV0073_CTRL_DFP_FLAGS_LANE_NONE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_LANE_SINGLE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_LANE_DUAL (0x00000002U) -#define NV0073_CTRL_DFP_FLAGS_LANE_QUAD (0x00000003U) -#define NV0073_CTRL_DFP_FLAGS_LANE_OCT (0x00000004U) -#define NV0073_CTRL_DFP_FLAGS_LIMIT 6:6 -#define NV0073_CTRL_DFP_FLAGS_LIMIT_DISABLE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_LIMIT_60HZ_RR (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_SLI_SCALER 7:7 -#define NV0073_CTRL_DFP_FLAGS_SLI_SCALER_NORMAL (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_SLI_SCALER_DISABLE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_HDMI_CAPABLE 8:8 -#define NV0073_CTRL_DFP_FLAGS_HDMI_CAPABLE_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_HDMI_CAPABLE_TRUE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_RANGE_LIMITED_CAPABLE 9:9 -#define NV0073_CTRL_DFP_FLAGS_RANGE_LIMITED_CAPABLE_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_RANGE_LIMITED_CAPABLE_TRUE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_RANGE_AUTO_CAPABLE 10:10 -#define NV0073_CTRL_DFP_FLAGS_RANGE_AUTO_CAPABLE_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_RANGE_AUTO_CAPABLE_TRUE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR422_CAPABLE 11:11 -#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR422_CAPABLE_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR422_CAPABLE_TRUE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR444_CAPABLE 12:12 -#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR444_CAPABLE_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR444_CAPABLE_TRUE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_HDMI_ALLOWED 14:14 -#define NV0073_CTRL_DFP_FLAGS_HDMI_ALLOWED_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_HDMI_ALLOWED_TRUE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_EMBEDDED_DISPLAYPORT 15:15 -#define NV0073_CTRL_DFP_FLAGS_EMBEDDED_DISPLAYPORT_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_EMBEDDED_DISPLAYPORT_TRUE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_DP_LINK_CONSTRAINT 16:16 -#define NV0073_CTRL_DFP_FLAGS_DP_LINK_CONSTRAINT_NONE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_DP_LINK_CONSTRAINT_PREFER_RBR (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW 19:17 -#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_1_62GBPS (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_2_70GBPS (0x00000002U) -#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_5_40GBPS (0x00000003U) -#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_8_10GBPS (0x00000004U) -#define NV0073_CTRL_DFP_FLAGS_LINK 21:20 -#define NV0073_CTRL_DFP_FLAGS_LINK_NONE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_LINK_SINGLE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_LINK_DUAL (0x00000002U) -#define NV0073_CTRL_DFP_FLAGS_DP_FORCE_RM_EDID 22:22 -#define NV0073_CTRL_DFP_FLAGS_DP_FORCE_RM_EDID_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_DP_FORCE_RM_EDID_TRUE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID 24:23 -#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_NONE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_A (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_B (0x00000002U) -#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_GANGED (0x00000003U) -#define NV0073_CTRL_DFP_FLAGS_DP_POST_CURSOR2_DISABLED 25:25 -#define NV0073_CTRL_DFP_FLAGS_DP_POST_CURSOR2_DISABLED_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_DP_POST_CURSOR2_DISABLED_TRUE (0x00000001U) -#define NV0073_CTRL_DFP_FLAGS_DP_PHY_REPEATER_COUNT 29:26 -#define NV0073_CTRL_DFP_FLAGS_DYNAMIC_MUX_CAPABLE 30:30 -#define NV0073_CTRL_DFP_FLAGS_DYNAMIC_MUX_CAPABLE_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_FLAGS_DYNAMIC_MUX_CAPABLE_TRUE (0x00000001U) - -#define NV0073_CTRL_CMD_DFP_SET_ELD_AUDIO_CAPS (0x731144U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DFP_INTERFACE_ID << 8) | NV0073_CTRL_DFP_SET_ELD_AUDIO_CAP_PARAMS_MESSAGE_ID" */ - -#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_ELD_BUFFER 96U - -typedef struct NV0073_CTRL_DFP_SET_ELD_AUDIO_CAP_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 numELDSize; - NvU8 bufferELD[NV0073_CTRL_DFP_ELD_AUDIO_CAPS_ELD_BUFFER]; - NvU32 maxFreqSupported; - NvU32 ctrl; - NvU32 deviceEntry; -} NV0073_CTRL_DFP_SET_ELD_AUDIO_CAP_PARAMS; - -#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_PD 0:0 -#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_PD_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_PD_TRUE (0x00000001U) -#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_ELDV 1:1 -#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_ELDV_FALSE (0x00000000U) -#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_ELDV_TRUE (0x00000001U) - -#define NV0073_CTRL_CMD_DFP_SET_AUDIO_ENABLE (0x731150U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DFP_INTERFACE_ID << 8) | NV0073_CTRL_DFP_SET_AUDIO_ENABLE_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_DFP_SET_AUDIO_ENABLE_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvBool enable; -} NV0073_CTRL_DFP_SET_AUDIO_ENABLE_PARAMS; - -typedef NvU32 NV0073_CTRL_DFP_ASSIGN_SOR_LINKCONFIG; - -typedef struct NV0073_CTRL_DFP_ASSIGN_SOR_INFO { - NvU32 displayMask; - NvU32 sorType; -} NV0073_CTRL_DFP_ASSIGN_SOR_INFO; - -#define NV0073_CTRL_CMD_DFP_ASSIGN_SOR (0x731152U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DFP_INTERFACE_ID << 8) | NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS_MESSAGE_ID" */ - -#define NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS 4U - -typedef struct NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU8 sorExcludeMask; - NvU32 slaveDisplayId; - NV0073_CTRL_DFP_ASSIGN_SOR_LINKCONFIG forceSublinkConfig; - NvBool bIs2Head1Or; - NvU32 sorAssignList[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS]; - NV0073_CTRL_DFP_ASSIGN_SOR_INFO sorAssignListWithTag[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS]; - NvU8 reservedSorMask; - NvU32 flags; -} NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS; - -#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_AUDIO 0:0 -#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_AUDIO_OPTIMAL (0x00000001U) -#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_AUDIO_DEFAULT (0x00000000U) -#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_ACTIVE_SOR_NOT_AUDIO_CAPABLE 1:1 -#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_ACTIVE_SOR_NOT_AUDIO_CAPABLE_NO (0x00000000U) -#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_ACTIVE_SOR_NOT_AUDIO_CAPABLE_YES (0x00000001U) - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dp.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dp.h deleted file mode 100644 index bae4b1997736..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dp.h +++ /dev/null @@ -1,335 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073dp_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073dp_h__ -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073common.h> - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2005-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV0073_CTRL_CMD_DP_AUXCH_CTRL (0x731341U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_DP_AUXCH_CTRL_PARAMS_MESSAGE_ID" */ - -#define NV0073_CTRL_DP_AUXCH_MAX_DATA_SIZE 16U - -typedef struct NV0073_CTRL_DP_AUXCH_CTRL_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvBool bAddrOnly; - NvU32 cmd; - NvU32 addr; - NvU8 data[NV0073_CTRL_DP_AUXCH_MAX_DATA_SIZE]; - NvU32 size; - NvU32 replyType; - NvU32 retryTimeMs; -} NV0073_CTRL_DP_AUXCH_CTRL_PARAMS; - -#define NV0073_CTRL_DP_AUXCH_CMD_TYPE 3:3 -#define NV0073_CTRL_DP_AUXCH_CMD_TYPE_I2C (0x00000000U) -#define NV0073_CTRL_DP_AUXCH_CMD_TYPE_AUX (0x00000001U) -#define NV0073_CTRL_DP_AUXCH_CMD_I2C_MOT 2:2 -#define NV0073_CTRL_DP_AUXCH_CMD_I2C_MOT_FALSE (0x00000000U) -#define NV0073_CTRL_DP_AUXCH_CMD_I2C_MOT_TRUE (0x00000001U) -#define NV0073_CTRL_DP_AUXCH_CMD_REQ_TYPE 1:0 -#define NV0073_CTRL_DP_AUXCH_CMD_REQ_TYPE_WRITE (0x00000000U) -#define NV0073_CTRL_DP_AUXCH_CMD_REQ_TYPE_READ (0x00000001U) -#define NV0073_CTRL_DP_AUXCH_CMD_REQ_TYPE_WRITE_STATUS (0x00000002U) - -#define NV0073_CTRL_CMD_DP_CTRL (0x731343U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_DP_CTRL_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_DP_CTRL_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 cmd; - NvU32 data; - NvU32 err; - NvU32 retryTimeMs; - NvU32 eightLaneDpcdBaseAddr; -} NV0073_CTRL_DP_CTRL_PARAMS; - -#define NV0073_CTRL_DP_CMD_SET_LANE_COUNT 0:0 -#define NV0073_CTRL_DP_CMD_SET_LANE_COUNT_FALSE (0x00000000U) -#define NV0073_CTRL_DP_CMD_SET_LANE_COUNT_TRUE (0x00000001U) -#define NV0073_CTRL_DP_CMD_SET_LINK_BW 1:1 -#define NV0073_CTRL_DP_CMD_SET_LINK_BW_FALSE (0x00000000U) -#define NV0073_CTRL_DP_CMD_SET_LINK_BW_TRUE (0x00000001U) -#define NV0073_CTRL_DP_CMD_DISABLE_DOWNSPREAD 2:2 -#define NV0073_CTRL_DP_CMD_DISABLE_DOWNSPREAD_FALSE (0x00000000U) -#define NV0073_CTRL_DP_CMD_DISABLE_DOWNSPREAD_TRUE (0x00000001U) -#define NV0073_CTRL_DP_CMD_UNUSED 3:3 -#define NV0073_CTRL_DP_CMD_SET_FORMAT_MODE 4:4 -#define NV0073_CTRL_DP_CMD_SET_FORMAT_MODE_SINGLE_STREAM (0x00000000U) -#define NV0073_CTRL_DP_CMD_SET_FORMAT_MODE_MULTI_STREAM (0x00000001U) -#define NV0073_CTRL_DP_CMD_FAST_LINK_TRAINING 5:5 -#define NV0073_CTRL_DP_CMD_FAST_LINK_TRAINING_NO (0x00000000U) -#define NV0073_CTRL_DP_CMD_FAST_LINK_TRAINING_YES (0x00000001U) -#define NV0073_CTRL_DP_CMD_NO_LINK_TRAINING 6:6 -#define NV0073_CTRL_DP_CMD_NO_LINK_TRAINING_NO (0x00000000U) -#define NV0073_CTRL_DP_CMD_NO_LINK_TRAINING_YES (0x00000001U) -#define NV0073_CTRL_DP_CMD_SET_ENHANCED_FRAMING 7:7 -#define NV0073_CTRL_DP_CMD_SET_ENHANCED_FRAMING_FALSE (0x00000000U) -#define NV0073_CTRL_DP_CMD_SET_ENHANCED_FRAMING_TRUE (0x00000001U) -#define NV0073_CTRL_DP_CMD_USE_DOWNSPREAD_SETTING 8:8 -#define NV0073_CTRL_DP_CMD_USE_DOWNSPREAD_SETTING_DEFAULT (0x00000000U) -#define NV0073_CTRL_DP_CMD_USE_DOWNSPREAD_SETTING_FORCE (0x00000001U) -#define NV0073_CTRL_DP_CMD_SKIP_HW_PROGRAMMING 9:9 -#define NV0073_CTRL_DP_CMD_SKIP_HW_PROGRAMMING_NO (0x00000000U) -#define NV0073_CTRL_DP_CMD_SKIP_HW_PROGRAMMING_YES (0x00000001U) -#define NV0073_CTRL_DP_CMD_POST_LT_ADJ_REQ_GRANTED 10:10 -#define NV0073_CTRL_DP_CMD_POST_LT_ADJ_REQ_GRANTED_NO (0x00000000U) -#define NV0073_CTRL_DP_CMD_POST_LT_ADJ_REQ_GRANTED_YES (0x00000001U) -#define NV0073_CTRL_DP_CMD_FAKE_LINK_TRAINING 12:11 -#define NV0073_CTRL_DP_CMD_FAKE_LINK_TRAINING_NO (0x00000000U) -#define NV0073_CTRL_DP_CMD_FAKE_LINK_TRAINING_DONOT_TOGGLE_TRANSMISSION (0x00000001U) -#define NV0073_CTRL_DP_CMD_FAKE_LINK_TRAINING_TOGGLE_TRANSMISSION_ON (0x00000002U) -#define NV0073_CTRL_DP_CMD_TRAIN_PHY_REPEATER 13:13 -#define NV0073_CTRL_DP_CMD_TRAIN_PHY_REPEATER_NO (0x00000000U) -#define NV0073_CTRL_DP_CMD_TRAIN_PHY_REPEATER_YES (0x00000001U) -#define NV0073_CTRL_DP_CMD_FALLBACK_CONFIG 14:14 -#define NV0073_CTRL_DP_CMD_FALLBACK_CONFIG_FALSE (0x00000000U) -#define NV0073_CTRL_DP_CMD_FALLBACK_CONFIG_TRUE (0x00000001U) -#define NV0073_CTRL_DP_CMD_ENABLE_FEC 15:15 -#define NV0073_CTRL_DP_CMD_ENABLE_FEC_FALSE (0x00000000U) -#define NV0073_CTRL_DP_CMD_ENABLE_FEC_TRUE (0x00000001U) - -#define NV0073_CTRL_DP_CMD_BANDWIDTH_TEST 29:29 -#define NV0073_CTRL_DP_CMD_BANDWIDTH_TEST_NO (0x00000000U) -#define NV0073_CTRL_DP_CMD_BANDWIDTH_TEST_YES (0x00000001U) -#define NV0073_CTRL_DP_CMD_LINK_CONFIG_CHECK_DISABLE 30:30 -#define NV0073_CTRL_DP_CMD_LINK_CONFIG_CHECK_DISABLE_FALSE (0x00000000U) -#define NV0073_CTRL_DP_CMD_LINK_CONFIG_CHECK_DISABLE_TRUE (0x00000001U) -#define NV0073_CTRL_DP_CMD_DISABLE_LINK_CONFIG 31:31 -#define NV0073_CTRL_DP_CMD_DISABLE_LINK_CONFIG_FALSE (0x00000000U) -#define NV0073_CTRL_DP_CMD_DISABLE_LINK_CONFIG_TRUE (0x00000001U) - -#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT 4:0 -#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT_0 (0x00000000U) -#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT_1 (0x00000001U) -#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT_2 (0x00000002U) -#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT_4 (0x00000004U) -#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT_8 (0x00000008U) -#define NV0073_CTRL_DP_DATA_SET_LINK_BW 15:8 -#define NV0073_CTRL_DP_DATA_SET_LINK_BW_1_62GBPS (0x00000006U) -#define NV0073_CTRL_DP_DATA_SET_LINK_BW_2_16GBPS (0x00000008U) -#define NV0073_CTRL_DP_DATA_SET_LINK_BW_2_43GBPS (0x00000009U) -#define NV0073_CTRL_DP_DATA_SET_LINK_BW_2_70GBPS (0x0000000AU) -#define NV0073_CTRL_DP_DATA_SET_LINK_BW_3_24GBPS (0x0000000CU) -#define NV0073_CTRL_DP_DATA_SET_LINK_BW_4_32GBPS (0x00000010U) -#define NV0073_CTRL_DP_DATA_SET_LINK_BW_5_40GBPS (0x00000014U) -#define NV0073_CTRL_DP_DATA_SET_LINK_BW_8_10GBPS (0x0000001EU) -#define NV0073_CTRL_DP_DATA_SET_ENHANCED_FRAMING 18:18 -#define NV0073_CTRL_DP_DATA_SET_ENHANCED_FRAMING_NO (0x00000000U) -#define NV0073_CTRL_DP_DATA_SET_ENHANCED_FRAMING_YES (0x00000001U) -#define NV0073_CTRL_DP_DATA_TARGET 22:19 -#define NV0073_CTRL_DP_DATA_TARGET_SINK (0x00000000U) -#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_0 (0x00000001U) -#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_1 (0x00000002U) -#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_2 (0x00000003U) -#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_3 (0x00000004U) -#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_4 (0x00000005U) -#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_5 (0x00000006U) -#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_6 (0x00000007U) -#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_7 (0x00000008U) - -#define NV0073_CTRL_MAX_LANES 8U - -typedef struct NV0073_CTRL_DP_LANE_DATA_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 numLanes; - NvU32 data[NV0073_CTRL_MAX_LANES]; -} NV0073_CTRL_DP_LANE_DATA_PARAMS; - -#define NV0073_CTRL_DP_LANE_DATA_PREEMPHASIS 1:0 -#define NV0073_CTRL_DP_LANE_DATA_PREEMPHASIS_NONE (0x00000000U) -#define NV0073_CTRL_DP_LANE_DATA_PREEMPHASIS_LEVEL1 (0x00000001U) -#define NV0073_CTRL_DP_LANE_DATA_PREEMPHASIS_LEVEL2 (0x00000002U) -#define NV0073_CTRL_DP_LANE_DATA_PREEMPHASIS_LEVEL3 (0x00000003U) -#define NV0073_CTRL_DP_LANE_DATA_DRIVECURRENT 3:2 -#define NV0073_CTRL_DP_LANE_DATA_DRIVECURRENT_LEVEL0 (0x00000000U) -#define NV0073_CTRL_DP_LANE_DATA_DRIVECURRENT_LEVEL1 (0x00000001U) -#define NV0073_CTRL_DP_LANE_DATA_DRIVECURRENT_LEVEL2 (0x00000002U) -#define NV0073_CTRL_DP_LANE_DATA_DRIVECURRENT_LEVEL3 (0x00000003U) - -#define NV0073_CTRL_CMD_DP_SET_LANE_DATA (0x731346U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_DP_SET_LANE_DATA_PARAMS_MESSAGE_ID" */ - -#define NV0073_CTRL_CMD_DP_SET_AUDIO_MUTESTREAM (0x731359U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_DP_SET_AUDIO_MUTESTREAM_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_DP_SET_AUDIO_MUTESTREAM_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 mute; -} NV0073_CTRL_DP_SET_AUDIO_MUTESTREAM_PARAMS; - -#define NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID (0x73135bU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 preferredDisplayId; - - NvBool force; - NvBool useBFM; - - NvU32 displayIdAssigned; - NvU32 allDisplayMask; -} NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID_PARAMS; - -#define NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID (0x73135cU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; -} NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID_PARAMS; - -#define NV0073_CTRL_CMD_DP_CONFIG_STREAM (0x731362U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS { - NvU32 subDeviceInstance; - NvU32 head; - NvU32 sorIndex; - NvU32 dpLink; - - NvBool bEnableOverride; - NvBool bMST; - NvU32 singleHeadMultistreamMode; - NvU32 hBlankSym; - NvU32 vBlankSym; - NvU32 colorFormat; - NvBool bEnableTwoHeadOneOr; - - struct { - NvU32 slotStart; - NvU32 slotEnd; - NvU32 PBN; - NvU32 Timeslice; - NvBool sendACT; // deprecated -Use NV0073_CTRL_CMD_DP_SEND_ACT - NvU32 singleHeadMSTPipeline; - NvBool bEnableAudioOverRightPanel; - } MST; - - struct { - NvBool bEnhancedFraming; - NvU32 tuSize; - NvU32 waterMark; - NvU32 actualPclkHz; // deprecated -Use MvidWarParams - NvU32 linkClkFreqHz; // deprecated -Use MvidWarParams - NvBool bEnableAudioOverRightPanel; - struct { - NvU32 activeCnt; - NvU32 activeFrac; - NvU32 activePolarity; - NvBool mvidWarEnabled; - struct { - NvU32 actualPclkHz; - NvU32 linkClkFreqHz; - } MvidWarParams; - } Legacy; - } SST; -} NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS; - -#define NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT (0x731365U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT_PARAMS { - NvU32 subDeviceInstance; -} NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT_PARAMS; - -#define NV0073_CTRL_CMD_DP_GET_CAPS (0x731369U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS_MESSAGE_ID" */ - -#define NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS_MESSAGE_ID (0x69U) - -typedef struct NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS { - NvU32 subDeviceInstance; - NvU32 sorIndex; - NvU32 maxLinkRate; - NvU32 dpVersionsSupported; - NvU32 UHBRSupported; - NvBool bIsMultistreamSupported; - NvBool bIsSCEnabled; - NvBool bHasIncreasedWatermarkLimits; - NvBool bIsPC2Disabled; - NvBool isSingleHeadMSTSupported; - NvBool bFECSupported; - NvBool bIsTrainPhyRepeater; - NvBool bOverrideLinkBw; - NV0073_CTRL_CMD_DSC_CAP_PARAMS DSC; -} NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS; - -#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_2 0:0 -#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_2_NO (0x00000000U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_2_YES (0x00000001U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_4 1:1 -#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_4_NO (0x00000000U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_4_YES (0x00000001U) - -#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE 2:0 -#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_NONE (0x00000000U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62 (0x00000001U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70 (0x00000002U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40 (0x00000003U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10 (0x00000004U) - -#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_RGB (0x00000001U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_444 (0x00000002U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_NATIVE_422 (0x00000004U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_NATIVE_420 (0x00000008U) - -#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_16 (0x00000001U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_8 (0x00000002U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_4 (0x00000003U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_2 (0x00000004U) -#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1 (0x00000005U) - -#define NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES (0x731377U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS_MESSAGE_ID" */ - -#define NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES 8U - -typedef struct NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS { - // In - NvU32 subDeviceInstance; - NvU32 displayId; - NvU16 linkRateTbl[NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES]; - - // Out - NvU8 linkBwTbl[NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES]; - NvU8 linkBwCount; -} NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS; - -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE 3:0 -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_MONITOR_ENABLE_BEGIN (0x00000000U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_MONITOR_ENABLE_CHALLENGE (0x00000001U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_MONITOR_ENABLE_CHECK (0x00000002U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_DRIVER_ENABLE_BEGIN (0x00000003U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_DRIVER_ENABLE_CHALLENGE (0x00000004U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_DRIVER_ENABLE_CHECK (0x00000005U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_RESET_MONITOR (0x00000006U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_INIT_PUBLIC_INFO (0x00000007U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_GET_PUBLIC_INFO (0x00000008U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_STATUS_CHECK (0x00000009U) - -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_OK (0x00000000U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_PENDING (0x80000001U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_READ_ERROR (0x80000002U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_WRITE_ERROR (0x80000003U) -#define NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_DEVICE_ERROR (0x80000004U) - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h deleted file mode 100644 index 954958dcf834..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h +++ /dev/null @@ -1,216 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073specific_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073specific_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV0073_CTRL_CMD_SPECIFIC_GET_EDID_V2 (0x730245U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_EDID_V2_PARAMS_MESSAGE_ID" */ - -#define NV0073_CTRL_SPECIFIC_GET_EDID_MAX_EDID_BYTES 2048U - -typedef struct NV0073_CTRL_SPECIFIC_GET_EDID_V2_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 bufferSize; - NvU32 flags; - NvU8 edidBuffer[NV0073_CTRL_SPECIFIC_GET_EDID_MAX_EDID_BYTES]; -} NV0073_CTRL_SPECIFIC_GET_EDID_V2_PARAMS; - -#define NV0073_CTRL_CMD_SPECIFIC_GET_CONNECTOR_DATA (0x730250U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS_MESSAGE_ID" */ - -#define NV0073_CTRL_MAX_CONNECTORS 4U - -typedef struct NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 flags; - NvU32 DDCPartners; - NvU32 count; - struct { - NvU32 index; - NvU32 type; - NvU32 location; - } data[NV0073_CTRL_MAX_CONNECTORS]; - NvU32 platform; -} NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS; - -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_ENABLE (0x730273U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_SET_HDMI_ENABLE_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_SPECIFIC_SET_HDMI_ENABLE_PARAMS { - NvU8 subDeviceInstance; - NvU32 displayId; - NvU8 enable; -} NV0073_CTRL_SPECIFIC_SET_HDMI_ENABLE_PARAMS; - -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM (0x730275U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM_PARAMS { - NvU8 subDeviceInstance; - NvU32 displayId; - NvU8 mute; -} NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM_PARAMS; - -#define NV0073_CTRL_CMD_SPECIFIC_GET_ALL_HEAD_MASK (0x730287U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_ALL_HEAD_MASK_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_SPECIFIC_GET_ALL_HEAD_MASK_PARAMS { - NvU32 subDeviceInstance; - NvU32 headMask; -} NV0073_CTRL_SPECIFIC_GET_ALL_HEAD_MASK_PARAMS; - -#define NV0073_CTRL_CMD_SPECIFIC_SET_OD_PACKET (0x730288U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS_MESSAGE_ID" */ - -#define NV0073_CTRL_SET_OD_MAX_PACKET_SIZE 36U - -typedef struct NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 transmitControl; - NvU32 packetSize; - NvU32 targetHead; - NvBool bUsePsrHeadforSdp; - NvU8 aPacket[NV0073_CTRL_SET_OD_MAX_PACKET_SIZE]; -} NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS; - -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ENABLE 0:0 -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ENABLE_NO (0x0000000U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ENABLE_YES (0x0000001U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_OTHER_FRAME 1:1 -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_OTHER_FRAME_DISABLE (0x0000000U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_OTHER_FRAME_ENABLE (0x0000001U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SINGLE_FRAME 2:2 -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SINGLE_FRAME_DISABLE (0x0000000U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SINGLE_FRAME_ENABLE (0x0000001U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ON_HBLANK 3:3 -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ON_HBLANK_DISABLE (0x0000000U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ON_HBLANK_ENABLE (0x0000001U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_IMMEDIATE 4:4 -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_IMMEDIATE_DISABLE (0x0000000U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_IMMEDIATE_ENABLE (0x0000001U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_VIDEO_FMT 5:5 -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_VIDEO_FMT_SW_CONTROLLED (0x0000000U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_VIDEO_FMT_HW_CONTROLLED (0x0000001U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_STEREO_POLARITY 6:6 -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_STEREO_POLARITY_FALSE (0x0000000U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_STEREO_POLARITY_TRUE (0x0000001U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_SELF_REFRESH_SETTING 7:7 -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_SELF_REFRESH_SETTING_FALSE (0x0000000U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_SELF_REFRESH_SETTING_TRUE (0x0000001U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_GEN_INFOFRAME_MODE 9:8 -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_GEN_INFOFRAME_MODE_INFOFRAME0 (0x0000000U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_GEN_INFOFRAME_MODE_INFOFRAME1 (0x0000001U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_RESERVED_LEGACY_MODE 31:31 -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_RESERVED_LEGACY_MODE_NO (0x0000000U) -#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_RESERVED_LEGACY_MODE_YES (0x0000001U) - -#define NV0073_CTRL_CMD_SPECIFIC_OR_GET_INFO (0x73028bU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 index; - NvU32 type; - NvU32 protocol; - NvU32 ditherType; - NvU32 ditherAlgo; - NvU32 location; - NvU32 rootPortId; - NvU32 dcbIndex; - NV_DECLARE_ALIGNED(NvU64 vbiosAddress, 8); - NvBool bIsLitByVbios; - NvBool bIsDispDynamic; -} NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS; - -#define NV0073_CTRL_SPECIFIC_OR_TYPE_NONE (0x00000000U) -#define NV0073_CTRL_SPECIFIC_OR_TYPE_DAC (0x00000001U) -#define NV0073_CTRL_SPECIFIC_OR_TYPE_SOR (0x00000002U) -#define NV0073_CTRL_SPECIFIC_OR_TYPE_PIOR (0x00000003U) - -#define NV0073_CTRL_SPECIFIC_OR_TYPE_DSI (0x00000005U) - -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_DAC_RGB_CRT (0x00000000U) - -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_LVDS_CUSTOM (0x00000000U) -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_A (0x00000001U) -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_B (0x00000002U) -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DUAL_TMDS (0x00000005U) -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DP_A (0x00000008U) -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DP_B (0x00000009U) -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DSI (0x00000010U) - -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_DSI (0x00000011U) - -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_PIOR_EXT_TMDS_ENC (0x00000000U) - -#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_UNKNOWN (0xFFFFFFFFU) - -#define NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS (0x730291U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 brightness; - NvBool bUncalibrated; -} NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS; - -#define NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS (0x730292U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS_PARAMS_MESSAGE_ID" */ - -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS (0x730293U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_SET_HDMI_SINK_CAPS_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_SPECIFIC_SET_HDMI_SINK_CAPS_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayId; - NvU32 caps; -} NV0073_CTRL_SPECIFIC_SET_HDMI_SINK_CAPS_PARAMS; - -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_GT_340MHZ_CLOCK_SUPPORTED 0:0 -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_GT_340MHZ_CLOCK_SUPPORTED_FALSE (0x00000000U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_GT_340MHZ_CLOCK_SUPPORTED_TRUE (0x00000001U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_LTE_340MHZ_SCRAMBLING_SUPPORTED 1:1 -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_LTE_340MHZ_SCRAMBLING_SUPPORTED_FALSE (0x00000000U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_LTE_340MHZ_SCRAMBLING_SUPPORTED_TRUE (0x00000001U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_SCDC_SUPPORTED 2:2 -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_SCDC_SUPPORTED_FALSE (0x00000000U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_SCDC_SUPPORTED_TRUE (0x00000001U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED 5:3 -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_NONE (0x00000000U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_3LANES_3G (0x00000001U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_3LANES_6G (0x00000002U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_4LANES_6G (0x00000003U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_4LANES_8G (0x00000004U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_4LANES_10G (0x00000005U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_4LANES_12G (0x00000006U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_12_SUPPORTED 6:6 -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_12_SUPPORTED_FALSE (0x00000000U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_12_SUPPORTED_TRUE (0x00000001U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED 9:7 -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_NONE (0x00000000U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_3LANES_3G (0x00000001U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_3LANES_6G (0x00000002U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_4LANES_6G (0x00000003U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_4LANES_8G (0x00000004U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_4LANES_10G (0x00000005U) -#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_4LANES_12G (0x00000006U) - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h deleted file mode 100644 index d69cef3c01fd..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073system_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl0073_ctrl0073system_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2005-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV0073_CTRL_CMD_SYSTEM_GET_NUM_HEADS (0x730102U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_NUM_HEADS_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_SYSTEM_GET_NUM_HEADS_PARAMS { - NvU32 subDeviceInstance; - NvU32 flags; - NvU32 numHeads; -} NV0073_CTRL_SYSTEM_GET_NUM_HEADS_PARAMS; - -#define NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED (0x730120U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS { - NvU32 subDeviceInstance; - NvU32 displayMask; - NvU32 displayMaskDDC; -} NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS; - -#define NV0073_CTRL_CMD_SYSTEM_GET_CONNECT_STATE (0x730122U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS { - NvU32 subDeviceInstance; - NvU32 flags; - NvU32 displayMask; - NvU32 retryTimeMs; -} NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS; - -#define NV0073_CTRL_CMD_SYSTEM_GET_ACTIVE (0x730126U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS_MESSAGE_ID" */ - -typedef struct NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS { - NvU32 subDeviceInstance; - NvU32 head; - NvU32 flags; - NvU32 displayId; -} NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS; - -#define NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS (16U) - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gpu.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gpu.h deleted file mode 100644 index 3db099e62364..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gpu.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl0080_ctrl0080gpu_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl0080_ctrl0080gpu_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2004-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS { - NvU32 totalVFs; - NvU32 firstVfOffset; - NvU32 vfFeatureMask; - NV_DECLARE_ALIGNED(NvU64 FirstVFBar0Address, 8); - NV_DECLARE_ALIGNED(NvU64 FirstVFBar1Address, 8); - NV_DECLARE_ALIGNED(NvU64 FirstVFBar2Address, 8); - NV_DECLARE_ALIGNED(NvU64 bar0Size, 8); - NV_DECLARE_ALIGNED(NvU64 bar1Size, 8); - NV_DECLARE_ALIGNED(NvU64 bar2Size, 8); - NvBool b64bitBar0; - NvBool b64bitBar1; - NvBool b64bitBar2; - NvBool bSriovEnabled; - NvBool bSriovHeavyEnabled; - NvBool bEmulateVFBar0TlbInvalidationRegister; - NvBool bClientRmAllocatedCtxBuffer; -} NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gr.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gr.h deleted file mode 100644 index ed01df925573..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gr.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl0080_ctrl0080gr_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl0080_ctrl0080gr_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2004-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV0080_CTRL_GR_CAPS_TBL_SIZE 23 - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080bios.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080bios.h deleted file mode 100644 index b5b7631de99b..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080bios.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080bios_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080bios_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2005-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS { - NvU32 BoardID; - char chipSKU[4]; - char chipSKUMod[2]; - char project[5]; - char projectSKU[5]; - char CDP[6]; - char projectSKUMod[2]; - NvU32 businessCycle; -} NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080ce.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080ce.h deleted file mode 100644 index fe912d2bd183..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080ce.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080ce_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080ce_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2014-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS { - NvU32 size; -} NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS; - -#define NV2080_CTRL_CMD_CE_GET_FAULT_METHOD_BUFFER_SIZE (0x20802a08) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_CE_INTERFACE_ID << 8) | NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS_MESSAGE_ID" */ - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080event.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080event.h deleted file mode 100644 index 87bc4ff92ce1..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080event.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080event_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080event_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION (0x20800301) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_EVENT_INTERFACE_ID << 8) | NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS_MESSAGE_ID" */ - -typedef struct NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS { - NvU32 event; - NvU32 action; - NvBool bNotifyState; - NvU32 info32; - NvU16 info16; -} NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS; - -#define NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT (0x00000002) - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fb.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fb.h deleted file mode 100644 index 68c81f9f803c..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fb.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080fb_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080fb_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MEM_TYPES 17U - -typedef NvBool NV2080_CTRL_CMD_FB_GET_FB_REGION_SURFACE_MEM_TYPE_FLAG[NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MEM_TYPES]; - -typedef struct NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO { - NV_DECLARE_ALIGNED(NvU64 base, 8); - NV_DECLARE_ALIGNED(NvU64 limit, 8); - NV_DECLARE_ALIGNED(NvU64 reserved, 8); - NvU32 performance; - NvBool supportCompressed; - NvBool supportISO; - NvBool bProtected; - NV2080_CTRL_CMD_FB_GET_FB_REGION_SURFACE_MEM_TYPE_FLAG blackList; -} NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO; - -#define NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MAX_ENTRIES 16U - -typedef struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS { - NvU32 numFBRegions; - NV_DECLARE_ALIGNED(NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO fbRegion[NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MAX_ENTRIES], 8); -} NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fifo.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fifo.h deleted file mode 100644 index bc0f63699b06..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fifo.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080fifo_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080fifo_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2006-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV2080_CTRL_CMD_FIFO_GET_DEVICE_INFO_TABLE (0x20801112) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_FIFO_INTERFACE_ID << 8) | NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS_MESSAGE_ID" */ - -#define NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_MAX_ENTRIES 32 -#define NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_DATA_TYPES 16 -#define NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_MAX_PBDMA 2 -#define NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_MAX_NAME_LEN 16 - -typedef struct NV2080_CTRL_FIFO_DEVICE_ENTRY { - NvU32 engineData[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_DATA_TYPES]; - NvU32 pbdmaIds[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_MAX_PBDMA]; - NvU32 pbdmaFaultIds[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_MAX_PBDMA]; - NvU32 numPbdmas; - char engineName[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_MAX_NAME_LEN]; -} NV2080_CTRL_FIFO_DEVICE_ENTRY; - -typedef struct NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS { - NvU32 baseIndex; - NvU32 numEntries; - NvBool bMore; - // C form: NV2080_CTRL_FIFO_DEVICE_ENTRY entries[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_MAX_ENTRIES]; - NV2080_CTRL_FIFO_DEVICE_ENTRY entries[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_MAX_ENTRIES]; -} NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h deleted file mode 100644 index 29d7a1052142..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080gpu_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080gpu_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2006-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV2080_GPU_MAX_NAME_STRING_LENGTH (0x0000040U) - -#define NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_0 (0x00000000U) - -#define NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3 (0x00000003U) - -typedef struct NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ENTRY { - NV_DECLARE_ALIGNED(NvU64 gpuPhysAddr, 8); - NV_DECLARE_ALIGNED(NvU64 gpuVirtAddr, 8); - NV_DECLARE_ALIGNED(NvU64 size, 8); - NvU32 physAttr; - NvU16 bufferId; - NvU8 bInitialize; - NvU8 bNonmapped; -} NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ENTRY; - -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_MAIN 0U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PM 1U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PATCH 2U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_BUFFER_BUNDLE_CB 3U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PAGEPOOL 4U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_ATTRIBUTE_CB 5U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_RTV_CB_GLOBAL 6U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_GFXP_POOL 7U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_GFXP_CTRL_BLK 8U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_FECS_EVENT 9U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PRIV_ACCESS_MAP 10U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_UNRESTRICTED_PRIV_ACCESS_MAP 11U -#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_GLOBAL_PRIV_ACCESS_MAP 12U - -#define NV2080_CTRL_GPU_PROMOTE_CONTEXT_MAX_ENTRIES 16U - -#define NV2080_CTRL_CMD_GPU_PROMOTE_CTX (0x2080012bU) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_GPU_INTERFACE_ID << 8) | NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS_MESSAGE_ID" */ - -typedef struct NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS { - NvU32 engineType; - NvHandle hClient; - NvU32 ChID; - NvHandle hChanClient; - NvHandle hObject; - NvHandle hVirtMemory; - NV_DECLARE_ALIGNED(NvU64 virtAddress, 8); - NV_DECLARE_ALIGNED(NvU64 size, 8); - NvU32 entryCount; - // C form: NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ENTRY promoteEntry[NV2080_CTRL_GPU_PROMOTE_CONTEXT_MAX_ENTRIES]; - NV_DECLARE_ALIGNED(NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ENTRY promoteEntry[NV2080_CTRL_GPU_PROMOTE_CONTEXT_MAX_ENTRIES], 8); -} NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS; - -typedef struct NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS { - NvU32 gpcMask; -} NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS; - -typedef struct NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS { - NvU32 gpcId; - NvU32 tpcMask; -} NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS; - -typedef struct NV2080_CTRL_GPU_GET_FERMI_ZCULL_INFO_PARAMS { - NvU32 gpcId; - NvU32 zcullMask; -} NV2080_CTRL_GPU_GET_FERMI_ZCULL_INFO_PARAMS; - -#define NV2080_GPU_MAX_GID_LENGTH (0x000000100ULL) - -typedef struct NV2080_CTRL_GPU_GET_GID_INFO_PARAMS { - NvU32 index; - NvU32 flags; - NvU32 length; - NvU8 data[NV2080_GPU_MAX_GID_LENGTH]; -} NV2080_CTRL_GPU_GET_GID_INFO_PARAMS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gr.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gr.h deleted file mode 100644 index 59f8895bc5d7..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gr.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080gr_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080gr_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2006-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef enum NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS { - NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_MAIN = 0, - NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_SPILL = 1, - NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_PAGEPOOL = 2, - NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_BETACB = 3, - NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_RTV = 4, - NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_CONTEXT_POOL = 5, - NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_CONTEXT_POOL_CONTROL = 6, - NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_CONTEXT_POOL_CONTROL_CPU = 7, - NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_END = 8, -} NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080internal.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080internal.h deleted file mode 100644 index e11b2dbe5288..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080internal.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080internal_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl2080_ctrl2080internal_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2020-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO (0x20800a01) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS_MESSAGE_ID" */ - -typedef struct NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS { - NvU32 feHwSysCap; - NvU32 windowPresentMask; - NvBool bFbRemapperEnabled; - NvU32 numHeads; - NvBool bPrimaryVga; - NvU32 i2cPort; - NvU32 internalDispActiveMask; -} NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS; - -#define NV2080_CTRL_INTERNAL_GR_MAX_ENGINES 8 - -#define NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT 0x19 - -typedef struct NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO { - NvU32 size; - NvU32 alignment; -} NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO; - -typedef struct NV2080_CTRL_INTERNAL_STATIC_GR_CONTEXT_BUFFERS_INFO { - NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO engine[NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT]; -} NV2080_CTRL_INTERNAL_STATIC_GR_CONTEXT_BUFFERS_INFO; - -typedef struct NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS { - NV2080_CTRL_INTERNAL_STATIC_GR_CONTEXT_BUFFERS_INFO engineContextBuffersInfo[NV2080_CTRL_INTERNAL_GR_MAX_ENGINES]; -} NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS; - -#define NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO (0x20800a32) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO_PARAMS_MESSAGE_ID" */ - -typedef struct NV2080_CTRL_INTERNAL_CONSTRUCTED_FALCON_INFO { - NvU32 engDesc; - NvU32 ctxAttr; - NvU32 ctxBufferSize; - NvU32 addrSpaceList; - NvU32 registerBase; -} NV2080_CTRL_INTERNAL_CONSTRUCTED_FALCON_INFO; -#define NV2080_CTRL_CMD_INTERNAL_MAX_CONSTRUCTED_FALCONS 0x40 - -#define NV2080_CTRL_CMD_INTERNAL_GET_CONSTRUCTED_FALCON_INFO (0x20800a42) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_GET_CONSTRUCTED_FALCON_INFO_PARAMS_MESSAGE_ID" */ - -typedef struct NV2080_CTRL_INTERNAL_GET_CONSTRUCTED_FALCON_INFO_PARAMS { - NvU32 numConstructedFalcons; - NV2080_CTRL_INTERNAL_CONSTRUCTED_FALCON_INFO constructedFalconsTable[NV2080_CTRL_CMD_INTERNAL_MAX_CONSTRUCTED_FALCONS]; -} NV2080_CTRL_INTERNAL_GET_CONSTRUCTED_FALCON_INFO_PARAMS; - -#define NV2080_CTRL_CMD_INTERNAL_DISPLAY_WRITE_INST_MEM (0x20800a49) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS_MESSAGE_ID" */ - -typedef struct NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS { - NV_DECLARE_ALIGNED(NvU64 instMemPhysAddr, 8); - NV_DECLARE_ALIGNED(NvU64 instMemSize, 8); - NvU32 instMemAddrSpace; - NvU32 instMemCpuCacheAttr; -} NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS; - -#define NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER (0x20800a58) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS_MESSAGE_ID" */ - -typedef struct NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS { - NvU32 addressSpace; - NV_DECLARE_ALIGNED(NvU64 physicalAddr, 8); - NV_DECLARE_ALIGNED(NvU64 limit, 8); - NvU32 cacheSnoop; - NvU32 hclass; - NvU32 channelInstance; - NvBool valid; -} NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS; - -#define NV2080_CTRL_CMD_INTERNAL_INTR_GET_KERNEL_TABLE (0x20800a5c) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_PARAMS_MESSAGE_ID" */ - -#define NV2080_CTRL_INTERNAL_INTR_MAX_TABLE_SIZE 128 - -typedef enum NV2080_INTR_CATEGORY { - NV2080_INTR_CATEGORY_DEFAULT = 0, - NV2080_INTR_CATEGORY_ESCHED_DRIVEN_ENGINE = 1, - NV2080_INTR_CATEGORY_ESCHED_DRIVEN_ENGINE_NOTIFICATION = 2, - NV2080_INTR_CATEGORY_RUNLIST = 3, - NV2080_INTR_CATEGORY_RUNLIST_NOTIFICATION = 4, - NV2080_INTR_CATEGORY_UVM_OWNED = 5, - NV2080_INTR_CATEGORY_UVM_SHARED = 6, - NV2080_INTR_CATEGORY_ENUM_COUNT = 7, -} NV2080_INTR_CATEGORY; - -typedef struct NV2080_INTR_CATEGORY_SUBTREE_MAP { - NvU8 subtreeStart; - NvU8 subtreeEnd; -} NV2080_INTR_CATEGORY_SUBTREE_MAP; - -typedef struct NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_ENTRY { - NvU16 engineIdx; - NvU32 pmcIntrMask; - NvU32 vectorStall; - NvU32 vectorNonStall; -} NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_ENTRY; - -typedef struct NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_PARAMS { - NvU32 tableLen; - NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_ENTRY table[NV2080_CTRL_INTERNAL_INTR_MAX_TABLE_SIZE]; - NV2080_INTR_CATEGORY_SUBTREE_MAP subtreeMap[NV2080_INTR_CATEGORY_ENUM_COUNT]; -} NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_PARAMS; - -#define NV2080_CTRL_CMD_INTERNAL_FBSR_INIT (0x20800ac2) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS_MESSAGE_ID" */ - -typedef struct NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS { - NvU32 fbsrType; - NvU32 numRegions; - NvHandle hClient; - NvHandle hSysMem; - NV_DECLARE_ALIGNED(NvU64 gspFbAllocsSysOffset, 8); - NvBool bEnteringGcoffState; -} NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS; - -#define NV2080_CTRL_CMD_INTERNAL_FBSR_SEND_REGION_INFO (0x20800ac3) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_FBSR_SEND_REGION_INFO_PARAMS_MESSAGE_ID" */ - -typedef struct NV2080_CTRL_INTERNAL_FBSR_SEND_REGION_INFO_PARAMS { - NvU32 fbsrType; - NvHandle hClient; - NvHandle hVidMem; - NV_DECLARE_ALIGNED(NvU64 vidOffset, 8); - NV_DECLARE_ALIGNED(NvU64 sysOffset, 8); - NV_DECLARE_ALIGNED(NvU64 size, 8); -} NV2080_CTRL_INTERNAL_FBSR_SEND_REGION_INFO_PARAMS; - -#define NV2080_CTRL_CMD_INTERNAL_INIT_BRIGHTC_STATE_LOAD (0x20800ac6) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_INIT_BRIGHTC_STATE_LOAD_PARAMS_MESSAGE_ID" */ - -#define NV2080_CTRL_ACPI_DSM_READ_SIZE (0x1000) /* finn: Evaluated from "(4 * 1024)" */ - -typedef struct NV2080_CTRL_INTERNAL_INIT_BRIGHTC_STATE_LOAD_PARAMS { - NvU32 status; - NvU16 backLightDataSize; - NvU8 backLightData[NV2080_CTRL_ACPI_DSM_READ_SIZE]; -} NV2080_CTRL_INTERNAL_INIT_BRIGHTC_STATE_LOAD_PARAMS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl90f1.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl90f1.h deleted file mode 100644 index 977e59818533..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl90f1.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl90f1_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl90f1_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define GMMU_FMT_MAX_LEVELS 6U - -#define NV90F1_CTRL_CMD_VASPACE_COPY_SERVER_RESERVED_PDES (0x90f10106U) /* finn: Evaluated from "(FINN_FERMI_VASPACE_A_VASPACE_INTERFACE_ID << 8) | NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS_MESSAGE_ID" */ - -typedef struct NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS { - /*! - * [in] GPU sub-device handle - this API only supports unicast. - * Pass 0 to use subDeviceId instead. - */ - NvHandle hSubDevice; - - /*! - * [in] GPU sub-device ID. Ignored if hSubDevice is non-zero. - */ - NvU32 subDeviceId; - - /*! - * [in] Page size (VA coverage) of the level to reserve. - * This need not be a leaf (page table) page size - it can be - * the coverage of an arbitrary level (including root page directory). - */ - NV_DECLARE_ALIGNED(NvU64 pageSize, 8); - - /*! - * [in] First GPU virtual address of the range to reserve. - * This must be aligned to pageSize. - */ - NV_DECLARE_ALIGNED(NvU64 virtAddrLo, 8); - - /*! - * [in] Last GPU virtual address of the range to reserve. - * This (+1) must be aligned to pageSize. - */ - NV_DECLARE_ALIGNED(NvU64 virtAddrHi, 8); - - /*! - * [in] Number of PDE levels to copy. - */ - NvU32 numLevelsToCopy; - - /*! - * [in] Per-level information. - */ - struct { - /*! - * Physical address of this page level instance. - */ - NV_DECLARE_ALIGNED(NvU64 physAddress, 8); - - /*! - * Size in bytes allocated for this level instance. - */ - NV_DECLARE_ALIGNED(NvU64 size, 8); - - /*! - * Aperture in which this page level instance resides. - */ - NvU32 aperture; - - /*! - * Page shift corresponding to the level - */ - NvU8 pageShift; - } levels[GMMU_FMT_MAX_LEVELS]; -} NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrla06f/ctrla06fgpfifo.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrla06f/ctrla06fgpfifo.h deleted file mode 100644 index 684045796232..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrla06f/ctrla06fgpfifo.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrla06f_ctrla06fgpfifo_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrla06f_ctrla06fgpfifo_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2007-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NVA06F_CTRL_CMD_GPFIFO_SCHEDULE (0xa06f0103) /* finn: Evaluated from "(FINN_KEPLER_CHANNEL_GPFIFO_A_GPFIFO_INTERFACE_ID << 8) | NVA06F_CTRL_GPFIFO_SCHEDULE_PARAMS_MESSAGE_ID" */ - -typedef struct NVA06F_CTRL_GPFIFO_SCHEDULE_PARAMS { - NvBool bEnable; - NvBool bSkipSubmit; -} NVA06F_CTRL_GPFIFO_SCHEDULE_PARAMS; - -#define NVA06F_CTRL_CMD_BIND (0xa06f0104) /* finn: Evaluated from "(FINN_KEPLER_CHANNEL_GPFIFO_A_GPFIFO_INTERFACE_ID << 8) | NVA06F_CTRL_BIND_PARAMS_MESSAGE_ID" */ - -typedef struct NVA06F_CTRL_BIND_PARAMS { - NvU32 engineType; -} NVA06F_CTRL_BIND_PARAMS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/nvlimits.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/nvlimits.h deleted file mode 100644 index 5c5a004a8031..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/nvlimits.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_nvlimits_h__ -#define __src_common_sdk_nvidia_inc_nvlimits_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2017 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV_MAX_SUBDEVICES 8 - -#define NV_PROC_NAME_MAX_LENGTH 100U - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h deleted file mode 100644 index 51b5591c603e..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef __src_common_sdk_nvidia_inc_nvos_h__ -#define __src_common_sdk_nvidia_inc_nvos_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NVOS02_FLAGS_PHYSICALITY 7:4 -#define NVOS02_FLAGS_PHYSICALITY_CONTIGUOUS (0x00000000) -#define NVOS02_FLAGS_PHYSICALITY_NONCONTIGUOUS (0x00000001) -#define NVOS02_FLAGS_LOCATION 11:8 -#define NVOS02_FLAGS_LOCATION_PCI (0x00000000) -#define NVOS02_FLAGS_LOCATION_AGP (0x00000001) -#define NVOS02_FLAGS_LOCATION_VIDMEM (0x00000002) -#define NVOS02_FLAGS_COHERENCY 15:12 -#define NVOS02_FLAGS_COHERENCY_UNCACHED (0x00000000) -#define NVOS02_FLAGS_COHERENCY_CACHED (0x00000001) -#define NVOS02_FLAGS_COHERENCY_WRITE_COMBINE (0x00000002) -#define NVOS02_FLAGS_COHERENCY_WRITE_THROUGH (0x00000003) -#define NVOS02_FLAGS_COHERENCY_WRITE_PROTECT (0x00000004) -#define NVOS02_FLAGS_COHERENCY_WRITE_BACK (0x00000005) -#define NVOS02_FLAGS_ALLOC 17:16 -#define NVOS02_FLAGS_ALLOC_NONE (0x00000001) -#define NVOS02_FLAGS_GPU_CACHEABLE 18:18 -#define NVOS02_FLAGS_GPU_CACHEABLE_NO (0x00000000) -#define NVOS02_FLAGS_GPU_CACHEABLE_YES (0x00000001) - -#define NVOS02_FLAGS_KERNEL_MAPPING 19:19 -#define NVOS02_FLAGS_KERNEL_MAPPING_NO_MAP (0x00000000) -#define NVOS02_FLAGS_KERNEL_MAPPING_MAP (0x00000001) -#define NVOS02_FLAGS_ALLOC_NISO_DISPLAY 20:20 -#define NVOS02_FLAGS_ALLOC_NISO_DISPLAY_NO (0x00000000) -#define NVOS02_FLAGS_ALLOC_NISO_DISPLAY_YES (0x00000001) - -#define NVOS02_FLAGS_ALLOC_USER_READ_ONLY 21:21 -#define NVOS02_FLAGS_ALLOC_USER_READ_ONLY_NO (0x00000000) -#define NVOS02_FLAGS_ALLOC_USER_READ_ONLY_YES (0x00000001) - -#define NVOS02_FLAGS_ALLOC_DEVICE_READ_ONLY 22:22 -#define NVOS02_FLAGS_ALLOC_DEVICE_READ_ONLY_NO (0x00000000) -#define NVOS02_FLAGS_ALLOC_DEVICE_READ_ONLY_YES (0x00000001) - -#define NVOS02_FLAGS_PEER_MAP_OVERRIDE 23:23 -#define NVOS02_FLAGS_PEER_MAP_OVERRIDE_DEFAULT (0x00000000) -#define NVOS02_FLAGS_PEER_MAP_OVERRIDE_REQUIRED (0x00000001) - -#define NVOS02_FLAGS_ALLOC_TYPE_SYNCPOINT 24:24 -#define NVOS02_FLAGS_ALLOC_TYPE_SYNCPOINT_APERTURE (0x00000001) - -#define NVOS02_FLAGS_MEMORY_PROTECTION 26:25 -#define NVOS02_FLAGS_MEMORY_PROTECTION_DEFAULT (0x00000000) -#define NVOS02_FLAGS_MEMORY_PROTECTION_PROTECTED (0x00000001) -#define NVOS02_FLAGS_MEMORY_PROTECTION_UNPROTECTED (0x00000002) - -#define NVOS02_FLAGS_MAPPING 31:30 -#define NVOS02_FLAGS_MAPPING_DEFAULT (0x00000000) -#define NVOS02_FLAGS_MAPPING_NO_MAP (0x00000001) -#define NVOS02_FLAGS_MAPPING_NEVER_MAP (0x00000002) - -#define NV01_EVENT_CLIENT_RM (0x04000000) - -typedef struct -{ - NvV32 channelInstance; // One of the n channel instances of a given channel type. - // Note that core channel has only one instance - // while all others have two (one per head). - NvHandle hObjectBuffer; // ctx dma handle for DMA push buffer - NvHandle hObjectNotify; // ctx dma handle for an area (of type NvNotification defined in sdk/nvidia/inc/nvtypes.h) where RM can write errors/notifications - NvU32 offset; // Initial offset for put/get, usually zero. - NvP64 pControl NV_ALIGN_BYTES(8); // pControl gives virt addr of UDISP GET/PUT regs - - NvU32 flags; -#define NV50VAIO_CHANNELDMA_ALLOCATION_FLAGS_CONNECT_PB_AT_GRAB 1:1 -#define NV50VAIO_CHANNELDMA_ALLOCATION_FLAGS_CONNECT_PB_AT_GRAB_YES 0x00000000 -#define NV50VAIO_CHANNELDMA_ALLOCATION_FLAGS_CONNECT_PB_AT_GRAB_NO 0x00000001 - -} NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS; - -typedef struct -{ - NvV32 channelInstance; // One of the n channel instances of a given channel type. - // All PIO channels have two instances (one per head). - NvHandle hObjectNotify; // ctx dma handle for an area (of type NvNotification defined in sdk/nvidia/inc/nvtypes.h) where RM can write errors. - NvP64 pControl NV_ALIGN_BYTES(8); // pControl gives virt addr of control region for PIO channel -} NV50VAIO_CHANNELPIO_ALLOCATION_PARAMETERS; - -typedef struct -{ - NvU32 size; - NvU32 prohibitMultipleInstances; - NvU32 engineInstance; // Select NVDEC0 or NVDEC1 or NVDEC2 -} NV_BSP_ALLOCATION_PARAMETERS; - -typedef struct -{ - NvU32 size; - NvU32 prohibitMultipleInstances; // Prohibit multiple allocations of MSENC? - NvU32 engineInstance; // Select MSENC/NVENC0 or NVENC1 or NVENC2 -} NV_MSENC_ALLOCATION_PARAMETERS; - -typedef struct -{ - NvU32 size; - NvU32 prohibitMultipleInstances; // Prohibit multiple allocations of NVJPG? - NvU32 engineInstance; -} NV_NVJPG_ALLOCATION_PARAMETERS; - -typedef struct -{ - NvU32 size; - NvU32 prohibitMultipleInstances; // Prohibit multiple allocations of OFA? -} NV_OFA_ALLOCATION_PARAMETERS; - -typedef struct -{ - NvU32 index; - NvV32 flags; - NvU64 vaSize NV_ALIGN_BYTES(8); - NvU64 vaStartInternal NV_ALIGN_BYTES(8); - NvU64 vaLimitInternal NV_ALIGN_BYTES(8); - NvU32 bigPageSize; - NvU64 vaBase NV_ALIGN_BYTES(8); -} NV_VASPACE_ALLOCATION_PARAMETERS; - -#define NV_VASPACE_ALLOCATION_INDEX_GPU_NEW 0x00 //<! Create new VASpace, by default - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/shared/msgq/inc/msgq/msgq_priv.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/shared/msgq/inc/msgq/msgq_priv.h deleted file mode 100644 index 0e32e71e123f..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/shared/msgq/inc/msgq/msgq_priv.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef __src_common_shared_msgq_inc_msgq_msgq_priv_h__ -#define __src_common_shared_msgq_inc_msgq_msgq_priv_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2018-2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * msgqTxHeader -- TX queue data structure - * @version: the version of this structure, must be 0 - * @size: the size of the entire queue, including this header - * @msgSize: the padded size of queue element, 16 is minimum - * @msgCount: the number of elements in this queue - * @writePtr: head index of this queue - * @flags: 1 = swap the RX pointers - * @rxHdrOff: offset of readPtr in this structure - * @entryOff: offset of beginning of queue (msgqRxHeader), relative to - * beginning of this structure - * - * The command queue is a queue of RPCs that are sent from the driver to the - * GSP. The status queue is a queue of messages/responses from GSP-RM to the - * driver. Although the driver allocates memory for both queues, the command - * queue is owned by the driver and the status queue is owned by GSP-RM. In - * addition, the headers of the two queues must not share the same 4K page. - * - * Each queue is prefixed with this data structure. The idea is that a queue - * and its header are written to only by their owner. That is, only the - * driver writes to the command queue and command queue header, and only the - * GSP writes to the status (receive) queue and its header. - * - * This is enforced by the concept of "swapping" the RX pointers. This is - * why the 'flags' field must be set to 1. 'rxHdrOff' is how the GSP knows - * where the where the tail pointer of its status queue. - * - * When the driver writes a new RPC to the command queue, it updates writePtr. - * When it reads a new message from the status queue, it updates readPtr. In - * this way, the GSP knows when a new command is in the queue (it polls - * writePtr) and it knows how much free space is in the status queue (it - * checks readPtr). The driver never cares about how much free space is in - * the status queue. - * - * As usual, producers write to the head pointer, and consumers read from the - * tail pointer. When head == tail, the queue is empty. - * - * So to summarize: - * command.writePtr = head of command queue - * command.readPtr = tail of status queue - * status.writePtr = head of status queue - * status.readPtr = tail of command queue - */ -typedef struct -{ - NvU32 version; // queue version - NvU32 size; // bytes, page aligned - NvU32 msgSize; // entry size, bytes, must be power-of-2, 16 is minimum - NvU32 msgCount; // number of entries in queue - NvU32 writePtr; // message id of next slot - NvU32 flags; // if set it means "i want to swap RX" - NvU32 rxHdrOff; // Offset of msgqRxHeader from start of backing store. - NvU32 entryOff; // Offset of entries from start of backing store. -} msgqTxHeader; - -/** - * msgqRxHeader - RX queue data structure - * @readPtr: tail index of the other queue - * - * Although this is a separate struct, it could easily be merged into - * msgqTxHeader. msgqTxHeader.rxHdrOff is simply the offset of readPtr - * from the beginning of msgqTxHeader. - */ -typedef struct -{ - NvU32 readPtr; // message id of last message read -} msgqRxHeader; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/uproc/os/common/include/libos_init_args.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/uproc/os/common/include/libos_init_args.h deleted file mode 100644 index 83cf1b2c15a3..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/uproc/os/common/include/libos_init_args.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __src_common_uproc_os_common_include_libos_init_args_h__ -#define __src_common_uproc_os_common_include_libos_init_args_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2018-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef NvU64 LibosAddress; - -typedef enum { - LIBOS_MEMORY_REGION_NONE, - LIBOS_MEMORY_REGION_CONTIGUOUS, - LIBOS_MEMORY_REGION_RADIX3 -} LibosMemoryRegionKind; - -typedef enum { - LIBOS_MEMORY_REGION_LOC_NONE, - LIBOS_MEMORY_REGION_LOC_SYSMEM, - LIBOS_MEMORY_REGION_LOC_FB -} LibosMemoryRegionLoc; - -typedef struct -{ - LibosAddress id8; // Id tag. - LibosAddress pa; // Physical address. - LibosAddress size; // Size of memory area. - NvU8 kind; // See LibosMemoryRegionKind above. - NvU8 loc; // See LibosMemoryRegionLoc above. -} LibosMemoryRegionInitArgument; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_sr_meta.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_sr_meta.h deleted file mode 100644 index 73213bdfcbda..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_sr_meta.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef __src_nvidia_arch_nvalloc_common_inc_gsp_gsp_fw_sr_meta_h__ -#define __src_nvidia_arch_nvalloc_common_inc_gsp_gsp_fw_sr_meta_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define GSP_FW_SR_META_MAGIC 0x8a3bb9e6c6c39d93ULL -#define GSP_FW_SR_META_REVISION 2 - -typedef struct -{ - // - // Magic - // Use for verification by Booter - // - NvU64 magic; // = GSP_FW_SR_META_MAGIC; - - // - // Revision number - // Bumped up when we change this interface so it is not backward compatible. - // Bumped up when we revoke GSP-RM ucode - // - NvU64 revision; // = GSP_FW_SR_META_MAGIC_REVISION; - - // - // ---- Members regarding data in SYSMEM ---------------------------- - // Consumed by Booter for DMA - // - NvU64 sysmemAddrOfSuspendResumeData; - NvU64 sizeOfSuspendResumeData; - - // ---- Members for crypto ops across S/R --------------------------- - - // - // HMAC over the entire GspFwSRMeta structure (including padding) - // with the hmac field itself zeroed. - // - NvU8 hmac[32]; - - // Hash over GspFwWprMeta structure - NvU8 wprMetaHash[32]; - - // Hash over GspFwHeapFreeList structure. All zeros signifies no free list. - NvU8 heapFreeListHash[32]; - - // Hash over data in WPR2 (skipping over free heap chunks; see Booter for details) - NvU8 dataHash[32]; - - // - // Pad structure to exactly 256 bytes (1 DMA chunk). - // Padding initialized to zero. - // - NvU32 padding[24]; - -} GspFwSRMeta; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_wpr_meta.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_wpr_meta.h deleted file mode 100644 index a2e141e4b459..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_wpr_meta.h +++ /dev/null @@ -1,170 +0,0 @@ -#ifndef __src_nvidia_arch_nvalloc_common_inc_gsp_gsp_fw_wpr_meta_h__ -#define __src_nvidia_arch_nvalloc_common_inc_gsp_gsp_fw_wpr_meta_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct -{ - // Magic - // BL to use for verification (i.e. Booter locked it in WPR2) - NvU64 magic; // = 0xdc3aae21371a60b3; - - // Revision number of Booter-BL-Sequencer handoff interface - // Bumped up when we change this interface so it is not backward compatible. - // Bumped up when we revoke GSP-RM ucode - NvU64 revision; // = 1; - - // ---- Members regarding data in SYSMEM ---------------------------- - // Consumed by Booter for DMA - - NvU64 sysmemAddrOfRadix3Elf; - NvU64 sizeOfRadix3Elf; - - NvU64 sysmemAddrOfBootloader; - NvU64 sizeOfBootloader; - - // Offsets inside bootloader image needed by Booter - NvU64 bootloaderCodeOffset; - NvU64 bootloaderDataOffset; - NvU64 bootloaderManifestOffset; - - union - { - // Used only at initial boot - struct - { - NvU64 sysmemAddrOfSignature; - NvU64 sizeOfSignature; - }; - - // - // Used at suspend/resume to read GspFwHeapFreeList - // Offset relative to GspFwWprMeta FBMEM PA (gspFwWprStart) - // - struct - { - NvU32 gspFwHeapFreeListWprOffset; - NvU32 unused0; - NvU64 unused1; - }; - }; - - // ---- Members describing FB layout -------------------------------- - NvU64 gspFwRsvdStart; - - NvU64 nonWprHeapOffset; - NvU64 nonWprHeapSize; - - NvU64 gspFwWprStart; - - // GSP-RM to use to setup heap. - NvU64 gspFwHeapOffset; - NvU64 gspFwHeapSize; - - // BL to use to find ELF for jump - NvU64 gspFwOffset; - // Size is sizeOfRadix3Elf above. - - NvU64 bootBinOffset; - // Size is sizeOfBootloader above. - - NvU64 frtsOffset; - NvU64 frtsSize; - - NvU64 gspFwWprEnd; - - // GSP-RM to use for fbRegionInfo? - NvU64 fbSize; - - // ---- Other members ----------------------------------------------- - - // GSP-RM to use for fbRegionInfo? - NvU64 vgaWorkspaceOffset; - NvU64 vgaWorkspaceSize; - - // Boot count. Used to determine whether to load the firmware image. - NvU64 bootCount; - - // TODO: the partitionRpc* fields below do not really belong in this - // structure. The values are patched in by the partition bootstrapper - // when GSP-RM is booted in a partition, and this structure was a - // convenient place for the bootstrapper to access them. These should - // be moved to a different comm. mechanism between the bootstrapper - // and the GSP-RM tasks. - - union - { - struct - { - // Shared partition RPC memory (physical address) - NvU64 partitionRpcAddr; - - // Offsets relative to partitionRpcAddr - NvU16 partitionRpcRequestOffset; - NvU16 partitionRpcReplyOffset; - - // Code section and dataSection offset and size. - NvU32 elfCodeOffset; - NvU32 elfDataOffset; - NvU32 elfCodeSize; - NvU32 elfDataSize; - - // Used during GSP-RM resume to check for revocation - NvU32 lsUcodeVersion; - }; - - struct - { - // Pad for the partitionRpc* fields, plus 4 bytes - NvU32 partitionRpcPadding[4]; - - // CrashCat (contiguous) buffer size/location - occupies same bytes as the - // elf(Code|Data)(Offset|Size) fields above. - // TODO: move to GSP_FMC_INIT_PARAMS - NvU64 sysmemAddrOfCrashReportQueue; - NvU32 sizeOfCrashReportQueue; - - // Pad for the lsUcodeVersion field - NvU32 lsUcodeVersionPadding[1]; - }; - }; - - // Number of VF partitions allocating sub-heaps from the WPR heap - // Used during boot to ensure the heap is adequately sized - NvU8 gspFwHeapVfPartitionCount; - - // Pad structure to exactly 256 bytes. Can replace padding with additional - // fields without incrementing revision. Padding initialized to 0. - NvU8 padding[7]; - - // BL to use for verification (i.e. Booter says OK to boot) - NvU64 verified; // 0x0 -> unverified, 0xa0a0a0a0a0a0a0a0 -> verified -} GspFwWprMeta; - -#define GSP_FW_WPR_META_REVISION 1 -#define GSP_FW_WPR_META_MAGIC 0xdc3aae21371a60b3ULL - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmRiscvUcode.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmRiscvUcode.h deleted file mode 100644 index 4eff473e8990..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmRiscvUcode.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef __src_nvidia_arch_nvalloc_common_inc_rmRiscvUcode_h__ -#define __src_nvidia_arch_nvalloc_common_inc_rmRiscvUcode_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2018-2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct { - // - // Version 1 - // Version 2 - // Version 3 = for Partition boot - // Version 4 = for eb riscv boot - // Version 5 = Support signing entire RISC-V image as "code" in code section for hopper and later. - // - NvU32 version; // structure version - NvU32 bootloaderOffset; - NvU32 bootloaderSize; - NvU32 bootloaderParamOffset; - NvU32 bootloaderParamSize; - NvU32 riscvElfOffset; - NvU32 riscvElfSize; - NvU32 appVersion; // Changelist number associated with the image - // - // Manifest contains information about Monitor and it is - // input to BR - // - NvU32 manifestOffset; - NvU32 manifestSize; - // - // Monitor Data offset within RISCV image and size - // - NvU32 monitorDataOffset; - NvU32 monitorDataSize; - // - // Monitor Code offset withtin RISCV image and size - // - NvU32 monitorCodeOffset; - NvU32 monitorCodeSize; - NvU32 bIsMonitorEnabled; - // - // Swbrom Code offset within RISCV image and size - // - NvU32 swbromCodeOffset; - NvU32 swbromCodeSize; - // - // Swbrom Data offset within RISCV image and size - // - NvU32 swbromDataOffset; - NvU32 swbromDataSize; - // - // Total size of FB carveout (image and reserved space). - // - NvU32 fbReservedSize; - // - // Indicates whether the entire RISC-V image is signed as "code" in code section. - // - NvU32 bSignedAsCode; -} RM_RISCV_UCODE_DESC; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmgspseq.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmgspseq.h deleted file mode 100644 index 341ab0dbeaf2..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmgspseq.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef __src_nvidia_arch_nvalloc_common_inc_rmgspseq_h__ -#define __src_nvidia_arch_nvalloc_common_inc_rmgspseq_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2019-2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef enum GSP_SEQ_BUF_OPCODE -{ - GSP_SEQ_BUF_OPCODE_REG_WRITE = 0, - GSP_SEQ_BUF_OPCODE_REG_MODIFY, - GSP_SEQ_BUF_OPCODE_REG_POLL, - GSP_SEQ_BUF_OPCODE_DELAY_US, - GSP_SEQ_BUF_OPCODE_REG_STORE, - GSP_SEQ_BUF_OPCODE_CORE_RESET, - GSP_SEQ_BUF_OPCODE_CORE_START, - GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT, - GSP_SEQ_BUF_OPCODE_CORE_RESUME, -} GSP_SEQ_BUF_OPCODE; - -#define GSP_SEQUENCER_PAYLOAD_SIZE_DWORDS(opcode) \ - ((opcode == GSP_SEQ_BUF_OPCODE_REG_WRITE) ? (sizeof(GSP_SEQ_BUF_PAYLOAD_REG_WRITE) / sizeof(NvU32)) : \ - (opcode == GSP_SEQ_BUF_OPCODE_REG_MODIFY) ? (sizeof(GSP_SEQ_BUF_PAYLOAD_REG_MODIFY) / sizeof(NvU32)) : \ - (opcode == GSP_SEQ_BUF_OPCODE_REG_POLL) ? (sizeof(GSP_SEQ_BUF_PAYLOAD_REG_POLL) / sizeof(NvU32)) : \ - (opcode == GSP_SEQ_BUF_OPCODE_DELAY_US) ? (sizeof(GSP_SEQ_BUF_PAYLOAD_DELAY_US) / sizeof(NvU32)) : \ - (opcode == GSP_SEQ_BUF_OPCODE_REG_STORE) ? (sizeof(GSP_SEQ_BUF_PAYLOAD_REG_STORE) / sizeof(NvU32)) : \ - /* GSP_SEQ_BUF_OPCODE_CORE_RESET */ \ - /* GSP_SEQ_BUF_OPCODE_CORE_START */ \ - /* GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT */ \ - /* GSP_SEQ_BUF_OPCODE_CORE_RESUME */ \ - 0) - -typedef struct -{ - NvU32 addr; - NvU32 val; -} GSP_SEQ_BUF_PAYLOAD_REG_WRITE; - -typedef struct -{ - NvU32 addr; - NvU32 mask; - NvU32 val; -} GSP_SEQ_BUF_PAYLOAD_REG_MODIFY; - -typedef struct -{ - NvU32 addr; - NvU32 mask; - NvU32 val; - NvU32 timeout; - NvU32 error; -} GSP_SEQ_BUF_PAYLOAD_REG_POLL; - -typedef struct -{ - NvU32 val; -} GSP_SEQ_BUF_PAYLOAD_DELAY_US; - -typedef struct -{ - NvU32 addr; - NvU32 index; -} GSP_SEQ_BUF_PAYLOAD_REG_STORE; - -typedef struct GSP_SEQUENCER_BUFFER_CMD -{ - GSP_SEQ_BUF_OPCODE opCode; - union - { - GSP_SEQ_BUF_PAYLOAD_REG_WRITE regWrite; - GSP_SEQ_BUF_PAYLOAD_REG_MODIFY regModify; - GSP_SEQ_BUF_PAYLOAD_REG_POLL regPoll; - GSP_SEQ_BUF_PAYLOAD_DELAY_US delayUs; - GSP_SEQ_BUF_PAYLOAD_REG_STORE regStore; - } payload; -} GSP_SEQUENCER_BUFFER_CMD; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_allclasses.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_allclasses.h deleted file mode 100644 index 3144e9beac61..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_allclasses.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __src_nvidia_generated_g_allclasses_h__ -#define __src_nvidia_generated_g_allclasses_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2021-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV01_EVENT_KERNEL_CALLBACK_EX (0x0000007e) - -#define NV04_DISPLAY_COMMON (0x00000073) - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_chipset_nvoc.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_chipset_nvoc.h deleted file mode 100644 index 6b8921138c7d..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_chipset_nvoc.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __src_nvidia_generated_g_chipset_nvoc_h__ -#define __src_nvidia_generated_g_chipset_nvoc_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct -{ - NvU16 deviceID; // deviceID - NvU16 vendorID; // vendorID - NvU16 subdeviceID; // subsystem deviceID - NvU16 subvendorID; // subsystem vendorID - NvU8 revisionID; // revision ID -} BUSINFO; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_fbsr_nvoc.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_fbsr_nvoc.h deleted file mode 100644 index a5128f00225b..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_fbsr_nvoc.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __src_nvidia_generated_g_fbsr_nvoc_h__ -#define __src_nvidia_generated_g_fbsr_nvoc_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2009-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define FBSR_TYPE_DMA 4 // Copy using DMA. Fastest. - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_gpu_nvoc.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_gpu_nvoc.h deleted file mode 100644 index 5641a21cacca..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_gpu_nvoc.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __src_nvidia_generated_g_gpu_nvoc_h__ -#define __src_nvidia_generated_g_gpu_nvoc_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2004-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef enum -{ - COMPUTE_BRANDING_TYPE_NONE, - COMPUTE_BRANDING_TYPE_TESLA, -} COMPUTE_BRANDING_TYPE; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_kernel_channel_nvoc.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_kernel_channel_nvoc.h deleted file mode 100644 index b5ad55f854dc..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_kernel_channel_nvoc.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef __src_nvidia_generated_g_kernel_channel_nvoc_h__ -#define __src_nvidia_generated_g_kernel_channel_nvoc_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2020-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef enum { - /*! - * Initial state as passed in NV_CHANNEL_ALLOC_PARAMS by - * kernel CPU-RM clients. - */ - ERROR_NOTIFIER_TYPE_UNKNOWN = 0, - /*! @brief Error notifier is explicitly not set. - * - * The corresponding hErrorContext or hEccErrorContext must be - * NV01_NULL_OBJECT. - */ - ERROR_NOTIFIER_TYPE_NONE, - /*! @brief Error notifier is a ContextDma */ - ERROR_NOTIFIER_TYPE_CTXDMA, - /*! @brief Error notifier is a NvNotification array in sysmem/vidmem */ - ERROR_NOTIFIER_TYPE_MEMORY -} ErrorNotifierType; - -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE 1:0 -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE_USER 0x0 -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE_ADMIN 0x1 -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE_KERNEL 0x2 -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE 3:2 -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_UNKNOWN ERROR_NOTIFIER_TYPE_UNKNOWN -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_NONE ERROR_NOTIFIER_TYPE_NONE -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_CTXDMA ERROR_NOTIFIER_TYPE_CTXDMA -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_MEMORY ERROR_NOTIFIER_TYPE_MEMORY -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE 5:4 -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_UNKNOWN ERROR_NOTIFIER_TYPE_UNKNOWN -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_NONE ERROR_NOTIFIER_TYPE_NONE -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_CTXDMA ERROR_NOTIFIER_TYPE_CTXDMA -#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_MEMORY ERROR_NOTIFIER_TYPE_MEMORY - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_kernel_fifo_nvoc.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_kernel_fifo_nvoc.h deleted file mode 100644 index 946954ac5b3d..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_kernel_fifo_nvoc.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef __src_nvidia_generated_g_kernel_fifo_nvoc_h__ -#define __src_nvidia_generated_g_kernel_fifo_nvoc_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef enum -{ - /* ************************************************************************* - * Bug 3820969 - * THINK BEFORE CHANGING ENUM ORDER HERE. - * VGPU-guest uses this same ordering. Because this enum is not versioned, - * changing the order here WILL BREAK old-guest-on-newer-host compatibility. - * ************************************************************************/ - - // *ENG_XYZ, e.g.: ENG_GR, ENG_CE etc., - ENGINE_INFO_TYPE_ENG_DESC = 0, - - // HW engine ID - ENGINE_INFO_TYPE_FIFO_TAG, - - // RM_ENGINE_TYPE_* - ENGINE_INFO_TYPE_RM_ENGINE_TYPE, - - // - // runlist id (meaning varies by GPU) - // Valid only for Esched-driven engines - // - ENGINE_INFO_TYPE_RUNLIST, - - // NV_PFIFO_INTR_MMU_FAULT_ENG_ID_* - ENGINE_INFO_TYPE_MMU_FAULT_ID, - - // ROBUST_CHANNEL_* - ENGINE_INFO_TYPE_RC_MASK, - - // Reset Bit Position. On Ampere, only valid if not _INVALID - ENGINE_INFO_TYPE_RESET, - - // Interrupt Bit Position - ENGINE_INFO_TYPE_INTR, - - // log2(MC_ENGINE_*) - ENGINE_INFO_TYPE_MC, - - // The DEV_TYPE_ENUM for this engine - ENGINE_INFO_TYPE_DEV_TYPE_ENUM, - - // The particular instance of this engine type - ENGINE_INFO_TYPE_INSTANCE_ID, - - // - // The base address for this engine's NV_RUNLIST. Valid only on Ampere+ - // Valid only for Esched-driven engines - // - ENGINE_INFO_TYPE_RUNLIST_PRI_BASE, - - // - // If this entry is a host-driven engine. - // Update _isEngineInfoTypeValidForOnlyHostDriven when adding any new entry. - // - ENGINE_INFO_TYPE_IS_HOST_DRIVEN_ENGINE, - - // - // The index into the per-engine NV_RUNLIST registers. Valid only on Ampere+ - // Valid only for Esched-driven engines - // - ENGINE_INFO_TYPE_RUNLIST_ENGINE_ID, - - // - // The base address for this engine's NV_CHRAM registers. Valid only on - // Ampere+ - // - // Valid only for Esched-driven engines - // - ENGINE_INFO_TYPE_CHRAM_PRI_BASE, - - // This entry added to copy data at RMCTRL_EXPORT() call for Kernel RM - ENGINE_INFO_TYPE_KERNEL_RM_MAX, - // Used for iterating the engine info table by the index passed. - ENGINE_INFO_TYPE_INVALID = ENGINE_INFO_TYPE_KERNEL_RM_MAX, - - // Size of FIFO_ENGINE_LIST.engineData - ENGINE_INFO_TYPE_ENGINE_DATA_ARRAY_SIZE = ENGINE_INFO_TYPE_INVALID, - - // Input-only parameter for kfifoEngineInfoXlate. - ENGINE_INFO_TYPE_PBDMA_ID - - /* ************************************************************************* - * Bug 3820969 - * THINK BEFORE CHANGING ENUM ORDER HERE. - * VGPU-guest uses this same ordering. Because this enum is not versioned, - * changing the order here WILL BREAK old-guest-on-newer-host compatibility. - * ************************************************************************/ -} ENGINE_INFO_TYPE; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_mem_desc_nvoc.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_mem_desc_nvoc.h deleted file mode 100644 index daabaee41c87..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_mem_desc_nvoc.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __src_nvidia_generated_g_mem_desc_nvoc_h__ -#define __src_nvidia_generated_g_mem_desc_nvoc_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define ADDR_SYSMEM 1 // System memory (PCI) -#define ADDR_FBMEM 2 // Frame buffer memory space - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_os_nvoc.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_os_nvoc.h deleted file mode 100644 index 10121218f4d3..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_os_nvoc.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __src_nvidia_generated_g_os_nvoc_h__ -#define __src_nvidia_generated_g_os_nvoc_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct PACKED_REGISTRY_ENTRY -{ - NvU32 nameOffset; - NvU8 type; - NvU32 data; - NvU32 length; -} PACKED_REGISTRY_ENTRY; - -typedef struct PACKED_REGISTRY_TABLE -{ - NvU32 size; - NvU32 numEntries; - PACKED_REGISTRY_ENTRY entries[] __counted_by(numEntries); -} PACKED_REGISTRY_TABLE; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_rpc-structures.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_rpc-structures.h deleted file mode 100644 index 8d925e24faea..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_rpc-structures.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef __src_nvidia_generated_g_rpc_structures_h__ -#define __src_nvidia_generated_g_rpc_structures_h__ -#include <nvrm/535.113.01/nvidia/generated/g_sdk-structures.h> -#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/sdk-structures.h> - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2008-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct rpc_alloc_memory_v13_01 -{ - NvHandle hClient; - NvHandle hDevice; - NvHandle hMemory; - NvU32 hClass; - NvU32 flags; - NvU32 pteAdjust; - NvU32 format; - NvU64 length NV_ALIGN_BYTES(8); - NvU32 pageCount; - struct pte_desc pteDesc; -} rpc_alloc_memory_v13_01; - -typedef struct rpc_free_v03_00 -{ - NVOS00_PARAMETERS_v03_00 params; -} rpc_free_v03_00; - -typedef struct rpc_unloading_guest_driver_v1F_07 -{ - NvBool bInPMTransition; - NvBool bGc6Entering; - NvU32 newLevel; -} rpc_unloading_guest_driver_v1F_07; - -typedef struct rpc_update_bar_pde_v15_00 -{ - UpdateBarPde_v15_00 info; -} rpc_update_bar_pde_v15_00; - -typedef struct rpc_gsp_rm_alloc_v03_00 -{ - NvHandle hClient; - NvHandle hParent; - NvHandle hObject; - NvU32 hClass; - NvU32 status; - NvU32 paramsSize; - NvU32 flags; - NvU8 reserved[4]; - NvU8 params[]; -} rpc_gsp_rm_alloc_v03_00; - -typedef struct rpc_gsp_rm_control_v03_00 -{ - NvHandle hClient; - NvHandle hObject; - NvU32 cmd; - NvU32 status; - NvU32 paramsSize; - NvU32 flags; - NvU8 params[]; -} rpc_gsp_rm_control_v03_00; - -typedef struct rpc_run_cpu_sequencer_v17_00 -{ - NvU32 bufferSizeDWord; - NvU32 cmdIndex; - NvU32 regSaveArea[8]; - NvU32 commandBuffer[]; -} rpc_run_cpu_sequencer_v17_00; - -typedef struct rpc_post_event_v17_00 -{ - NvHandle hClient; - NvHandle hEvent; - NvU32 notifyIndex; - NvU32 data; - NvU16 info16; - NvU32 status; - NvU32 eventDataSize; - NvBool bNotifyList; - NvU8 eventData[]; -} rpc_post_event_v17_00; - -typedef struct rpc_rc_triggered_v17_02 -{ - NvU32 nv2080EngineType; - NvU32 chid; - NvU32 exceptType; - NvU32 scope; - NvU16 partitionAttributionId; -} rpc_rc_triggered_v17_02; - -typedef struct rpc_os_error_log_v17_00 -{ - NvU32 exceptType; - NvU32 runlistId; - NvU32 chid; - char errString[0x100]; -} rpc_os_error_log_v17_00; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_sdk-structures.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_sdk-structures.h deleted file mode 100644 index e9fed4140468..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/generated/g_sdk-structures.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __src_nvidia_generated_g_sdk_structures_h__ -#define __src_nvidia_generated_g_sdk_structures_h__ -#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_headers.h> - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2008-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct NVOS00_PARAMETERS_v03_00 -{ - NvHandle hRoot; - NvHandle hObjectParent; - NvHandle hObjectOld; - NvV32 status; -} NVOS00_PARAMETERS_v03_00; - -typedef struct UpdateBarPde_v15_00 -{ - NV_RPC_UPDATE_PDE_BAR_TYPE barType; - NvU64 entryValue NV_ALIGN_BYTES(8); - NvU64 entryLevelShift NV_ALIGN_BYTES(8); -} UpdateBarPde_v15_00; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_acpi_data.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_acpi_data.h deleted file mode 100644 index af50b11ec3b4..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_acpi_data.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef __src_nvidia_inc_kernel_gpu_gpu_acpi_data_h__ -#define __src_nvidia_inc_kernel_gpu_gpu_acpi_data_h__ -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h> - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct DOD_METHOD_DATA -{ - NV_STATUS status; - NvU32 acpiIdListLen; - NvU32 acpiIdList[NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS]; -} DOD_METHOD_DATA; - -typedef struct JT_METHOD_DATA -{ - NV_STATUS status; - NvU32 jtCaps; - NvU16 jtRevId; - NvBool bSBIOSCaps; -} JT_METHOD_DATA; - -typedef struct MUX_METHOD_DATA_ELEMENT -{ - NvU32 acpiId; - NvU32 mode; - NV_STATUS status; -} MUX_METHOD_DATA_ELEMENT; - -typedef struct MUX_METHOD_DATA -{ - NvU32 tableLen; - MUX_METHOD_DATA_ELEMENT acpiIdMuxModeTable[NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS]; - MUX_METHOD_DATA_ELEMENT acpiIdMuxPartTable[NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS]; -} MUX_METHOD_DATA; - -typedef struct CAPS_METHOD_DATA -{ - NV_STATUS status; - NvU32 optimusCaps; -} CAPS_METHOD_DATA; - -typedef struct ACPI_METHOD_DATA -{ - NvBool bValid; - DOD_METHOD_DATA dodMethodData; - JT_METHOD_DATA jtMethodData; - MUX_METHOD_DATA muxMethodData; - CAPS_METHOD_DATA capsMethodData; -} ACPI_METHOD_DATA; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_engine_type.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_engine_type.h deleted file mode 100644 index e3160c60036d..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_engine_type.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef __src_nvidia_inc_kernel_gpu_gpu_engine_type_h__ -#define __src_nvidia_inc_kernel_gpu_gpu_engine_type_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef enum -{ - RM_ENGINE_TYPE_NULL = (0x00000000), - RM_ENGINE_TYPE_GR0 = (0x00000001), - RM_ENGINE_TYPE_GR1 = (0x00000002), - RM_ENGINE_TYPE_GR2 = (0x00000003), - RM_ENGINE_TYPE_GR3 = (0x00000004), - RM_ENGINE_TYPE_GR4 = (0x00000005), - RM_ENGINE_TYPE_GR5 = (0x00000006), - RM_ENGINE_TYPE_GR6 = (0x00000007), - RM_ENGINE_TYPE_GR7 = (0x00000008), - RM_ENGINE_TYPE_COPY0 = (0x00000009), - RM_ENGINE_TYPE_COPY1 = (0x0000000a), - RM_ENGINE_TYPE_COPY2 = (0x0000000b), - RM_ENGINE_TYPE_COPY3 = (0x0000000c), - RM_ENGINE_TYPE_COPY4 = (0x0000000d), - RM_ENGINE_TYPE_COPY5 = (0x0000000e), - RM_ENGINE_TYPE_COPY6 = (0x0000000f), - RM_ENGINE_TYPE_COPY7 = (0x00000010), - RM_ENGINE_TYPE_COPY8 = (0x00000011), - RM_ENGINE_TYPE_COPY9 = (0x00000012), - RM_ENGINE_TYPE_NVDEC0 = (0x0000001d), - RM_ENGINE_TYPE_NVDEC1 = (0x0000001e), - RM_ENGINE_TYPE_NVDEC2 = (0x0000001f), - RM_ENGINE_TYPE_NVDEC3 = (0x00000020), - RM_ENGINE_TYPE_NVDEC4 = (0x00000021), - RM_ENGINE_TYPE_NVDEC5 = (0x00000022), - RM_ENGINE_TYPE_NVDEC6 = (0x00000023), - RM_ENGINE_TYPE_NVDEC7 = (0x00000024), - RM_ENGINE_TYPE_NVENC0 = (0x00000025), - RM_ENGINE_TYPE_NVENC1 = (0x00000026), - RM_ENGINE_TYPE_NVENC2 = (0x00000027), - RM_ENGINE_TYPE_VP = (0x00000028), - RM_ENGINE_TYPE_ME = (0x00000029), - RM_ENGINE_TYPE_PPP = (0x0000002a), - RM_ENGINE_TYPE_MPEG = (0x0000002b), - RM_ENGINE_TYPE_SW = (0x0000002c), - RM_ENGINE_TYPE_TSEC = (0x0000002d), - RM_ENGINE_TYPE_VIC = (0x0000002e), - RM_ENGINE_TYPE_MP = (0x0000002f), - RM_ENGINE_TYPE_SEC2 = (0x00000030), - RM_ENGINE_TYPE_HOST = (0x00000031), - RM_ENGINE_TYPE_DPU = (0x00000032), - RM_ENGINE_TYPE_PMU = (0x00000033), - RM_ENGINE_TYPE_FBFLCN = (0x00000034), - RM_ENGINE_TYPE_NVJPEG0 = (0x00000035), - RM_ENGINE_TYPE_NVJPEG1 = (0x00000036), - RM_ENGINE_TYPE_NVJPEG2 = (0x00000037), - RM_ENGINE_TYPE_NVJPEG3 = (0x00000038), - RM_ENGINE_TYPE_NVJPEG4 = (0x00000039), - RM_ENGINE_TYPE_NVJPEG5 = (0x0000003a), - RM_ENGINE_TYPE_NVJPEG6 = (0x0000003b), - RM_ENGINE_TYPE_NVJPEG7 = (0x0000003c), - RM_ENGINE_TYPE_OFA = (0x0000003d), - RM_ENGINE_TYPE_LAST = (0x0000003e), -} RM_ENGINE_TYPE; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_fw_heap.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_fw_heap.h deleted file mode 100644 index 3abec59f0cc4..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_fw_heap.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __src_nvidia_inc_kernel_gpu_gsp_gsp_fw_heap_h__ -#define __src_nvidia_inc_kernel_gpu_gsp_gsp_fw_heap_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define GSP_FW_HEAP_PARAM_SIZE_PER_GB_FB (96 << 10) // All architectures - -#define GSP_FW_HEAP_PARAM_CLIENT_ALLOC_SIZE ((48 << 10) * 2048) // Support 2048 channels - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_init_args.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_init_args.h deleted file mode 100644 index 4033a6f85a76..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_init_args.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef __src_nvidia_inc_kernel_gpu_gsp_gsp_init_args_h__ -#define __src_nvidia_inc_kernel_gpu_gsp_gsp_init_args_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct { - RmPhysAddr sharedMemPhysAddr; - NvU32 pageTableEntryCount; - NvLength cmdQueueOffset; - NvLength statQueueOffset; - NvLength locklessCmdQueueOffset; - NvLength locklessStatQueueOffset; -} MESSAGE_QUEUE_INIT_ARGUMENTS; - -typedef struct { - NvU32 oldLevel; - NvU32 flags; - NvBool bInPMTransition; -} GSP_SR_INIT_ARGUMENTS; - -typedef struct -{ - MESSAGE_QUEUE_INIT_ARGUMENTS messageQueueInitArguments; - GSP_SR_INIT_ARGUMENTS srInitArguments; - NvU32 gpuInstance; - - struct - { - NvU64 pa; - NvU64 size; - } profilerArgs; -} GSP_ARGUMENTS_CACHED; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_static_config.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_static_config.h deleted file mode 100644 index eeab25a5e290..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_static_config.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef __src_nvidia_inc_kernel_gpu_gsp_gsp_static_config_h__ -#define __src_nvidia_inc_kernel_gpu_gsp_gsp_static_config_h__ -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gpu.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080gr.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080bios.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fb.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gr.h> -#include <nvrm/535.113.01/nvidia/generated/g_chipset_nvoc.h> -#include <nvrm/535.113.01/nvidia/generated/g_gpu_nvoc.h> -#include <nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_acpi_data.h> -#include <nvrm/535.113.01/nvidia/inc/kernel/gpu/nvbitmask.h> -#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_headers.h> - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -typedef struct GSP_VF_INFO -{ - NvU32 totalVFs; - NvU32 firstVFOffset; - NvU64 FirstVFBar0Address; - NvU64 FirstVFBar1Address; - NvU64 FirstVFBar2Address; - NvBool b64bitBar0; - NvBool b64bitBar1; - NvBool b64bitBar2; -} GSP_VF_INFO; - -typedef struct GspSMInfo_t -{ - NvU32 version; - NvU32 regBankCount; - NvU32 regBankRegCount; - NvU32 maxWarpsPerSM; - NvU32 maxThreadsPerWarp; - NvU32 geomGsObufEntries; - NvU32 geomXbufEntries; - NvU32 maxSPPerSM; - NvU32 rtCoreCount; -} GspSMInfo; - -typedef struct GspStaticConfigInfo_t -{ - NvU8 grCapsBits[NV0080_CTRL_GR_CAPS_TBL_SIZE]; - NV2080_CTRL_GPU_GET_GID_INFO_PARAMS gidInfo; - NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS gpcInfo; - NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS tpcInfo[MAX_GPC_COUNT]; - NV2080_CTRL_GPU_GET_FERMI_ZCULL_INFO_PARAMS zcullInfo[MAX_GPC_COUNT]; - NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS SKUInfo; - NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS fbRegionInfoParams; - COMPUTE_BRANDING_TYPE computeBranding; - - NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS sriovCaps; - NvU32 sriovMaxGfid; - - NvU32 engineCaps[NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX]; - - GspSMInfo SM_info; - - NvBool poisonFuseEnabled; - - NvU64 fb_length; - NvU32 fbio_mask; - NvU32 fb_bus_width; - NvU32 fb_ram_type; - NvU32 fbp_mask; - NvU32 l2_cache_size; - - NvU32 gfxpBufferSize[NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_CONTEXT_POOL]; - NvU32 gfxpBufferAlignment[NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_CONTEXT_POOL]; - - NvU8 gpuNameString[NV2080_GPU_MAX_NAME_STRING_LENGTH]; - NvU8 gpuShortNameString[NV2080_GPU_MAX_NAME_STRING_LENGTH]; - NvU16 gpuNameString_Unicode[NV2080_GPU_MAX_NAME_STRING_LENGTH]; - NvBool bGpuInternalSku; - NvBool bIsQuadroGeneric; - NvBool bIsQuadroAd; - NvBool bIsNvidiaNvs; - NvBool bIsVgx; - NvBool bGeforceSmb; - NvBool bIsTitan; - NvBool bIsTesla; - NvBool bIsMobile; - NvBool bIsGc6Rtd3Allowed; - NvBool bIsGcOffRtd3Allowed; - NvBool bIsGcoffLegacyAllowed; - - NvU64 bar1PdeBase; - NvU64 bar2PdeBase; - - NvBool bVbiosValid; - NvU32 vbiosSubVendor; - NvU32 vbiosSubDevice; - - NvBool bPageRetirementSupported; - - NvBool bSplitVasBetweenServerClientRm; - - NvBool bClRootportNeedsNosnoopWAR; - - VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS displaylessMaxHeads; - VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS displaylessMaxResolution; - NvU64 displaylessMaxPixels; - - // Client handle for internal RMAPI control. - NvHandle hInternalClient; - - // Device handle for internal RMAPI control. - NvHandle hInternalDevice; - - // Subdevice handle for internal RMAPI control. - NvHandle hInternalSubdevice; - - NvBool bSelfHostedMode; - NvBool bAtsSupported; - - NvBool bIsGpuUefi; -} GspStaticConfigInfo; - -typedef struct GspSystemInfo -{ - NvU64 gpuPhysAddr; - NvU64 gpuPhysFbAddr; - NvU64 gpuPhysInstAddr; - NvU64 nvDomainBusDeviceFunc; - NvU64 simAccessBufPhysAddr; - NvU64 pcieAtomicsOpMask; - NvU64 consoleMemSize; - NvU64 maxUserVa; - NvU32 pciConfigMirrorBase; - NvU32 pciConfigMirrorSize; - NvU8 oorArch; - NvU64 clPdbProperties; - NvU32 Chipset; - NvBool bGpuBehindBridge; - NvBool bMnocAvailable; - NvBool bUpstreamL0sUnsupported; - NvBool bUpstreamL1Unsupported; - NvBool bUpstreamL1PorSupported; - NvBool bUpstreamL1PorMobileOnly; - NvU8 upstreamAddressValid; - BUSINFO FHBBusInfo; - BUSINFO chipsetIDInfo; - ACPI_METHOD_DATA acpiMethodData; - NvU32 hypervisorType; - NvBool bIsPassthru; - NvU64 sysTimerOffsetNs; - GSP_VF_INFO gspVFInfo; -} GspSystemInfo; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/intr/engine_idx.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/intr/engine_idx.h deleted file mode 100644 index bd5e01f9814b..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/intr/engine_idx.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef __src_nvidia_inc_kernel_gpu_intr_engine_idx_h__ -#define __src_nvidia_inc_kernel_gpu_intr_engine_idx_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define MC_ENGINE_IDX_DISP 2 - -#define MC_ENGINE_IDX_CE0 15 - -#define MC_ENGINE_IDX_CE9 24 - -#define MC_ENGINE_IDX_MSENC 38 - -#define MC_ENGINE_IDX_MSENC2 40 - -#define MC_ENGINE_IDX_GSP 49 -#define MC_ENGINE_IDX_NVJPG 50 -#define MC_ENGINE_IDX_NVJPEG MC_ENGINE_IDX_NVJPG -#define MC_ENGINE_IDX_NVJPEG0 MC_ENGINE_IDX_NVJPEG - -#define MC_ENGINE_IDX_NVJPEG7 57 - -#define MC_ENGINE_IDX_BSP 64 -#define MC_ENGINE_IDX_NVDEC MC_ENGINE_IDX_BSP -#define MC_ENGINE_IDX_NVDEC0 MC_ENGINE_IDX_NVDEC - -#define MC_ENGINE_IDX_NVDEC7 71 - -#define MC_ENGINE_IDX_OFA0 80 - -#define MC_ENGINE_IDX_GR 82 -#define MC_ENGINE_IDX_GR0 MC_ENGINE_IDX_GR - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/nvbitmask.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/nvbitmask.h deleted file mode 100644 index 366447a368bf..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/gpu/nvbitmask.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __src_nvidia_inc_kernel_gpu_nvbitmask_h__ -#define __src_nvidia_inc_kernel_gpu_nvbitmask_h__ -#include <nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_engine_type.h> - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NVGPU_ENGINE_CAPS_MASK_BITS 32 -#define NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX ((RM_ENGINE_TYPE_LAST-1)/NVGPU_ENGINE_CAPS_MASK_BITS + 1) - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/os/nv_memory_type.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/os/nv_memory_type.h deleted file mode 100644 index 4a850dad4776..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/inc/kernel/os/nv_memory_type.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __src_nvidia_inc_kernel_os_nv_memory_type_h__ -#define __src_nvidia_inc_kernel_os_nv_memory_type_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define NV_MEMORY_WRITECOMBINED 2 - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_headers.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_headers.h deleted file mode 100644 index f14b23852456..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_headers.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __src_nvidia_kernel_inc_vgpu_rpc_headers_h__ -#define __src_nvidia_kernel_inc_vgpu_rpc_headers_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2017-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define MAX_GPC_COUNT 32 - -typedef enum -{ - NV_RPC_UPDATE_PDE_BAR_1, - NV_RPC_UPDATE_PDE_BAR_2, - NV_RPC_UPDATE_PDE_BAR_INVALID, -} NV_RPC_UPDATE_PDE_BAR_TYPE; - -typedef struct VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS -{ - NvU32 headIndex; - NvU32 maxHResolution; - NvU32 maxVResolution; -} VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS; - -typedef struct VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS -{ - NvU32 numHeads; - NvU32 maxNumHeads; -} VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/sdk-structures.h b/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/sdk-structures.h deleted file mode 100644 index 7801af232dff..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/sdk-structures.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __src_nvidia_kernel_inc_vgpu_sdk_structures_h__ -#define __src_nvidia_kernel_inc_vgpu_sdk_structures_h__ - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -struct pte_desc -{ - NvU32 idr:2; - NvU32 reserved1:14; - NvU32 length:16; - union { - NvU64 pte; // PTE when IDR==0; PDE when IDR > 0 - NvU64 pde; // PTE when IDR==0; PDE when IDR > 0 - } pte_pde[] NV_ALIGN_BYTES(8); // PTE when IDR==0; PDE when IDR > 0 -}; - -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/nvtypes.h b/drivers/gpu/drm/nouveau/include/nvrm/nvtypes.h index e6833df1ccc7..af11648ad9c8 100644 --- a/drivers/gpu/drm/nouveau/include/nvrm/nvtypes.h +++ b/drivers/gpu/drm/nouveau/include/nvrm/nvtypes.h @@ -21,4 +21,6 @@ typedef NvU64 NvLength; typedef NvU64 RmPhysAddr; typedef NvU32 NV_STATUS; + +typedef union {} rpc_generic_union; #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 2a0617e5fe2a..a3ba07fc48a0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -315,7 +315,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) break; } case NOUVEAU_GETPARAM_VRAM_BAR_SIZE: - getparam->value = nvkm_device->func->resource_size(nvkm_device, 1); + getparam->value = nvkm_device->func->resource_size(nvkm_device, NVKM_BAR1_FB); break; case NOUVEAU_GETPARAM_VRAM_USED: { struct ttm_resource_manager *vram_mgr = ttm_manager_type(&drm->ttm.bdev, TTM_PL_VRAM); @@ -416,7 +416,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) */ if (nouveau_cli_uvmm(cli)) { ret = nouveau_sched_create(&chan->sched, drm, drm->sched_wq, - chan->chan->dma.ib_max); + chan->chan->chan.gpfifo.max); if (ret) goto done; } diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 2016c1e7242f..b96f0555ca14 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -401,6 +401,83 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, return 0; } +void +nouveau_bo_unpin_del(struct nouveau_bo **pnvbo) +{ + struct nouveau_bo *nvbo = *pnvbo; + + if (!nvbo) + return; + + nouveau_bo_unmap(nvbo); + nouveau_bo_unpin(nvbo); + nouveau_bo_fini(nvbo); + + *pnvbo = NULL; +} + +int +nouveau_bo_new_pin(struct nouveau_cli *cli, u32 domain, u32 size, struct nouveau_bo **pnvbo) +{ + struct nouveau_bo *nvbo; + int ret; + + ret = nouveau_bo_new(cli, size, 0, domain, 0, 0, NULL, NULL, &nvbo); + if (ret) + return ret; + + ret = nouveau_bo_pin(nvbo, domain, false); + if (ret) { + nouveau_bo_fini(nvbo); + return ret; + } + + *pnvbo = nvbo; + return 0; +} + +int +nouveau_bo_new_map(struct nouveau_cli *cli, u32 domain, u32 size, struct nouveau_bo **pnvbo) +{ + struct nouveau_bo *nvbo; + int ret; + + ret = nouveau_bo_new_pin(cli, domain, size, &nvbo); + if (ret) + return ret; + + ret = nouveau_bo_map(nvbo); + if (ret) { + nouveau_bo_unpin_del(&nvbo); + return ret; + } + + *pnvbo = nvbo; + return 0; +} + +int +nouveau_bo_new_map_gpu(struct nouveau_cli *cli, u32 domain, u32 size, + struct nouveau_bo **pnvbo, struct nouveau_vma **pvma) +{ + struct nouveau_vmm *vmm = nouveau_cli_vmm(cli); + struct nouveau_bo *nvbo; + int ret; + + ret = nouveau_bo_new_map(cli, domain, size, &nvbo); + if (ret) + return ret; + + ret = nouveau_vma_new(nvbo, vmm, pvma); + if (ret) { + nouveau_bo_unpin_del(&nvbo); + return ret; + } + + *pnvbo = nvbo; + return 0; +} + static void set_placement_range(struct nouveau_bo *nvbo, uint32_t domain) { @@ -923,6 +1000,9 @@ nouveau_bo_move_init(struct nouveau_drm *drm) struct ttm_resource *, struct ttm_resource *); int (*init)(struct nouveau_channel *, u32 handle); } _methods[] = { + { "COPY", 4, 0xcab5, nve0_bo_move_copy, nve0_bo_move_init }, + { "COPY", 4, 0xc9b5, nve0_bo_move_copy, nve0_bo_move_init }, + { "COPY", 4, 0xc8b5, nve0_bo_move_copy, nve0_bo_move_init }, { "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init }, { "GRCE", 0, 0xc7b5, nve0_bo_move_copy, nvc0_bo_move_init }, { "COPY", 4, 0xc6b5, nve0_bo_move_copy, nve0_bo_move_init }, @@ -1204,7 +1284,7 @@ retry: fallthrough; /* tiled memory */ case TTM_PL_VRAM: reg->bus.offset = (reg->start << PAGE_SHIFT) + - device->func->resource_addr(device, 1); + device->func->resource_addr(device, NVKM_BAR1_FB); reg->bus.is_iomem = true; /* Some BARs do not support being ioremapped WC */ @@ -1295,7 +1375,7 @@ vm_fault_t nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) struct nouveau_drm *drm = nouveau_bdev(bo->bdev); struct nouveau_bo *nvbo = nouveau_bo(bo); struct nvkm_device *device = nvxx_device(drm); - u32 mappable = device->func->resource_size(device, 1) >> PAGE_SHIFT; + u32 mappable = device->func->resource_size(device, NVKM_BAR1_FB) >> PAGE_SHIFT; int i, ret; /* as long as the bo isn't in vram, and isn't tiled, we've got diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index 596a63a50a20..d59fd12268b9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -9,6 +9,7 @@ struct nouveau_channel; struct nouveau_cli; struct nouveau_drm; struct nouveau_fence; +struct nouveau_vma; struct nouveau_bo { struct ttm_buffer_object bo; @@ -89,6 +90,12 @@ void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo); void nouveau_bo_add_io_reserve_lru(struct ttm_buffer_object *bo); void nouveau_bo_del_io_reserve_lru(struct ttm_buffer_object *bo); +int nouveau_bo_new_pin(struct nouveau_cli *, u32 domain, u32 size, struct nouveau_bo **); +int nouveau_bo_new_map(struct nouveau_cli *, u32 domain, u32 size, struct nouveau_bo **); +int nouveau_bo_new_map_gpu(struct nouveau_cli *, u32 domain, u32 size, + struct nouveau_bo **, struct nouveau_vma **); +void nouveau_bo_unpin_del(struct nouveau_bo **); + /* TODO: submit equivalent to TTM generic API upstream? */ static inline void __iomem * nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo) diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 1286a664f688..b1e92b1f7a26 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -103,12 +103,11 @@ nouveau_channel_del(struct nouveau_channel **pchan) nvif_event_dtor(&chan->kill); nvif_object_dtor(&chan->user); nvif_mem_dtor(&chan->mem_userd); + nouveau_vma_del(&chan->sema.vma); + nouveau_bo_unpin_del(&chan->sema.bo); nvif_object_dtor(&chan->push.ctxdma); nouveau_vma_del(&chan->push.vma); - nouveau_bo_unmap(chan->push.buffer); - if (chan->push.buffer && chan->push.buffer->bo.pin_count) - nouveau_bo_unpin(chan->push.buffer); - nouveau_bo_fini(chan->push.buffer); + nouveau_bo_unpin_del(&chan->push.buffer); kfree(chan); } *pchan = NULL; @@ -163,14 +162,7 @@ nouveau_channel_prep(struct nouveau_cli *cli, if (nouveau_vram_pushbuf) target = NOUVEAU_GEM_DOMAIN_VRAM; - ret = nouveau_bo_new(cli, size, 0, target, 0, 0, NULL, NULL, - &chan->push.buffer); - if (ret == 0) { - ret = nouveau_bo_pin(chan->push.buffer, target, false); - if (ret == 0) - ret = nouveau_bo_map(chan->push.buffer); - } - + ret = nouveau_bo_new_map(cli, target, size, &chan->push.buffer); if (ret) { nouveau_channel_del(pchan); return ret; @@ -199,8 +191,10 @@ nouveau_channel_prep(struct nouveau_cli *cli, chan->push.addr = chan->push.vma->addr; - if (device->info.family >= NV_DEVICE_INFO_V0_FERMI) - return 0; + if (device->info.family >= NV_DEVICE_INFO_V0_FERMI) { + return nouveau_bo_new_map_gpu(cli, NOUVEAU_GEM_DOMAIN_GART, PAGE_SIZE, + &chan->sema.bo, &chan->sema.vma); + } args.target = NV_DMA_V0_TARGET_VM; args.access = NV_DMA_V0_ACCESS_VM; @@ -209,13 +203,15 @@ nouveau_channel_prep(struct nouveau_cli *cli, } else if (chan->push.buffer->bo.resource->mem_type == TTM_PL_VRAM) { if (device->info.family == NV_DEVICE_INFO_V0_TNT) { + struct nvkm_device *nvkm_device = nvxx_device(drm); + /* nv04 vram pushbuf hack, retarget to its location in * the framebuffer bar rather than direct vram access.. * nfi why this exists, it came from the -nv ddx. */ args.target = NV_DMA_V0_TARGET_PCI; args.access = NV_DMA_V0_ACCESS_RDWR; - args.start = nvxx_device(drm)->func->resource_addr(nvxx_device(drm), 1); + args.start = nvkm_device->func->resource_addr(nvkm_device, NVKM_BAR1_FB); args.limit = args.start + device->info.ram_user - 1; } else { args.target = NV_DMA_V0_TARGET_VRAM; @@ -253,21 +249,24 @@ nouveau_channel_ctor(struct nouveau_cli *cli, bool priv, u64 runm, struct nouveau_channel **pchan) { const struct nvif_mclass hosts[] = { - { AMPERE_CHANNEL_GPFIFO_B, 0 }, - { AMPERE_CHANNEL_GPFIFO_A, 0 }, - { TURING_CHANNEL_GPFIFO_A, 0 }, - { VOLTA_CHANNEL_GPFIFO_A, 0 }, - { PASCAL_CHANNEL_GPFIFO_A, 0 }, - { MAXWELL_CHANNEL_GPFIFO_A, 0 }, - { KEPLER_CHANNEL_GPFIFO_B, 0 }, - { KEPLER_CHANNEL_GPFIFO_A, 0 }, - { FERMI_CHANNEL_GPFIFO , 0 }, - { G82_CHANNEL_GPFIFO , 0 }, - { NV50_CHANNEL_GPFIFO , 0 }, - { NV40_CHANNEL_DMA , 0 }, - { NV17_CHANNEL_DMA , 0 }, - { NV10_CHANNEL_DMA , 0 }, - { NV03_CHANNEL_DMA , 0 }, + { BLACKWELL_CHANNEL_GPFIFO_B, 0 }, + { BLACKWELL_CHANNEL_GPFIFO_A, 0 }, + { HOPPER_CHANNEL_GPFIFO_A, 0 }, + { AMPERE_CHANNEL_GPFIFO_B, 0 }, + { AMPERE_CHANNEL_GPFIFO_A, 0 }, + { TURING_CHANNEL_GPFIFO_A, 0 }, + { VOLTA_CHANNEL_GPFIFO_A, 0 }, + { PASCAL_CHANNEL_GPFIFO_A, 0 }, + { MAXWELL_CHANNEL_GPFIFO_A, 0 }, + { KEPLER_CHANNEL_GPFIFO_B, 0 }, + { KEPLER_CHANNEL_GPFIFO_A, 0 }, + { FERMI_CHANNEL_GPFIFO , 0 }, + { G82_CHANNEL_GPFIFO , 0 }, + { NV50_CHANNEL_GPFIFO , 0 }, + { NV40_CHANNEL_DMA , 0 }, + { NV17_CHANNEL_DMA , 0 }, + { NV10_CHANNEL_DMA , 0 }, + { NV03_CHANNEL_DMA , 0 }, {} }; DEFINE_RAW_FLEX(struct nvif_chan_v0, args, name, TASK_COMM_LEN + 16); @@ -431,25 +430,33 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) } /* initialise dma tracking parameters */ - switch (chan->user.oclass) { - case NV03_CHANNEL_DMA: - case NV10_CHANNEL_DMA: - case NV17_CHANNEL_DMA: - case NV40_CHANNEL_DMA: + if (chan->user.oclass < NV50_CHANNEL_GPFIFO) { chan->user_put = 0x40; chan->user_get = 0x44; chan->dma.max = (0x10000 / 4) - 2; - break; - default: - chan->user_put = 0x40; - chan->user_get = 0x44; - chan->user_get_hi = 0x60; - chan->dma.ib_base = 0x10000 / 4; - chan->dma.ib_max = NV50_DMA_IB_MAX; - chan->dma.ib_put = 0; - chan->dma.ib_free = chan->dma.ib_max - chan->dma.ib_put; - chan->dma.max = chan->dma.ib_base; - break; + } else + if (chan->user.oclass < FERMI_CHANNEL_GPFIFO) { + ret = nvif_chan506f_ctor(&chan->chan, chan->userd->map.ptr, + (u8*)chan->push.buffer->kmap.virtual + 0x10000, 0x2000, + chan->push.buffer->kmap.virtual, chan->push.addr, 0x10000); + if (ret) + return ret; + } else + if (chan->user.oclass < VOLTA_CHANNEL_GPFIFO_A) { + ret = nvif_chan906f_ctor(&chan->chan, chan->userd->map.ptr, + (u8*)chan->push.buffer->kmap.virtual + 0x10000, 0x2000, + chan->push.buffer->kmap.virtual, chan->push.addr, 0x10000, + chan->sema.bo->kmap.virtual, chan->sema.vma->addr); + if (ret) + return ret; + } else { + ret = nvif_chanc36f_ctor(&chan->chan, chan->userd->map.ptr, + (u8*)chan->push.buffer->kmap.virtual + 0x10000, 0x2000, + chan->push.buffer->kmap.virtual, chan->push.addr, 0x10000, + chan->sema.bo->kmap.virtual, chan->sema.vma->addr, + &drm->client.device.user, chan->token); + if (ret) + return ret; } chan->dma.put = 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h index 016f668c0bc1..561877725aac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.h +++ b/drivers/gpu/drm/nouveau/nouveau_chan.h @@ -3,13 +3,11 @@ #define __NOUVEAU_CHAN_H__ #include <nvif/object.h> #include <nvif/event.h> -#include <nvif/push.h> +#include <nvif/chan.h> struct nvif_device; struct nouveau_channel { - struct { - struct nvif_push push; - } chan; + struct nvif_chan chan; struct nouveau_cli *cli; struct nouveau_vmm *vmm; @@ -41,15 +39,15 @@ struct nouveau_channel { int free; int cur; int put; - int ib_base; - int ib_max; - int ib_free; - int ib_put; } dma; - u32 user_get_hi; u32 user_get; u32 user_put; + struct { + struct nouveau_bo *bo; + struct nouveau_vma *vma; + } sema; + struct nvif_object user; struct nvif_object blit; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 1b10c6c12f46..63621b1510f6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1401,6 +1401,8 @@ nouveau_connector_create(struct drm_device *dev, int index) nv_connector->aux.drm_dev = dev; nv_connector->aux.transfer = nouveau_connector_aux_xfer; nv_connector->aux.name = connector->name; + if (disp->disp.object.oclass >= GB202_DISP) + nv_connector->aux.no_zero_sized = true; drm_dp_aux_init(&nv_connector->aux); break; default: diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index a1f329ef0641..017a803121d4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -43,8 +43,6 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) uint64_t val; val = nvif_rd32(chan->userd, chan->user_get); - if (chan->user_get_hi) - val |= (uint64_t)nvif_rd32(chan->userd, chan->user_get_hi) << 32; /* reset counter as long as GET is still advancing, this is * to avoid misdetecting a GPU lockup if the GPU happens to @@ -68,111 +66,12 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) return (val - chan->push.addr) >> 2; } -void -nv50_dma_push(struct nouveau_channel *chan, u64 offset, u32 length, - bool no_prefetch) -{ - struct nvif_user *user = &chan->cli->drm->client.device.user; - struct nouveau_bo *pb = chan->push.buffer; - int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; - - BUG_ON(chan->dma.ib_free < 1); - WARN_ON(length > NV50_DMA_PUSH_MAX_LENGTH); - - nouveau_bo_wr32(pb, ip++, lower_32_bits(offset)); - nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8 | - (no_prefetch ? (1 << 31) : 0)); - - chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max; - - mb(); - /* Flush writes. */ - nouveau_bo_rd32(pb, 0); - - nvif_wr32(chan->userd, 0x8c, chan->dma.ib_put); - if (user->func && user->func->doorbell) - user->func->doorbell(user, chan->token); - chan->dma.ib_free--; -} - -static int -nv50_dma_push_wait(struct nouveau_channel *chan, int count) -{ - uint32_t cnt = 0, prev_get = 0; - - while (chan->dma.ib_free < count) { - uint32_t get = nvif_rd32(chan->userd, 0x88); - if (get != prev_get) { - prev_get = get; - cnt = 0; - } - - if ((++cnt & 0xff) == 0) { - udelay(1); - if (cnt > 100000) - return -EBUSY; - } - - chan->dma.ib_free = get - chan->dma.ib_put; - if (chan->dma.ib_free <= 0) - chan->dma.ib_free += chan->dma.ib_max; - } - - return 0; -} - -static int -nv50_dma_wait(struct nouveau_channel *chan, int slots, int count) -{ - uint64_t prev_get = 0; - int ret, cnt = 0; - - ret = nv50_dma_push_wait(chan, slots + 1); - if (unlikely(ret)) - return ret; - - while (chan->dma.free < count) { - int get = READ_GET(chan, &prev_get, &cnt); - if (unlikely(get < 0)) { - if (get == -EINVAL) - continue; - - return get; - } - - if (get <= chan->dma.cur) { - chan->dma.free = chan->dma.max - chan->dma.cur; - if (chan->dma.free >= count) - break; - - FIRE_RING(chan); - do { - get = READ_GET(chan, &prev_get, &cnt); - if (unlikely(get < 0)) { - if (get == -EINVAL) - continue; - return get; - } - } while (get == 0); - chan->dma.cur = 0; - chan->dma.put = 0; - } - - chan->dma.free = get - chan->dma.cur - 1; - } - - return 0; -} - int -nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size) +nouveau_dma_wait(struct nouveau_channel *chan, int size) { uint64_t prev_get = 0; int cnt = 0, get; - if (chan->dma.ib_max) - return nv50_dma_wait(chan, slots, size); - while (chan->dma.free < size) { get = READ_GET(chan, &prev_get, &cnt); if (unlikely(get == -EBUSY)) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index c52cda82353e..0e27b76d1e1c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -30,9 +30,7 @@ #include "nouveau_bo.h" #include "nouveau_chan.h" -int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); -void nv50_dma_push(struct nouveau_channel *, u64 addr, u32 length, - bool no_prefetch); +int nouveau_dma_wait(struct nouveau_channel *, int size); /* * There's a hw race condition where you can't jump to your PUT offset, @@ -67,7 +65,7 @@ RING_SPACE(struct nouveau_channel *chan, int size) { int ret; - ret = nouveau_dma_wait(chan, 1, size); + ret = nouveau_dma_wait(chan, size); if (ret) return ret; @@ -94,12 +92,7 @@ FIRE_RING(struct nouveau_channel *chan) return; chan->accel_done = true; - if (chan->dma.ib_max) { - nv50_dma_push(chan, chan->push.addr + (chan->dma.put << 2), - (chan->dma.cur - chan->dma.put) << 2, false); - } else { - WRITE_PUT(chan->dma.cur); - } + WRITE_PUT(chan->dma.cur); chan->dma.put = chan->dma.cur; } diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c index 61d0f411ef84..ca4932a150e3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c @@ -256,20 +256,15 @@ nouveau_dmem_chunk_alloc(struct nouveau_drm *drm, struct page **ppage) chunk->pagemap.ops = &nouveau_dmem_pagemap_ops; chunk->pagemap.owner = drm->dev; - ret = nouveau_bo_new(&drm->client, DMEM_CHUNK_SIZE, 0, - NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, NULL, NULL, - &chunk->bo); + ret = nouveau_bo_new_pin(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, DMEM_CHUNK_SIZE, + &chunk->bo); if (ret) goto out_release; - ret = nouveau_bo_pin(chunk->bo, NOUVEAU_GEM_DOMAIN_VRAM, false); - if (ret) - goto out_bo_free; - ptr = memremap_pages(&chunk->pagemap, numa_node_id()); if (IS_ERR(ptr)) { ret = PTR_ERR(ptr); - goto out_bo_unpin; + goto out_bo_free; } mutex_lock(&drm->dmem->mutex); @@ -292,10 +287,8 @@ nouveau_dmem_chunk_alloc(struct nouveau_drm *drm, struct page **ppage) return 0; -out_bo_unpin: - nouveau_bo_unpin(chunk->bo); out_bo_free: - nouveau_bo_fini(chunk->bo); + nouveau_bo_unpin_del(&chunk->bo); out_release: release_mem_region(chunk->pagemap.range.start, range_len(&chunk->pagemap.range)); out_free: @@ -426,8 +419,7 @@ nouveau_dmem_fini(struct nouveau_drm *drm) list_for_each_entry_safe(chunk, tmp, &drm->dmem->chunks, list) { nouveau_dmem_evict_chunk(chunk); - nouveau_bo_unpin(chunk->bo); - nouveau_bo_fini(chunk->bo); + nouveau_bo_unpin_del(&chunk->bo); WARN_ON(chunk->callocated); list_del(&chunk->list); memunmap_pages(&chunk->pagemap); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index c69139701056..0c82a63cd49d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -503,11 +503,16 @@ nouveau_accel_init(struct nouveau_drm *drm) case KEPLER_CHANNEL_GPFIFO_B: case MAXWELL_CHANNEL_GPFIFO_A: case PASCAL_CHANNEL_GPFIFO_A: + ret = nvc0_fence_create(drm); + break; case VOLTA_CHANNEL_GPFIFO_A: case TURING_CHANNEL_GPFIFO_A: case AMPERE_CHANNEL_GPFIFO_A: case AMPERE_CHANNEL_GPFIFO_B: - ret = nvc0_fence_create(drm); + case HOPPER_CHANNEL_GPFIFO_A: + case BLACKWELL_CHANNEL_GPFIFO_A: + case BLACKWELL_CHANNEL_GPFIFO_B: + ret = gv100_fence_create(drm); break; default: break; diff --git a/drivers/gpu/drm/nouveau/nouveau_exec.c b/drivers/gpu/drm/nouveau/nouveau_exec.c index a0b5f1b16e8b..41b7c608c905 100644 --- a/drivers/gpu/drm/nouveau/nouveau_exec.c +++ b/drivers/gpu/drm/nouveau/nouveau_exec.c @@ -10,6 +10,8 @@ #include "nouveau_sched.h" #include "nouveau_uvmm.h" +#include <nvif/class.h> + /** * DOC: Overview * @@ -131,7 +133,7 @@ nouveau_exec_job_run(struct nouveau_job *job) struct nouveau_fence *fence = exec_job->fence; int i, ret; - ret = nouveau_dma_wait(chan, exec_job->push.count + 1, 16); + ret = nvif_chan_gpfifo_wait(&chan->chan, exec_job->push.count + 1, 16); if (ret) { NV_PRINTK(err, job->cli, "nv50cal_space: %d\n", ret); return ERR_PTR(ret); @@ -141,9 +143,11 @@ nouveau_exec_job_run(struct nouveau_job *job) struct drm_nouveau_exec_push *p = &exec_job->push.s[i]; bool no_prefetch = p->flags & DRM_NOUVEAU_EXEC_PUSH_NO_PREFETCH; - nv50_dma_push(chan, p->va, p->va_len, no_prefetch); + nvif_chan_gpfifo_push(&chan->chan, p->va, p->va_len, no_prefetch); } + nvif_chan_gpfifo_post(&chan->chan); + ret = nouveau_fence_emit(fence); if (ret) { nouveau_fence_unref(&exec_job->fence); @@ -375,10 +379,10 @@ nouveau_exec_ioctl_exec(struct drm_device *dev, if (unlikely(atomic_read(&chan->killed))) return nouveau_abi16_put(abi16, -ENODEV); - if (!chan->dma.ib_max) + if (chan->user.oclass < NV50_CHANNEL_GPFIFO) return nouveau_abi16_put(abi16, -ENOSYS); - push_max = nouveau_exec_push_max_from_ib_max(chan->dma.ib_max); + push_max = nouveau_exec_push_max_from_ib_max(chan->chan.gpfifo.max); if (unlikely(req->push_count > push_max)) { NV_PRINTK(err, cli, "pushbuf push count exceeds limit: %d max %d\n", req->push_count, push_max); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index 8bc065acfe35..6a983dd9f7b9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -83,6 +83,7 @@ void nv17_fence_resume(struct nouveau_drm *drm); int nv50_fence_create(struct nouveau_drm *); int nv84_fence_create(struct nouveau_drm *); int nvc0_fence_create(struct nouveau_drm *); +int gv100_fence_create(struct nouveau_drm *); struct nv84_fence_chan { struct nouveau_fence_chan base; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 67e3c99de73a..690e10fbf0bd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -850,8 +850,8 @@ revalidate: } } - if (chan->dma.ib_max) { - ret = nouveau_dma_wait(chan, req->nr_push + 1, 16); + if (chan->user.oclass >= NV50_CHANNEL_GPFIFO) { + ret = nvif_chan_gpfifo_wait(&chan->chan, req->nr_push + 1, 16); if (ret) { NV_PRINTK(err, cli, "nv50cal_space: %d\n", ret); goto out; @@ -864,8 +864,10 @@ revalidate: u32 length = push[i].length & ~NOUVEAU_GEM_PUSHBUF_NO_PREFETCH; bool no_prefetch = push[i].length & NOUVEAU_GEM_PUSHBUF_NO_PREFETCH; - nv50_dma_push(chan, addr, length, no_prefetch); + nvif_chan_gpfifo_push(&chan->chan, addr, length, no_prefetch); } + + nvif_chan_gpfifo_post(&chan->chan); } else if (drm->client.device.info.chipset >= 0x25) { ret = PUSH_WAIT(&chan->chan.push, req->nr_push * 2); @@ -958,7 +960,7 @@ out_prevalid: u_free(push); out_next: - if (chan->dma.ib_max) { + if (chan->user.oclass >= NV50_CHANNEL_GPFIFO) { req->suffix0 = 0x00000000; req->suffix1 = 0x00000000; } else diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index e244927eb5d4..7d2436e5d50d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -312,8 +312,8 @@ nouveau_ttm_init(struct nouveau_drm *drm) /* VRAM init */ drm->gem.vram_available = drm->client.device.info.ram_user; - arch_io_reserve_memtype_wc(device->func->resource_addr(device, 1), - device->func->resource_size(device, 1)); + arch_io_reserve_memtype_wc(device->func->resource_addr(device, NVKM_BAR1_FB), + device->func->resource_size(device, NVKM_BAR1_FB)); ret = nouveau_ttm_init_vram(drm); if (ret) { @@ -321,8 +321,8 @@ nouveau_ttm_init(struct nouveau_drm *drm) return ret; } - drm->ttm.mtrr = arch_phys_wc_add(device->func->resource_addr(device, 1), - device->func->resource_size(device, 1)); + drm->ttm.mtrr = arch_phys_wc_add(device->func->resource_addr(device, NVKM_BAR1_FB), + device->func->resource_size(device, NVKM_BAR1_FB)); /* GART init */ if (!drm->agp.bridge) { @@ -357,7 +357,7 @@ nouveau_ttm_fini(struct nouveau_drm *drm) arch_phys_wc_del(drm->ttm.mtrr); drm->ttm.mtrr = 0; - arch_io_free_memtype_wc(device->func->resource_addr(device, 1), - device->func->resource_size(device, 1)); + arch_io_free_memtype_wc(device->func->resource_addr(device, NVKM_BAR1_FB), + device->func->resource_size(device, NVKM_BAR1_FB)); } diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c index 8c73f40e3bda..40ee95340814 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/drivers/gpu/drm/nouveau/nv10_fence.c @@ -85,10 +85,8 @@ void nv10_fence_destroy(struct nouveau_drm *drm) { struct nv10_fence_priv *priv = drm->fence; - nouveau_bo_unmap(priv->bo); - if (priv->bo) - nouveau_bo_unpin(priv->bo); - nouveau_bo_fini(priv->bo); + + nouveau_bo_unpin_del(&priv->bo); drm->fence = NULL; kfree(priv); } diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c b/drivers/gpu/drm/nouveau/nv17_fence.c index d09bfd11369f..1b0c0aa3c305 100644 --- a/drivers/gpu/drm/nouveau/nv17_fence.c +++ b/drivers/gpu/drm/nouveau/nv17_fence.c @@ -130,20 +130,7 @@ nv17_fence_create(struct nouveau_drm *drm) priv->base.context_del = nv10_fence_context_del; spin_lock_init(&priv->lock); - ret = nouveau_bo_new(&drm->client, 4096, 0x1000, - NOUVEAU_GEM_DOMAIN_VRAM, - 0, 0x0000, NULL, NULL, &priv->bo); - if (!ret) { - ret = nouveau_bo_pin(priv->bo, NOUVEAU_GEM_DOMAIN_VRAM, false); - if (!ret) { - ret = nouveau_bo_map(priv->bo); - if (ret) - nouveau_bo_unpin(priv->bo); - } - if (ret) - nouveau_bo_fini(priv->bo); - } - + ret = nouveau_bo_new_map(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, PAGE_SIZE, &priv->bo); if (ret) { nv10_fence_destroy(drm); return ret; diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c index 62e28dddf87c..e1f0e8adf313 100644 --- a/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/drivers/gpu/drm/nouveau/nv50_fence.c @@ -81,20 +81,7 @@ nv50_fence_create(struct nouveau_drm *drm) priv->base.context_del = nv10_fence_context_del; spin_lock_init(&priv->lock); - ret = nouveau_bo_new(&drm->client, 4096, 0x1000, - NOUVEAU_GEM_DOMAIN_VRAM, - 0, 0x0000, NULL, NULL, &priv->bo); - if (!ret) { - ret = nouveau_bo_pin(priv->bo, NOUVEAU_GEM_DOMAIN_VRAM, false); - if (!ret) { - ret = nouveau_bo_map(priv->bo); - if (ret) - nouveau_bo_unpin(priv->bo); - } - if (ret) - nouveau_bo_fini(priv->bo); - } - + ret = nouveau_bo_new_map(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, PAGE_SIZE, &priv->bo); if (ret) { nv10_fence_destroy(drm); return ret; diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index aa7dd0c5d917..1765b2cedaf9 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -185,10 +185,8 @@ static void nv84_fence_destroy(struct nouveau_drm *drm) { struct nv84_fence_priv *priv = drm->fence; - nouveau_bo_unmap(priv->bo); - if (priv->bo) - nouveau_bo_unpin(priv->bo); - nouveau_bo_fini(priv->bo); + + nouveau_bo_unpin_del(&priv->bo); drm->fence = NULL; kfree(priv); } @@ -222,19 +220,8 @@ nv84_fence_create(struct nouveau_drm *drm) * will lose CPU/GPU coherency! */ NOUVEAU_GEM_DOMAIN_GART | NOUVEAU_GEM_DOMAIN_COHERENT; - ret = nouveau_bo_new(&drm->client, 16 * drm->chan_total, 0, - domain, 0, 0, NULL, NULL, &priv->bo); - if (ret == 0) { - ret = nouveau_bo_pin(priv->bo, domain, false); - if (ret == 0) { - ret = nouveau_bo_map(priv->bo); - if (ret) - nouveau_bo_unpin(priv->bo); - } - if (ret) - nouveau_bo_fini(priv->bo); - } + ret = nouveau_bo_new_map(&drm->client, domain, 16 * drm->chan_total, &priv->bo); if (ret) nv84_fence_destroy(drm); return ret; diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild index b7963a39dd91..198889c20ce1 100644 --- a/drivers/gpu/drm/nouveau/nvif/Kbuild +++ b/drivers/gpu/drm/nouveau/nvif/Kbuild @@ -14,6 +14,12 @@ nvif-y += nvif/outp.o nvif-y += nvif/timer.o nvif-y += nvif/vmm.o +# Channel classes +nvif-y += nvif/chan.o +nvif-y += nvif/chan506f.o +nvif-y += nvif/chan906f.o +nvif-y += nvif/chanc36f.o + # Usermode classes nvif-y += nvif/user.o nvif-y += nvif/userc361.o diff --git a/drivers/gpu/drm/nouveau/nvif/chan.c b/drivers/gpu/drm/nouveau/nvif/chan.c new file mode 100644 index 000000000000..baa10227d51a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/chan.c @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <nvif/chan.h> + +static void +nvif_chan_gpfifo_push_kick(struct nvif_push *push) +{ + struct nvif_chan *chan = container_of(push, typeof(*chan), push); + u32 put = push->bgn - (u32 *)chan->push.mem.object.map.ptr; + u32 cnt; + + if (chan->func->gpfifo.post) { + if (push->end - push->cur < chan->func->gpfifo.post_size) + push->end = push->cur + chan->func->gpfifo.post_size; + + WARN_ON(nvif_chan_gpfifo_post(chan)); + } + + cnt = push->cur - push->bgn; + + chan->func->gpfifo.push(chan, true, chan->push.addr + (put << 2), cnt << 2, false); + chan->func->gpfifo.kick(chan); +} + +static int +nvif_chan_gpfifo_push_wait(struct nvif_push *push, u32 push_nr) +{ + struct nvif_chan *chan = container_of(push, typeof(*chan), push); + + return nvif_chan_gpfifo_wait(chan, 1, push_nr); +} + +int +nvif_chan_gpfifo_post(struct nvif_chan *chan) +{ + const u32 *map = chan->push.mem.object.map.ptr; + const u32 pbptr = (chan->push.cur - map) + chan->func->gpfifo.post_size; + const u32 gpptr = (chan->gpfifo.cur + 1) & chan->gpfifo.max; + + return chan->func->gpfifo.post(chan, gpptr, pbptr); +} + +void +nvif_chan_gpfifo_push(struct nvif_chan *chan, u64 addr, u32 size, bool no_prefetch) +{ + chan->func->gpfifo.push(chan, false, addr, size, no_prefetch); +} + +int +nvif_chan_gpfifo_wait(struct nvif_chan *chan, u32 gpfifo_nr, u32 push_nr) +{ + struct nvif_push *push = &chan->push; + int ret = 0, time = 1000000; + + if (gpfifo_nr) { + /* Account for pushbuf space needed by nvif_chan_gpfifo_post(), + * if used after pushing userspace GPFIFO entries. + */ + if (chan->func->gpfifo.post) + push_nr += chan->func->gpfifo.post_size; + } + + /* Account for the GPFIFO entry needed to submit pushbuf. */ + if (push_nr) + gpfifo_nr++; + + /* Wait for space in main push buffer. */ + if (push->cur + push_nr > push->end) { + ret = nvif_chan_dma_wait(chan, push_nr); + if (ret) + return ret; + } + + /* Wait for GPFIFO space. */ + while (chan->gpfifo.free < gpfifo_nr) { + chan->gpfifo.free = chan->func->gpfifo.read_get(chan) - chan->gpfifo.cur - 1; + if (chan->gpfifo.free < 0) + chan->gpfifo.free += chan->gpfifo.max + 1; + + if (chan->gpfifo.free < gpfifo_nr) { + if (!time--) + return -ETIMEDOUT; + udelay(1); + } + } + + return 0; +} + +void +nvif_chan_gpfifo_ctor(const struct nvif_chan_func *func, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, struct nvif_chan *chan) +{ + chan->func = func; + + chan->userd.map.ptr = userd; + + chan->gpfifo.map.ptr = gpfifo; + chan->gpfifo.max = (gpfifo_size >> 3) - 1; + chan->gpfifo.free = chan->gpfifo.max; + + chan->push.mem.object.map.ptr = push; + chan->push.wait = nvif_chan_gpfifo_push_wait; + chan->push.kick = nvif_chan_gpfifo_push_kick; + chan->push.addr = push_addr; + chan->push.hw.max = push_size >> 2; + chan->push.bgn = chan->push.cur = chan->push.end = push; +} + +int +nvif_chan_dma_wait(struct nvif_chan *chan, u32 nr) +{ + struct nvif_push *push = &chan->push; + u32 cur = push->cur - (u32 *)push->mem.object.map.ptr; + u32 free, time = 1000000; + + nr += chan->func->gpfifo.post_size; + + do { + u32 get = chan->func->push.read_get(chan); + + if (get <= cur) { + free = push->hw.max - cur; + if (free >= nr) + break; + + PUSH_KICK(push); + + while (get == 0) { + get = chan->func->push.read_get(chan); + if (get == 0) { + if (!time--) + return -ETIMEDOUT; + udelay(1); + } + } + + cur = 0; + } + + free = get - cur - 1; + + if (free < nr) { + if (!time--) + return -ETIMEDOUT; + udelay(1); + } + } while (free < nr); + + push->bgn = (u32 *)push->mem.object.map.ptr + cur; + push->cur = push->bgn; + push->end = push->bgn + free - chan->func->gpfifo.post_size; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvif/chan506f.c b/drivers/gpu/drm/nouveau/nvif/chan506f.c new file mode 100644 index 000000000000..d3900887c4a7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/chan506f.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <nvif/chan.h> + +void +nvif_chan506f_gpfifo_kick(struct nvif_chan *chan) +{ + wmb(); + nvif_wr32(&chan->userd, 0x8c, chan->gpfifo.cur); +} + +void +nvif_chan506f_gpfifo_push(struct nvif_chan *chan, bool main, u64 addr, u32 size, bool no_prefetch) +{ + u32 gpptr = chan->gpfifo.cur << 3; + + if (WARN_ON(!chan->gpfifo.free)) + return; + + nvif_wr32(&chan->gpfifo, gpptr + 0, lower_32_bits(addr)); + nvif_wr32(&chan->gpfifo, gpptr + 4, upper_32_bits(addr) | + (main ? 0 : BIT(9)) | + (size >> 2) << 10 | + (no_prefetch ? BIT(31) : 0)); + + chan->gpfifo.cur = (chan->gpfifo.cur + 1) & chan->gpfifo.max; + chan->gpfifo.free--; + if (!chan->gpfifo.free) + chan->push.end = chan->push.cur; +} + +static u32 +nvif_chan506f_gpfifo_read_get(struct nvif_chan *chan) +{ + return nvif_rd32(&chan->userd, 0x88); +} + +static u32 +nvif_chan506f_read_get(struct nvif_chan *chan) +{ + u32 tlgetlo = nvif_rd32(&chan->userd, 0x58); + u32 tlgethi = nvif_rd32(&chan->userd, 0x5c); + struct nvif_push *push = &chan->push; + + /* Update cached GET pointer if TOP_LEVEL_GET is valid. */ + if (tlgethi & BIT(31)) { + u64 tlget = ((u64)(tlgethi & 0xff) << 32) | tlgetlo; + + push->hw.get = (tlget - push->addr) >> 2; + } + + return push->hw.get; +} + +static const struct nvif_chan_func +nvif_chan506f = { + .push.read_get = nvif_chan506f_read_get, + .gpfifo.read_get = nvif_chan506f_gpfifo_read_get, + .gpfifo.push = nvif_chan506f_gpfifo_push, + .gpfifo.kick = nvif_chan506f_gpfifo_kick, +}; + +int +nvif_chan506f_ctor(struct nvif_chan *chan, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size) +{ + nvif_chan_gpfifo_ctor(&nvif_chan506f, userd, gpfifo, gpfifo_size, + push, push_addr, push_size, chan); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvif/chan906f.c b/drivers/gpu/drm/nouveau/nvif/chan906f.c new file mode 100644 index 000000000000..c9cfb85179b0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/chan906f.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <nvif/chan.h> +#include <nvif/user.h> +#include <nvif/push906f.h> + +#include <nvhw/class/cl906f.h> + +/* Limits GPFIFO size to 1MiB, and "main" push buffer size to 64KiB. */ +#define NVIF_CHAN906F_PBPTR_BITS 15 +#define NVIF_CHAN906F_PBPTR_MASK ((1 << NVIF_CHAN906F_PBPTR_BITS) - 1) + +#define NVIF_CHAN906F_GPPTR_SHIFT NVIF_CHAN906F_PBPTR_BITS +#define NVIF_CHAN906F_GPPTR_BITS (32 - NVIF_CHAN906F_PBPTR_BITS) +#define NVIF_CHAN906F_GPPTR_MASK ((1 << NVIF_CHAN906F_GPPTR_BITS) - 1) + +#define NVIF_CHAN906F_SEM_RELEASE_SIZE 5 + +static int +nvif_chan906f_sem_release(struct nvif_chan *chan, u64 addr, u32 data) +{ + struct nvif_push *push = &chan->push; + int ret; + + ret = PUSH_WAIT(push, NVIF_CHAN906F_SEM_RELEASE_SIZE); + if (ret) + return ret; + + PUSH_MTHD(push, NV906F, SEMAPHOREA, + NVVAL(NV906F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(addr)), + + SEMAPHOREB, lower_32_bits(addr), + + SEMAPHOREC, data, + + SEMAPHORED, + NVDEF(NV906F, SEMAPHORED, OPERATION, RELEASE) | + NVDEF(NV906F, SEMAPHORED, RELEASE_WFI, DIS) | + NVDEF(NV906F, SEMAPHORED, RELEASE_SIZE, 16BYTE)); + + return 0; +} + +int +nvif_chan906f_gpfifo_post(struct nvif_chan *chan, u32 gpptr, u32 pbptr) +{ + return chan->func->sem.release(chan, chan->sema.addr, + (gpptr << NVIF_CHAN906F_GPPTR_SHIFT) | pbptr); +} + +u32 +nvif_chan906f_gpfifo_read_get(struct nvif_chan *chan) +{ + return nvif_rd32(&chan->sema, 0) >> NVIF_CHAN906F_GPPTR_SHIFT; +} + +u32 +nvif_chan906f_read_get(struct nvif_chan *chan) +{ + return nvif_rd32(&chan->sema, 0) & NVIF_CHAN906F_PBPTR_MASK; +} + +static const struct nvif_chan_func +nvif_chan906f = { + .push.read_get = nvif_chan906f_read_get, + .gpfifo.read_get = nvif_chan906f_gpfifo_read_get, + .gpfifo.push = nvif_chan506f_gpfifo_push, + .gpfifo.kick = nvif_chan506f_gpfifo_kick, + .gpfifo.post = nvif_chan906f_gpfifo_post, + .gpfifo.post_size = NVIF_CHAN906F_SEM_RELEASE_SIZE, + .sem.release = nvif_chan906f_sem_release, +}; + +int +nvif_chan906f_ctor_(const struct nvif_chan_func *func, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr, + struct nvif_chan *chan) +{ + nvif_chan_gpfifo_ctor(func, userd, gpfifo, gpfifo_size, push, push_addr, push_size, chan); + chan->sema.map.ptr = sema; + chan->sema.addr = sema_addr; + return 0; +} + +int +nvif_chan906f_ctor(struct nvif_chan *chan, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr) +{ + return nvif_chan906f_ctor_(&nvif_chan906f, userd, gpfifo, gpfifo_size, + push, push_addr, push_size, sema, sema_addr, chan); +} diff --git a/drivers/gpu/drm/nouveau/nvif/chanc36f.c b/drivers/gpu/drm/nouveau/nvif/chanc36f.c new file mode 100644 index 000000000000..ca02b939c3fd --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvif/chanc36f.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <nvif/chan.h> +#include <nvif/user.h> + +#include <nvif/push906f.h> +#include <nvhw/class/clc36f.h> + +static void +nvif_chanc36f_gpfifo_kick(struct nvif_chan *chan) +{ + struct nvif_user *usermode = chan->usermode; + + nvif_wr32(&chan->userd, 0x8c, chan->gpfifo.cur); + + wmb(); /* ensure CPU writes are flushed to BAR1 */ + nvif_rd32(&chan->userd, 0); /* ensure BAR1 writes are flushed to vidmem */ + + usermode->func->doorbell(usermode, chan->doorbell_token); +} + +#define NVIF_CHANC36F_SEM_RELEASE_SIZE 6 + +static int +nvif_chanc36f_sem_release(struct nvif_chan *chan, u64 addr, u32 data) +{ + struct nvif_push *push = &chan->push; + int ret; + + ret = PUSH_WAIT(push, NVIF_CHANC36F_SEM_RELEASE_SIZE); + if (ret) + return ret; + + PUSH_MTHD(push, NVC36F, SEM_ADDR_LO, lower_32_bits(addr), + + SEM_ADDR_HI, upper_32_bits(addr), + + SEM_PAYLOAD_LO, data); + + PUSH_MTHD(push, NVC36F, SEM_EXECUTE, + NVDEF(NVC36F, SEM_EXECUTE, OPERATION, RELEASE) | + NVDEF(NVC36F, SEM_EXECUTE, RELEASE_WFI, DIS) | + NVDEF(NVC36F, SEM_EXECUTE, PAYLOAD_SIZE, 32BIT) | + NVDEF(NVC36F, SEM_EXECUTE, RELEASE_TIMESTAMP, DIS)); + + return 0; +} + +static const struct nvif_chan_func +nvif_chanc36f = { + .push.read_get = nvif_chan906f_read_get, + .gpfifo.read_get = nvif_chan906f_gpfifo_read_get, + .gpfifo.push = nvif_chan506f_gpfifo_push, + .gpfifo.kick = nvif_chanc36f_gpfifo_kick, + .gpfifo.post = nvif_chan906f_gpfifo_post, + .gpfifo.post_size = NVIF_CHANC36F_SEM_RELEASE_SIZE, + .sem.release = nvif_chanc36f_sem_release, +}; + +int +nvif_chanc36f_ctor(struct nvif_chan *chan, void *userd, void *gpfifo, u32 gpfifo_size, + void *push, u64 push_addr, u32 push_size, void *sema, u64 sema_addr, + struct nvif_user *usermode, u32 doorbell_token) +{ + int ret; + + ret = nvif_chan906f_ctor_(&nvif_chanc36f, userd, gpfifo, gpfifo_size, + push, push_addr, push_size, sema, sema_addr, chan); + if (ret) + return ret; + + chan->usermode = usermode; + chan->doorbell_token = doorbell_token; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvif/disp.c b/drivers/gpu/drm/nouveau/nvif/disp.c index 14da22fa3b5b..fa42146252da 100644 --- a/drivers/gpu/drm/nouveau/nvif/disp.c +++ b/drivers/gpu/drm/nouveau/nvif/disp.c @@ -36,6 +36,7 @@ int nvif_disp_ctor(struct nvif_device *device, const char *name, s32 oclass, struct nvif_disp *disp) { static const struct nvif_mclass disps[] = { + { GB202_DISP, 0 }, { AD102_DISP, 0 }, { GA102_DISP, 0 }, { TU102_DISP, 0 }, diff --git a/drivers/gpu/drm/nouveau/nvif/user.c b/drivers/gpu/drm/nouveau/nvif/user.c index b648a5e036af..53f03fa1c9c2 100644 --- a/drivers/gpu/drm/nouveau/nvif/user.c +++ b/drivers/gpu/drm/nouveau/nvif/user.c @@ -41,9 +41,11 @@ nvif_user_ctor(struct nvif_device *device, const char *name) int version; const struct nvif_user_func *func; } users[] = { - { AMPERE_USERMODE_A, -1, &nvif_userc361 }, - { TURING_USERMODE_A, -1, &nvif_userc361 }, - { VOLTA_USERMODE_A, -1, &nvif_userc361 }, + { BLACKWELL_USERMODE_A, -1, &nvif_userc361 }, + { HOPPER_USERMODE_A, -1, &nvif_userc361 }, + { AMPERE_USERMODE_A, -1, &nvif_userc361 }, + { TURING_USERMODE_A, -1, &nvif_userc361 }, + { VOLTA_USERMODE_A, -1, &nvif_userc361 }, {} }; int cid, ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild index 2e48b0816670..ddcf8782d6b6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild @@ -17,8 +17,6 @@ include $(src)/nvkm/engine/msppp/Kbuild include $(src)/nvkm/engine/msvld/Kbuild include $(src)/nvkm/engine/nvenc/Kbuild include $(src)/nvkm/engine/nvdec/Kbuild -include $(src)/nvkm/engine/nvjpg/Kbuild -include $(src)/nvkm/engine/ofa/Kbuild include $(src)/nvkm/engine/sec/Kbuild include $(src)/nvkm/engine/sec2/Kbuild include $(src)/nvkm/engine/sw/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild index 165d61fc5d6c..9754bac65df7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild @@ -10,5 +10,4 @@ nvkm-y += nvkm/engine/ce/gv100.o nvkm-y += nvkm/engine/ce/tu102.o nvkm-y += nvkm/engine/ce/ga100.o nvkm-y += nvkm/engine/ce/ga102.o - -nvkm-y += nvkm/engine/ce/r535.o +nvkm-y += nvkm/engine/ce/gb202.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c index 9427a592bd16..1c0c60138706 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c @@ -90,7 +90,7 @@ ga100_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) { if (nvkm_gsp_rm(device->gsp)) - return r535_ce_new(&ga100_ce, device, type, inst, pengine); + return -ENODEV; return nvkm_engine_new_(&ga100_ce, device, type, inst, true, pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c index ce56ede7c2e9..9359c5e7aa3a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c @@ -44,7 +44,7 @@ ga102_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) { if (nvkm_gsp_rm(device->gsp)) - return r535_ce_new(&ga102_ce, device, type, inst, pengine); + return -ENODEV; return nvkm_engine_new_(&ga102_ce, device, type, inst, true, pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gb202.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gb202.c new file mode 100644 index 000000000000..37c3c619c71b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gb202.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gb202/dev_ce.h> + +u32 +gb202_ce_grce_mask(struct nvkm_device *device) +{ + u32 data = nvkm_rd32(device, NV_CE_GRCE_MASK); + + return NVVAL_GET(data, NV_CE, GRCE_MASK, VALUE); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h index 806a76a72249..34fd2657134b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h @@ -16,4 +16,6 @@ int ga100_ce_oneinit(struct nvkm_engine *); int ga100_ce_init(struct nvkm_engine *); int ga100_ce_fini(struct nvkm_engine *, bool); int ga100_ce_nonstall(struct nvkm_engine *); + +u32 gb202_ce_grce_mask(struct nvkm_device *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/r535.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/r535.c deleted file mode 100644 index bd0d435dbbd3..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/r535.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <core/object.h> -#include <subdev/gsp.h> -#include <engine/fifo.h> - -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080_notification.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/clc0b5sw.h> - -struct r535_ce_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_ce_obj_dtor(struct nvkm_object *object) -{ - struct r535_ce_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_ce_obj = { - .dtor = r535_ce_obj_dtor, -}; - -static int -r535_ce_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) -{ - struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); - struct r535_ce_obj *obj; - NVC0B5_ALLOCATION_PARAMETERS *args; - - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_ce_obj, oclass, &obj->object); - *pobject = &obj->object; - - args = nvkm_gsp_rm_alloc_get(&chan->rm.object, oclass->handle, oclass->base.oclass, - sizeof(*args), &obj->rm); - if (WARN_ON(IS_ERR(args))) - return PTR_ERR(args); - - args->version = 1; - args->engineType = NV2080_ENGINE_TYPE_COPY0 + oclass->engine->subdev.inst; - - return nvkm_gsp_rm_alloc_wr(&obj->rm, args); -} - -static void * -r535_ce_dtor(struct nvkm_engine *engine) -{ - kfree(engine->func); - return engine; -} - -int -r535_ce_new(const struct nvkm_engine_func *hw, struct nvkm_device *device, - enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) -{ - struct nvkm_engine_func *rm; - int nclass, ret; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_ce_dtor; - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_ce_obj_ctor; - } - - ret = nvkm_engine_new_(rm, device, type, inst, true, pengine); - if (ret) - kfree(rm); - - return ret; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/tu102.c index 7c8647dcb349..67d0545cf902 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/tu102.c @@ -40,7 +40,7 @@ tu102_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) { if (nvkm_gsp_rm(device->gsp)) - return r535_ce_new(&tu102_ce, device, type, inst, pengine); + return -ENODEV; return nvkm_engine_new_(&tu102_ce, device, type, inst, true, pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 9093d89b16f3..3375a59ebf1a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2529,9 +2529,6 @@ nv170_chipset = { .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x000003ff, ga100_ce_new }, .fifo = { 0x00000001, ga100_fifo_new }, - .nvdec = { 0x0000001f, ga100_nvdec_new }, - .nvjpg = { 0x00000001, ga100_nvjpg_new }, - .ofa = { 0x00000001, ga100_ofa_new }, }; static const struct nvkm_device_chip @@ -2561,8 +2558,6 @@ nv172_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ga102_gr_new }, .nvdec = { 0x00000003, ga102_nvdec_new }, - .nvenc = { 0x00000001, ga102_nvenc_new }, - .ofa = { 0x00000001, ga102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2593,8 +2588,6 @@ nv173_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ga102_gr_new }, .nvdec = { 0x00000003, ga102_nvdec_new }, - .nvenc = { 0x00000001, ga102_nvenc_new }, - .ofa = { 0x00000001, ga102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2625,8 +2618,6 @@ nv174_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ga102_gr_new }, .nvdec = { 0x00000003, ga102_nvdec_new }, - .nvenc = { 0x00000001, ga102_nvenc_new }, - .ofa = { 0x00000001, ga102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2657,8 +2648,6 @@ nv176_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ga102_gr_new }, .nvdec = { 0x00000003, ga102_nvdec_new }, - .nvenc = { 0x00000001, ga102_nvenc_new }, - .ofa = { 0x00000001, ga102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2689,12 +2678,26 @@ nv177_chipset = { .fifo = { 0x00000001, ga102_fifo_new }, .gr = { 0x00000001, ga102_gr_new }, .nvdec = { 0x00000003, ga102_nvdec_new }, - .nvenc = { 0x00000001, ga102_nvenc_new }, - .ofa = { 0x00000001, ga102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; static const struct nvkm_device_chip +nv180_chipset = { + .name = "GH100", + .bar = { 0x00000001, tu102_bar_new }, + .fault = { 0x00000001, tu102_fault_new }, + .fb = { 0x00000001, gh100_fb_new }, + .fsp = { 0x00000001, gh100_fsp_new }, + .gsp = { 0x00000001, gh100_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip nv192_chipset = { .name = "AD102", .bar = { 0x00000001, tu102_bar_new }, @@ -2709,14 +2712,9 @@ nv192_chipset = { .timer = { 0x00000001, gk20a_timer_new }, .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x0000001f, ga102_ce_new }, - .disp = { 0x00000001, ad102_disp_new }, + .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, - .gr = { 0x00000001, ad102_gr_new }, - .nvdec = { 0x0000000f, ad102_nvdec_new }, - .nvenc = { 0x00000007, ad102_nvenc_new }, - .nvjpg = { 0x0000000f, ad102_nvjpg_new }, - .ofa = { 0x00000001, ad102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2735,14 +2733,9 @@ nv193_chipset = { .timer = { 0x00000001, gk20a_timer_new }, .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x0000001f, ga102_ce_new }, - .disp = { 0x00000001, ad102_disp_new }, + .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, - .gr = { 0x00000001, ad102_gr_new }, - .nvdec = { 0x0000000f, ad102_nvdec_new }, - .nvenc = { 0x00000007, ad102_nvenc_new }, - .nvjpg = { 0x0000000f, ad102_nvjpg_new }, - .ofa = { 0x00000001, ad102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2761,14 +2754,9 @@ nv194_chipset = { .timer = { 0x00000001, gk20a_timer_new }, .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x0000001f, ga102_ce_new }, - .disp = { 0x00000001, ad102_disp_new }, + .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, - .gr = { 0x00000001, ad102_gr_new }, - .nvdec = { 0x0000000f, ad102_nvdec_new }, - .nvenc = { 0x00000007, ad102_nvenc_new }, - .nvjpg = { 0x0000000f, ad102_nvjpg_new }, - .ofa = { 0x00000001, ad102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2787,14 +2775,9 @@ nv196_chipset = { .timer = { 0x00000001, gk20a_timer_new }, .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x0000001f, ga102_ce_new }, - .disp = { 0x00000001, ad102_disp_new }, + .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, - .gr = { 0x00000001, ad102_gr_new }, - .nvdec = { 0x0000000f, ad102_nvdec_new }, - .nvenc = { 0x00000007, ad102_nvenc_new }, - .nvjpg = { 0x0000000f, ad102_nvjpg_new }, - .ofa = { 0x00000001, ad102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; @@ -2813,17 +2796,122 @@ nv197_chipset = { .timer = { 0x00000001, gk20a_timer_new }, .vfn = { 0x00000001, ga100_vfn_new }, .ce = { 0x0000001f, ga102_ce_new }, - .disp = { 0x00000001, ad102_disp_new }, + .disp = { 0x00000001, ga102_disp_new }, .dma = { 0x00000001, gv100_dma_new }, .fifo = { 0x00000001, ga102_fifo_new }, - .gr = { 0x00000001, ad102_gr_new }, - .nvdec = { 0x0000000f, ad102_nvdec_new }, - .nvenc = { 0x00000007, ad102_nvenc_new }, - .nvjpg = { 0x0000000f, ad102_nvjpg_new }, - .ofa = { 0x00000001, ad102_ofa_new }, .sec2 = { 0x00000001, ga102_sec2_new }, }; +static const struct nvkm_device_chip +nv1a0_chipset = { + .name = "GB100", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb100_fb_new }, + .fsp = { 0x00000001, gb100_fsp_new }, + .gsp = { 0x00000001, gb100_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1a2_chipset = { + .name = "GB102", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb100_fb_new }, + .fsp = { 0x00000001, gb100_fsp_new }, + .gsp = { 0x00000001, gb100_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1b2_chipset = { + .name = "GB202", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb202_fb_new }, + .fsp = { 0x00000001, gb202_fsp_new }, + .gsp = { 0x00000001, gb202_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .disp = { 0x00000001, ga102_disp_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1b3_chipset = { + .name = "GB203", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb202_fb_new }, + .fsp = { 0x00000001, gb202_fsp_new }, + .gsp = { 0x00000001, gb202_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .disp = { 0x00000001, ga102_disp_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1b5_chipset = { + .name = "GB205", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb202_fb_new }, + .fsp = { 0x00000001, gb202_fsp_new }, + .gsp = { 0x00000001, gb202_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .disp = { 0x00000001, ga102_disp_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1b6_chipset = { + .name = "GB206", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb202_fb_new }, + .fsp = { 0x00000001, gb202_fsp_new }, + .gsp = { 0x00000001, gb202_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .disp = { 0x00000001, ga102_disp_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + +static const struct nvkm_device_chip +nv1b7_chipset = { + .name = "GB207", + .bar = { 0x00000001, tu102_bar_new }, + .fb = { 0x00000001, gb202_fb_new }, + .fsp = { 0x00000001, gb202_fsp_new }, + .gsp = { 0x00000001, gb202_gsp_new }, + .imem = { 0x00000001, gh100_instmem_new }, + .mmu = { 0x00000001, gh100_mmu_new }, + .pci = { 0x00000001, gh100_pci_new }, + .timer = { 0x00000001, gk20a_timer_new }, + .vfn = { 0x00000001, ga100_vfn_new }, + .disp = { 0x00000001, ga102_disp_new }, + .fifo = { 0x00000001, ga102_fifo_new }, +}; + struct nvkm_subdev * nvkm_device_subdev(struct nvkm_device *device, int type, int inst) { @@ -3065,8 +3153,8 @@ nvkm_device_ctor(const struct nvkm_device_func *func, device->debug = nvkm_dbgopt(device->dbgopt, "device"); INIT_LIST_HEAD(&device->subdev); - mmio_base = device->func->resource_addr(device, 0); - mmio_size = device->func->resource_size(device, 0); + mmio_base = device->func->resource_addr(device, NVKM_BAR0_PRI); + mmio_size = device->func->resource_size(device, NVKM_BAR0_PRI); device->pri = ioremap(mmio_base, mmio_size); if (device->pri == NULL) { @@ -3139,7 +3227,10 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x140: device->card_type = GV100; break; case 0x160: device->card_type = TU100; break; case 0x170: device->card_type = GA100; break; + case 0x180: device->card_type = GH100; break; case 0x190: device->card_type = AD100; break; + case 0x1a0: device->card_type = GB10x; break; + case 0x1b0: device->card_type = GB20x; break; default: break; } @@ -3242,11 +3333,19 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x174: device->chip = &nv174_chipset; break; case 0x176: device->chip = &nv176_chipset; break; case 0x177: device->chip = &nv177_chipset; break; + case 0x180: device->chip = &nv180_chipset; break; case 0x192: device->chip = &nv192_chipset; break; case 0x193: device->chip = &nv193_chipset; break; case 0x194: device->chip = &nv194_chipset; break; case 0x196: device->chip = &nv196_chipset; break; case 0x197: device->chip = &nv197_chipset; break; + case 0x1a0: device->chip = &nv1a0_chipset; break; + case 0x1a2: device->chip = &nv1a2_chipset; break; + case 0x1b2: device->chip = &nv1b2_chipset; break; + case 0x1b3: device->chip = &nv1b3_chipset; break; + case 0x1b5: device->chip = &nv1b5_chipset; break; + case 0x1b6: device->chip = &nv1b6_chipset; break; + case 0x1b7: device->chip = &nv1b7_chipset; break; default: if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) { switch (device->chipset) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c index 3ff6436007fa..8f0261a0d618 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c @@ -1560,18 +1560,42 @@ nvkm_device_pci(struct nvkm_device *device) return container_of(device, struct nvkm_device_pci, device); } +static int +nvkm_device_pci_resource_idx(struct nvkm_device_pci *pdev, enum nvkm_bar_id bar) +{ + int idx = 0; + + if (bar == NVKM_BAR0_PRI) + return idx; + + idx += (pci_resource_flags(pdev->pdev, idx) & IORESOURCE_MEM_64) ? 2 : 1; + if (bar == NVKM_BAR1_FB) + return idx; + + idx += (pci_resource_flags(pdev->pdev, idx) & IORESOURCE_MEM_64) ? 2 : 1; + if (bar == NVKM_BAR2_INST) + return idx; + + WARN_ON(1); + return -1; +} + static resource_size_t -nvkm_device_pci_resource_addr(struct nvkm_device *device, unsigned bar) +nvkm_device_pci_resource_addr(struct nvkm_device *device, enum nvkm_bar_id bar) { struct nvkm_device_pci *pdev = nvkm_device_pci(device); - return pci_resource_start(pdev->pdev, bar); + int idx = nvkm_device_pci_resource_idx(pdev, bar); + + return idx >= 0 ? pci_resource_start(pdev->pdev, idx) : 0; } static resource_size_t -nvkm_device_pci_resource_size(struct nvkm_device *device, unsigned bar) +nvkm_device_pci_resource_size(struct nvkm_device *device, enum nvkm_bar_id bar) { struct nvkm_device_pci *pdev = nvkm_device_pci(device); - return pci_resource_len(pdev->pdev, bar); + int idx = nvkm_device_pci_resource_idx(pdev, bar); + + return idx >= 0 ? pci_resource_len(pdev->pdev, idx) : 0; } static int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h index e42b18820a95..75ee7506d443 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h @@ -11,6 +11,7 @@ #include <subdev/devinit.h> #include <subdev/fault.h> #include <subdev/fb.h> +#include <subdev/fsp.h> #include <subdev/fuse.h> #include <subdev/gpio.h> #include <subdev/gsp.h> @@ -43,8 +44,6 @@ #include <engine/msvld.h> #include <engine/nvenc.h> #include <engine/nvdec.h> -#include <engine/nvjpg.h> -#include <engine/ofa.h> #include <engine/sec.h> #include <engine/sec2.h> #include <engine/sw.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index 78a83f904bbd..114e50ca1827 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -186,21 +186,31 @@ nvkm_device_tegra(struct nvkm_device *device) } static struct resource * -nvkm_device_tegra_resource(struct nvkm_device *device, unsigned bar) +nvkm_device_tegra_resource(struct nvkm_device *device, enum nvkm_bar_id bar) { struct nvkm_device_tegra *tdev = nvkm_device_tegra(device); - return platform_get_resource(tdev->pdev, IORESOURCE_MEM, bar); + int idx; + + switch (bar) { + case NVKM_BAR0_PRI: idx = 0; break; + case NVKM_BAR1_FB : idx = 1; break; + default: + WARN_ON(1); + return NULL; + } + + return platform_get_resource(tdev->pdev, IORESOURCE_MEM, idx); } static resource_size_t -nvkm_device_tegra_resource_addr(struct nvkm_device *device, unsigned bar) +nvkm_device_tegra_resource_addr(struct nvkm_device *device, enum nvkm_bar_id bar) { struct resource *res = nvkm_device_tegra_resource(device, bar); return res ? res->start : 0; } static resource_size_t -nvkm_device_tegra_resource_size(struct nvkm_device *device, unsigned bar) +nvkm_device_tegra_resource_size(struct nvkm_device *device, enum nvkm_bar_id bar) { struct resource *res = nvkm_device_tegra_resource(device, bar); return res ? resource_size(res) : 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index d7f75b3a43c8..58191b7a0494 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -148,6 +148,9 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size) case TU100: args->v0.family = NV_DEVICE_INFO_V0_TURING; break; case GA100: args->v0.family = NV_DEVICE_INFO_V0_AMPERE; break; case AD100: args->v0.family = NV_DEVICE_INFO_V0_ADA; break; + case GH100: args->v0.family = NV_DEVICE_INFO_V0_HOPPER; break; + case GB10x: args->v0.family = NV_DEVICE_INFO_V0_BLACKWELL; break; + case GB20x: args->v0.family = NV_DEVICE_INFO_V0_BLACKWELL; break; default: args->v0.family = 0; break; @@ -209,8 +212,8 @@ nvkm_udevice_map(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_udevice *udev = nvkm_udevice(object); struct nvkm_device *device = udev->device; *type = NVKM_OBJECT_MAP_IO; - *addr = device->func->resource_addr(device, 0); - *size = device->func->resource_size(device, 0); + *addr = device->func->resource_addr(device, NVKM_BAR0_PRI); + *size = device->func->resource_size(device, NVKM_BAR0_PRI); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index e346e924fee8..e1aecd3fe96c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild @@ -27,9 +27,6 @@ nvkm-y += nvkm/engine/disp/gp102.o nvkm-y += nvkm/engine/disp/gv100.o nvkm-y += nvkm/engine/disp/tu102.o nvkm-y += nvkm/engine/disp/ga102.o -nvkm-y += nvkm/engine/disp/ad102.o - -nvkm-y += nvkm/engine/disp/r535.o nvkm-y += nvkm/engine/disp/udisp.o nvkm-y += nvkm/engine/disp/uconn.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ad102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ad102.c deleted file mode 100644 index 7f300a79aa29..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ad102.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" -#include "chan.h" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_disp_func -ad102_disp = { - .uevent = &gv100_disp_chan_uevent, - .ramht_size = 0x2000, - .root = { 0, 0,AD102_DISP }, - .user = { - {{-1,-1,GV100_DISP_CAPS }, gv100_disp_caps_new }, - {{ 0, 0,GA102_DISP_CURSOR }, nvkm_disp_chan_new, &gv100_disp_curs }, - {{ 0, 0,GA102_DISP_WINDOW_IMM_CHANNEL_DMA}, nvkm_disp_wndw_new, &gv100_disp_wimm }, - {{ 0, 0,AD102_DISP_CORE_CHANNEL_DMA }, nvkm_disp_core_new, &gv100_disp_core }, - {{ 0, 0,GA102_DISP_WINDOW_CHANNEL_DMA }, nvkm_disp_wndw_new, &gv100_disp_wndw }, - {} - }, -}; - -int -ad102_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_disp **pdisp) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_disp_new(&ad102_disp, device, type, inst, pdisp); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c index 4e43ee383c34..9b84e357d354 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c @@ -49,7 +49,7 @@ nvkm_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc, { struct nvkm_disp_chan *chan = nvkm_disp_chan(object); struct nvkm_device *device = chan->disp->engine.subdev.device; - const u64 base = device->func->resource_addr(device, 0); + const u64 base = device->func->resource_addr(device, NVKM_BAR0_PRI); *type = NVKM_OBJECT_MAP_IO; *addr = base + chan->func->user(chan, size); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c index cfa3698d3a2f..614921166fba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c @@ -805,7 +805,7 @@ gv100_disp_caps_map(struct nvkm_object *object, void *argv, u32 argc, struct gv100_disp_caps *caps = gv100_disp_caps(object); struct nvkm_device *device = caps->disp->engine.subdev.device; *type = NVKM_OBJECT_MAP_IO; - *addr = 0x640000 + device->func->resource_addr(device, 0); + *addr = 0x640000 + device->func->resource_addr(device, NVKM_BAR0_PRI); *size = 0x1000; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild index aff92848abfe..376e9c3bcb1a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild @@ -25,8 +25,7 @@ nvkm-y += nvkm/engine/fifo/gv100.o nvkm-y += nvkm/engine/fifo/tu102.o nvkm-y += nvkm/engine/fifo/ga100.o nvkm-y += nvkm/engine/fifo/ga102.o - -nvkm-y += nvkm/engine/fifo/r535.o +nvkm-y += nvkm/engine/fifo/gb202.o nvkm-y += nvkm/engine/fifo/ucgrp.o nvkm-y += nvkm/engine/fifo/uchan.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index 22443fe4a39f..fdffa0391b31 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -303,7 +303,7 @@ nvkm_fifo_oneinit(struct nvkm_engine *engine) } /* Allocate USERD + BAR1 polling area. */ - if (fifo->func->chan.func->userd->bar == 1) { + if (fifo->func->chan.func->userd->bar == NVKM_BAR1_FB) { struct nvkm_vmm *bar1 = nvkm_bar_bar1_vmm(device); ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, fifo->chid->nr * @@ -349,8 +349,6 @@ nvkm_fifo_dtor(struct nvkm_engine *engine) nvkm_chid_unref(&fifo->cgid); nvkm_chid_unref(&fifo->chid); - mutex_destroy(&fifo->userd.mutex); - nvkm_event_fini(&fifo->nonstall.event); mutex_destroy(&fifo->mutex); @@ -391,8 +389,5 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device, spin_lock_init(&fifo->lock); mutex_init(&fifo->mutex); - INIT_LIST_HEAD(&fifo->userd.list); - mutex_init(&fifo->userd.mutex); - return nvkm_engine_ctor(&nvkm_fifo, device, type, inst, true, &fifo->engine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c index 7d4716dcd512..4e09985424b6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c @@ -275,11 +275,7 @@ nvkm_chan_del(struct nvkm_chan **pchan) nvkm_gpuobj_del(&chan->ramfc); if (chan->cgrp) { - if (!chan->func->id_put) - nvkm_chid_put(chan->cgrp->runl->chid, chan->id, &chan->cgrp->lock); - else - chan->func->id_put(chan); - + nvkm_chid_put(chan->cgrp->runl->chid, chan->id, &chan->cgrp->lock); nvkm_cgrp_unref(&chan->cgrp); } @@ -359,14 +355,14 @@ nvkm_chan_new_(const struct nvkm_chan_func *func, struct nvkm_runl *runl, int ru /* Validate arguments against class requirements. */ if ((runq && runq >= runl->func->runqs) || (!func->inst->vmm != !vmm) || - ((func->userd->bar < 0) == !userd) || + (!func->userd->bar == !userd) || (!func->ramfc->ctxdma != !dmaobj) || ((func->ramfc->devm < devm) && devm != BIT(0)) || (!func->ramfc->priv && priv)) { RUNL_DEBUG(runl, "args runq:%d:%d vmm:%d:%p userd:%d:%p " "push:%d:%p devm:%08x:%08x priv:%d:%d", runl->func->runqs, runq, func->inst->vmm, vmm, - func->userd->bar < 0, userd, func->ramfc->ctxdma, dmaobj, + func->userd->bar, userd, func->ramfc->ctxdma, dmaobj, func->ramfc->devm, devm, func->ramfc->priv, priv); return -EINVAL; } @@ -441,30 +437,26 @@ nvkm_chan_new_(const struct nvkm_chan_func *func, struct nvkm_runl *runl, int ru } /* Allocate channel ID. */ - if (!chan->func->id_get) { - chan->id = nvkm_chid_get(runl->chid, chan); - if (chan->id >= 0) { - if (func->userd->bar < 0) { - if (ouserd + chan->func->userd->size >= - nvkm_memory_size(userd)) { - RUNL_DEBUG(runl, "ouserd %llx", ouserd); - return -EINVAL; - } - - ret = nvkm_memory_kmap(userd, &chan->userd.mem); - if (ret) { - RUNL_DEBUG(runl, "userd %d", ret); - return ret; - } - - chan->userd.base = ouserd; - } else { - chan->userd.mem = nvkm_memory_ref(fifo->userd.mem); - chan->userd.base = chan->id * chan->func->userd->size; + chan->id = nvkm_chid_get(runl->chid, chan); + if (chan->id >= 0) { + if (!func->userd->bar) { + if (ouserd + chan->func->userd->size >= + nvkm_memory_size(userd)) { + RUNL_DEBUG(runl, "ouserd %llx", ouserd); + return -EINVAL; + } + + ret = nvkm_memory_kmap(userd, &chan->userd.mem); + if (ret) { + RUNL_DEBUG(runl, "userd %d", ret); + return ret; } + + chan->userd.base = ouserd; + } else { + chan->userd.mem = nvkm_memory_ref(fifo->userd.mem); + chan->userd.base = chan->id * chan->func->userd->size; } - } else { - chan->id = chan->func->id_get(chan, userd, ouserd); } if (chan->id < 0) { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h index 013682a709d5..445db5dfd1e4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h @@ -17,9 +17,6 @@ struct nvkm_cctx { }; struct nvkm_chan_func { - int (*id_get)(struct nvkm_chan *, struct nvkm_memory *userd, u64 ouserd); - void (*id_put)(struct nvkm_chan *); - const struct nvkm_chan_func_inst { u32 size; bool zero; @@ -27,7 +24,7 @@ struct nvkm_chan_func { } *inst; const struct nvkm_chan_func_userd { - int bar; + enum nvkm_bar_id bar; u32 base; u32 size; void (*clear)(struct nvkm_chan *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gb202.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gb202.c new file mode 100644 index 000000000000..b469e8afeb0b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gb202.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" +#include "cgrp.h" +#include "chan.h" +#include "runl.h" + +u32 +gb202_chan_doorbell_handle(struct nvkm_chan *chan) +{ + return BIT(30) | (chan->cgrp->runl->id << 16) | chan->id; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index 6c94451d0faa..e4a4fad2eafc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c @@ -133,7 +133,7 @@ gf100_chan_userd_clear(struct nvkm_chan *chan) static const struct nvkm_chan_func_userd gf100_chan_userd = { - .bar = 1, + .bar = NVKM_BAR1_FB, .size = 0x1000, .clear = gf100_chan_userd_clear, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index d8a4d773a58c..5655eda52a7b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -113,7 +113,7 @@ gk104_chan_ramfc = { const struct nvkm_chan_func_userd gk104_chan_userd = { - .bar = 1, + .bar = NVKM_BAR1_FB, .size = 0x200, .clear = gf100_chan_userd_clear, }; @@ -745,7 +745,7 @@ gk104_fifo_init(struct nvkm_fifo *fifo) { struct nvkm_device *device = fifo->engine.subdev.device; - if (fifo->func->chan.func->userd->bar == 1) + if (fifo->func->chan.func->userd->bar == NVKM_BAR1_FB) nvkm_wr32(device, 0x002254, 0x10000000 | fifo->userd.bar1->addr >> 12); nvkm_wr32(device, 0x002100, 0xffffffff); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c index 33066c8cdc64..d7f046c03cfd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c @@ -70,7 +70,6 @@ gv100_chan_ramfc = { const struct nvkm_chan_func_userd gv100_chan_userd = { - .bar = -1, .size = 0x200, .clear = gf100_chan_userd_clear, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c index 674faf002b20..c4b8e567d86f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c @@ -154,7 +154,7 @@ nv04_chan_ramfc = { const struct nvkm_chan_func_userd nv04_chan_userd = { - .bar = 0, + .bar = NVKM_BAR0_PRI, .base = 0x800000, .size = 0x010000, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c index e50a94b6d7f8..084ca5561ee1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c @@ -93,7 +93,7 @@ nv40_chan_ramfc = { static const struct nvkm_chan_func_userd nv40_chan_userd = { - .bar = 0, + .bar = NVKM_BAR0_PRI, .base = 0xc00000, .size = 0x001000, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c index 954b5f3a7d57..7bf77661157d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c @@ -124,7 +124,7 @@ nv50_chan_ramfc = { const struct nvkm_chan_func_userd nv50_chan_userd = { - .bar = 0, + .bar = NVKM_BAR0_PRI, .base = 0xc00000, .size = 0x002000, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index a0f3277605a5..5e81ae195329 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -6,6 +6,7 @@ #include <core/enum.h> struct nvkm_cctx; struct nvkm_cgrp; +struct nvkm_chan; struct nvkm_engn; struct nvkm_memory; struct nvkm_runl; @@ -195,6 +196,7 @@ extern const struct nvkm_chan_func_ramfc gv100_chan_ramfc; void tu102_fifo_intr_ctxsw_timeout_info(struct nvkm_engn *, u32 info); extern const struct nvkm_fifo_func_mmu_fault tu102_fifo_mmu_fault; +u32 tu102_chan_doorbell_handle(struct nvkm_chan *); int ga100_fifo_runl_ctor(struct nvkm_fifo *); int ga100_fifo_nonstall_ctor(struct nvkm_fifo *); @@ -206,6 +208,8 @@ extern const struct nvkm_engn_func ga100_engn_ce; extern const struct nvkm_cgrp_func ga100_cgrp; extern const struct nvkm_chan_func ga100_chan; +u32 gb202_chan_doorbell_handle(struct nvkm_chan *); + int nvkm_uchan_new(struct nvkm_fifo *, struct nvkm_cgrp *, const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **); int nvkm_ucgrp_new(struct nvkm_fifo *, const struct nvkm_oclass *, void *argv, u32 argc, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c index 1d39a6840a40..c5a03298e88c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c @@ -31,7 +31,7 @@ #include <nvif/class.h> -static u32 +u32 tu102_chan_doorbell_handle(struct nvkm_chan *chan) { return (chan->cgrp->runl->id << 16) | chan->id; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c index 9e56bcc166ed..52420a1edca5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c @@ -258,7 +258,7 @@ nvkm_uchan_map(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_chan *chan = nvkm_uchan(object)->chan; struct nvkm_device *device = chan->cgrp->runl->fifo->engine.subdev.device; - if (chan->func->userd->bar < 0) + if (!chan->func->userd->bar) return -ENOSYS; *type = NVKM_OBJECT_MAP_IO; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild index 1555f8c40b4f..b5418f05ccd8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild @@ -41,9 +41,6 @@ nvkm-y += nvkm/engine/gr/gp10b.o nvkm-y += nvkm/engine/gr/gv100.o nvkm-y += nvkm/engine/gr/tu102.o nvkm-y += nvkm/engine/gr/ga102.o -nvkm-y += nvkm/engine/gr/ad102.o - -nvkm-y += nvkm/engine/gr/r535.o nvkm-y += nvkm/engine/gr/ctxnv40.o nvkm-y += nvkm/engine/gr/ctxnv50.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c index d285c597aff9..2b51f1d0c281 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c @@ -352,7 +352,7 @@ int ga102_gr_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gr **pgr) { if (nvkm_gsp_rm(device->gsp)) - return r535_gr_new(&ga102_gr, device, type, inst, pgr); + return -ENODEV; return gf100_gr_new_(ga102_gr_fwif, device, type, inst, pgr); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index b0e0c9305034..54f686ba39ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -445,6 +445,4 @@ void gp108_gr_acr_bld_patch(struct nvkm_acr *, u32, s64); int gf100_gr_new_(const struct gf100_gr_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gr **); -int r535_gr_new(const struct gf100_gr_func *, struct nvkm_device *, enum nvkm_subdev_type, int, - struct nvkm_gr **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c index 02a8c62a0a32..13407fafe947 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c @@ -297,7 +297,7 @@ nv20_gr_init(struct nvkm_gr *base) nvkm_wr32(device, NV10_PGRAPH_SURFACE, tmp); /* begin RAM config */ - vramsz = device->func->resource_size(device, 1) - 1; + vramsz = device->func->resource_size(device, NVKM_BAR1_FB) - 1; nvkm_wr32(device, 0x4009A4, nvkm_rd32(device, 0x100200)); nvkm_wr32(device, 0x4009A8, nvkm_rd32(device, 0x100204)); nvkm_wr32(device, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c index a5e1f02791b4..b609b0150ba1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c @@ -386,7 +386,7 @@ nv40_gr_init(struct nvkm_gr *base) } /* begin RAM config */ - vramsz = device->func->resource_size(device, 1) - 1; + vramsz = device->func->resource_size(device, NVKM_BAR1_FB) - 1; switch (device->chipset) { case 0x40: nvkm_wr32(device, 0x4009A4, nvkm_rd32(device, 0x100200)); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/r535.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/r535.c deleted file mode 100644 index f4bed3eb1ec2..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/r535.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "gf100.h" - -#include <core/memory.h> -#include <subdev/gsp.h> -#include <subdev/mmu/vmm.h> -#include <engine/fifo/priv.h> - -#include <nvif/if900d.h> - -#include <nvhw/drf.h> - -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/alloc/alloc_channel.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080fifo.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080internal.h> -#include <nvrm/535.113.01/nvidia/generated/g_kernel_channel_nvoc.h> - -#define r535_gr(p) container_of((p), struct r535_gr, base) - -#define R515_GR_MAX_CTXBUFS 9 - -struct r535_gr { - struct nvkm_gr base; - - struct { - u16 bufferId; - u32 size; - u8 page; - u8 align; - bool global; - bool init; - bool ro; - } ctxbuf[R515_GR_MAX_CTXBUFS]; - int ctxbuf_nr; - - struct nvkm_memory *ctxbuf_mem[R515_GR_MAX_CTXBUFS]; -}; - -struct r535_gr_chan { - struct nvkm_object object; - struct r535_gr *gr; - - struct nvkm_vmm *vmm; - struct nvkm_chan *chan; - - struct nvkm_memory *mem[R515_GR_MAX_CTXBUFS]; - struct nvkm_vma *vma[R515_GR_MAX_CTXBUFS]; -}; - -struct r535_gr_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_gr_obj_dtor(struct nvkm_object *object) -{ - struct r535_gr_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_gr_obj = { - .dtor = r535_gr_obj_dtor, -}; - -static int -r535_gr_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) -{ - struct r535_gr_chan *chan = container_of(oclass->parent, typeof(*chan), object); - struct r535_gr_obj *obj; - - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_gr_obj, oclass, &obj->object); - *pobject = &obj->object; - - return nvkm_gsp_rm_alloc(&chan->chan->rm.object, oclass->handle, oclass->base.oclass, 0, - &obj->rm); -} - -static void * -r535_gr_chan_dtor(struct nvkm_object *object) -{ - struct r535_gr_chan *grc = container_of(object, typeof(*grc), object); - struct r535_gr *gr = grc->gr; - - for (int i = 0; i < gr->ctxbuf_nr; i++) { - nvkm_vmm_put(grc->vmm, &grc->vma[i]); - nvkm_memory_unref(&grc->mem[i]); - } - - nvkm_vmm_unref(&grc->vmm); - return grc; -} - -static const struct nvkm_object_func -r535_gr_chan = { - .dtor = r535_gr_chan_dtor, -}; - -static int -r535_gr_promote_ctx(struct r535_gr *gr, bool golden, struct nvkm_vmm *vmm, - struct nvkm_memory **pmem, struct nvkm_vma **pvma, - struct nvkm_gsp_object *chan) -{ - struct nvkm_subdev *subdev = &gr->base.engine.subdev; - struct nvkm_device *device = subdev->device; - NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS *ctrl; - - ctrl = nvkm_gsp_rm_ctrl_get(&vmm->rm.device.subdevice, - NV2080_CTRL_CMD_GPU_PROMOTE_CTX, sizeof(*ctrl)); - if (WARN_ON(IS_ERR(ctrl))) - return PTR_ERR(ctrl); - - ctrl->engineType = 1; - ctrl->hChanClient = vmm->rm.client.object.handle; - ctrl->hObject = chan->handle; - - for (int i = 0; i < gr->ctxbuf_nr; i++) { - NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ENTRY *entry = - &ctrl->promoteEntry[ctrl->entryCount]; - const bool alloc = golden || !gr->ctxbuf[i].global; - int ret; - - entry->bufferId = gr->ctxbuf[i].bufferId; - entry->bInitialize = gr->ctxbuf[i].init && alloc; - - if (alloc) { - ret = nvkm_memory_new(device, gr->ctxbuf[i].init ? - NVKM_MEM_TARGET_INST : NVKM_MEM_TARGET_INST_SR_LOST, - gr->ctxbuf[i].size, 1 << gr->ctxbuf[i].page, - gr->ctxbuf[i].init, &pmem[i]); - if (WARN_ON(ret)) - return ret; - - if (gr->ctxbuf[i].bufferId == - NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PRIV_ACCESS_MAP) - entry->bNonmapped = 1; - } else { - if (gr->ctxbuf[i].bufferId == - NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_UNRESTRICTED_PRIV_ACCESS_MAP) - continue; - - pmem[i] = nvkm_memory_ref(gr->ctxbuf_mem[i]); - } - - if (!entry->bNonmapped) { - struct gf100_vmm_map_v0 args = { - .priv = 1, - .ro = gr->ctxbuf[i].ro, - }; - - mutex_lock(&vmm->mutex.vmm); - ret = nvkm_vmm_get_locked(vmm, false, true, false, 0, gr->ctxbuf[i].align, - nvkm_memory_size(pmem[i]), &pvma[i]); - mutex_unlock(&vmm->mutex.vmm); - if (ret) - return ret; - - ret = nvkm_memory_map(pmem[i], 0, vmm, pvma[i], &args, sizeof(args)); - if (ret) - return ret; - - entry->gpuVirtAddr = pvma[i]->addr; - } - - if (entry->bInitialize) { - entry->gpuPhysAddr = nvkm_memory_addr(pmem[i]); - entry->size = gr->ctxbuf[i].size; - entry->physAttr = 4; - } - - nvkm_debug(subdev, - "promote %02d: pa %016llx/%08x sz %016llx va %016llx init:%d nm:%d\n", - entry->bufferId, entry->gpuPhysAddr, entry->physAttr, entry->size, - entry->gpuVirtAddr, entry->bInitialize, entry->bNonmapped); - - ctrl->entryCount++; - } - - return nvkm_gsp_rm_ctrl_wr(&vmm->rm.device.subdevice, ctrl); -} - -static int -r535_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *chan, const struct nvkm_oclass *oclass, - struct nvkm_object **pobject) -{ - struct r535_gr *gr = r535_gr(base); - struct r535_gr_chan *grc; - int ret; - - if (!(grc = kzalloc(sizeof(*grc), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_gr_chan, oclass, &grc->object); - grc->gr = gr; - grc->vmm = nvkm_vmm_ref(chan->vmm); - grc->chan = chan; - *pobject = &grc->object; - - ret = r535_gr_promote_ctx(gr, false, grc->vmm, grc->mem, grc->vma, &chan->rm.object); - if (ret) - return ret; - - return 0; -} - -static u64 -r535_gr_units(struct nvkm_gr *gr) -{ - struct nvkm_gsp *gsp = gr->engine.subdev.device->gsp; - - return (gsp->gr.tpcs << 8) | gsp->gr.gpcs; -} - -static int -r535_gr_oneinit(struct nvkm_gr *base) -{ - NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS *info; - struct r535_gr *gr = container_of(base, typeof(*gr), base); - struct nvkm_subdev *subdev = &gr->base.engine.subdev; - struct nvkm_device *device = subdev->device; - struct nvkm_gsp *gsp = device->gsp; - struct nvkm_mmu *mmu = device->mmu; - struct { - struct nvkm_memory *inst; - struct nvkm_vmm *vmm; - struct nvkm_gsp_object chan; - struct nvkm_vma *vma[R515_GR_MAX_CTXBUFS]; - } golden = {}; - int ret; - - /* Allocate a channel to use for golden context init. */ - ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x12000, 0, true, &golden.inst); - if (ret) - goto done; - - ret = nvkm_vmm_new(device, 0x1000, 0, NULL, 0, NULL, "grGoldenVmm", &golden.vmm); - if (ret) - goto done; - - ret = mmu->func->promote_vmm(golden.vmm); - if (ret) - goto done; - - { - NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS *args; - - args = nvkm_gsp_rm_alloc_get(&golden.vmm->rm.device.object, 0xf1f00000, - device->fifo->func->chan.user.oclass, - sizeof(*args), &golden.chan); - if (IS_ERR(args)) { - ret = PTR_ERR(args); - goto done; - } - - args->gpFifoOffset = 0; - args->gpFifoEntries = 0x1000 / 8; - args->flags = - NVDEF(NVOS04, FLAGS, CHANNEL_TYPE, PHYSICAL) | - NVDEF(NVOS04, FLAGS, VPR, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_SKIP_MAP_REFCOUNTING, FALSE) | - NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, 0) | - NVDEF(NVOS04, FLAGS, PRIVILEGED_CHANNEL, TRUE) | - NVDEF(NVOS04, FLAGS, DELAY_CHANNEL_SCHEDULING, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_DENY_PHYSICAL_MODE_CE, FALSE) | - NVVAL(NVOS04, FLAGS, CHANNEL_USERD_INDEX_VALUE, 0) | - NVDEF(NVOS04, FLAGS, CHANNEL_USERD_INDEX_FIXED, FALSE) | - NVVAL(NVOS04, FLAGS, CHANNEL_USERD_INDEX_PAGE_VALUE, 0) | - NVDEF(NVOS04, FLAGS, CHANNEL_USERD_INDEX_PAGE_FIXED, TRUE) | - NVDEF(NVOS04, FLAGS, CHANNEL_DENY_AUTH_LEVEL_PRIV, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_SKIP_SCRUBBER, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_CLIENT_MAP_FIFO, FALSE) | - NVDEF(NVOS04, FLAGS, SET_EVICT_LAST_CE_PREFETCH_CHANNEL, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_VGPU_PLUGIN_CONTEXT, FALSE) | - NVDEF(NVOS04, FLAGS, CHANNEL_PBDMA_ACQUIRE_TIMEOUT, FALSE) | - NVDEF(NVOS04, FLAGS, GROUP_CHANNEL_THREAD, DEFAULT) | - NVDEF(NVOS04, FLAGS, MAP_CHANNEL, FALSE) | - NVDEF(NVOS04, FLAGS, SKIP_CTXBUFFER_ALLOC, FALSE); - args->hVASpace = golden.vmm->rm.object.handle; - args->engineType = 1; - args->instanceMem.base = nvkm_memory_addr(golden.inst); - args->instanceMem.size = 0x1000; - args->instanceMem.addressSpace = 2; - args->instanceMem.cacheAttrib = 1; - args->ramfcMem.base = nvkm_memory_addr(golden.inst); - args->ramfcMem.size = 0x200; - args->ramfcMem.addressSpace = 2; - args->ramfcMem.cacheAttrib = 1; - args->userdMem.base = nvkm_memory_addr(golden.inst) + 0x1000; - args->userdMem.size = 0x200; - args->userdMem.addressSpace = 2; - args->userdMem.cacheAttrib = 1; - args->mthdbufMem.base = nvkm_memory_addr(golden.inst) + 0x2000; - args->mthdbufMem.size = 0x5000; - args->mthdbufMem.addressSpace = 2; - args->mthdbufMem.cacheAttrib = 1; - args->internalFlags = - NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, PRIVILEGE, ADMIN) | - NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, ERROR_NOTIFIER_TYPE, NONE) | - NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, ECC_ERROR_NOTIFIER_TYPE, NONE); - - ret = nvkm_gsp_rm_alloc_wr(&golden.chan, args); - if (ret) - goto done; - } - - /* Fetch context buffer info from RM and allocate each of them here to use - * during golden context init (or later as a global context buffer). - * - * Also build the information that'll be used to create channel contexts. - */ - info = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, - NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO, - sizeof(*info)); - if (WARN_ON(IS_ERR(info))) { - ret = PTR_ERR(info); - goto done; - } - - for (int i = 0; i < ARRAY_SIZE(info->engineContextBuffersInfo[0].engine); i++) { - static const struct { - u32 id0; /* NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID */ - u32 id1; /* NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID */ - bool global; - bool init; - bool ro; - } map[] = { -#define _A(n,N,G,I,R) { .id0 = NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_##n, \ - .id1 = NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_##N, \ - .global = (G), .init = (I), .ro = (R) } -#define _B(N,G,I,R) _A(GRAPHICS_##N, N, (G), (I), (R)) - /* global init ro */ - _A( GRAPHICS, MAIN, false, true, false), - _B( PATCH, false, true, false), - _A( GRAPHICS_BUNDLE_CB, BUFFER_BUNDLE_CB, true, false, false), - _B( PAGEPOOL, true, false, false), - _B( ATTRIBUTE_CB, true, false, false), - _B( RTV_CB_GLOBAL, true, false, false), - _B( FECS_EVENT, true, true, false), - _B( PRIV_ACCESS_MAP, true, true, true), -#undef _B -#undef _A - }; - u32 size = info->engineContextBuffersInfo[0].engine[i].size; - u8 align, page; - int id; - - for (id = 0; id < ARRAY_SIZE(map); id++) { - if (map[id].id0 == i) - break; - } - - nvkm_debug(subdev, "%02x: size:0x%08x %s\n", i, - size, (id < ARRAY_SIZE(map)) ? "*" : ""); - if (id >= ARRAY_SIZE(map)) - continue; - - if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_MAIN) - size = ALIGN(size, 0x1000) + 64 * 0x1000; /* per-subctx headers */ - - if (size >= 1 << 21) page = 21; - else if (size >= 1 << 16) page = 16; - else page = 12; - - if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_ATTRIBUTE_CB) - align = order_base_2(size); - else - align = page; - - if (WARN_ON(gr->ctxbuf_nr == ARRAY_SIZE(gr->ctxbuf))) - continue; - - gr->ctxbuf[gr->ctxbuf_nr].bufferId = map[id].id1; - gr->ctxbuf[gr->ctxbuf_nr].size = size; - gr->ctxbuf[gr->ctxbuf_nr].page = page; - gr->ctxbuf[gr->ctxbuf_nr].align = align; - gr->ctxbuf[gr->ctxbuf_nr].global = map[id].global; - gr->ctxbuf[gr->ctxbuf_nr].init = map[id].init; - gr->ctxbuf[gr->ctxbuf_nr].ro = map[id].ro; - gr->ctxbuf_nr++; - - if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PRIV_ACCESS_MAP) { - if (WARN_ON(gr->ctxbuf_nr == ARRAY_SIZE(gr->ctxbuf))) - continue; - - gr->ctxbuf[gr->ctxbuf_nr] = gr->ctxbuf[gr->ctxbuf_nr - 1]; - gr->ctxbuf[gr->ctxbuf_nr].bufferId = - NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_UNRESTRICTED_PRIV_ACCESS_MAP; - gr->ctxbuf_nr++; - } - } - - nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, info); - - /* Promote golden context to RM. */ - ret = r535_gr_promote_ctx(gr, true, golden.vmm, gr->ctxbuf_mem, golden.vma, &golden.chan); - if (ret) - goto done; - - /* Allocate 3D class on channel to trigger golden context init in RM. */ - { - int i; - - for (i = 0; gr->base.func->sclass[i].ctor; i++) { - if ((gr->base.func->sclass[i].oclass & 0xff) == 0x97) { - struct nvkm_gsp_object threed; - - ret = nvkm_gsp_rm_alloc(&golden.chan, 0x97000000, - gr->base.func->sclass[i].oclass, 0, - &threed); - if (ret) - goto done; - - nvkm_gsp_rm_free(&threed); - break; - } - } - - if (WARN_ON(!gr->base.func->sclass[i].ctor)) { - ret = -EINVAL; - goto done; - } - } - -done: - nvkm_gsp_rm_free(&golden.chan); - for (int i = gr->ctxbuf_nr - 1; i >= 0; i--) - nvkm_vmm_put(golden.vmm, &golden.vma[i]); - nvkm_vmm_unref(&golden.vmm); - nvkm_memory_unref(&golden.inst); - return ret; - -} - -static void * -r535_gr_dtor(struct nvkm_gr *base) -{ - struct r535_gr *gr = r535_gr(base); - - while (gr->ctxbuf_nr) - nvkm_memory_unref(&gr->ctxbuf_mem[--gr->ctxbuf_nr]); - - kfree(gr->base.func); - return gr; -} - -int -r535_gr_new(const struct gf100_gr_func *hw, - struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gr **pgr) -{ - struct nvkm_gr_func *rm; - struct r535_gr *gr; - int nclass; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_gr_dtor; - rm->oneinit = r535_gr_oneinit; - rm->units = r535_gr_units; - rm->chan_new = r535_gr_chan_new; - - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_gr_obj_ctor; - } - - if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL))) { - kfree(rm); - return -ENOMEM; - } - - *pgr = &gr->base; - - return nvkm_gr_ctor(rm, device, type, inst, true, &gr->base); -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c index b7a458e9040a..bda8054c6b59 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c @@ -219,7 +219,7 @@ int tu102_gr_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gr **pgr) { if (nvkm_gsp_rm(device->gsp)) - return r535_gr_new(&tu102_gr, device, type, inst, pgr); + return -ENODEV; return gf100_gr_new_(tu102_gr_fwif, device, type, inst, pgr); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild index 2b0e923cb755..37b0cdc760c7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/Kbuild @@ -2,8 +2,4 @@ nvkm-y += nvkm/engine/nvdec/base.o nvkm-y += nvkm/engine/nvdec/gm107.o nvkm-y += nvkm/engine/nvdec/tu102.o -nvkm-y += nvkm/engine/nvdec/ga100.o nvkm-y += nvkm/engine/nvdec/ga102.o -nvkm-y += nvkm/engine/nvdec/ad102.o - -nvkm-y += nvkm/engine/nvdec/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga102.c index 022a9c824304..eea6368adae2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga102.c @@ -23,16 +23,6 @@ #include <subdev/gsp.h> -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga102_nvdec_gsp = { - .sclass = { - { -1, -1, NVC7B0_VIDEO_DECODER }, - {} - } -}; - static const struct nvkm_falcon_func ga102_nvdec_flcn = { .disable = gm200_flcn_disable, @@ -67,7 +57,7 @@ ga102_nvdec_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst struct nvkm_nvdec **pnvdec) { if (nvkm_gsp_rm(device->gsp)) - return r535_nvdec_new(&ga102_nvdec_gsp, device, type, inst, pnvdec); + return -ENODEV; return nvkm_nvdec_new_(ga102_nvdec_fwif, device, type, inst, 0x848000, pnvdec); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/priv.h index f506ae83bfd7..f8d43e913093 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/priv.h @@ -20,7 +20,4 @@ extern const struct nvkm_nvdec_fwif gm107_nvdec_fwif[]; int nvkm_nvdec_new_(const struct nvkm_nvdec_fwif *fwif, struct nvkm_device *, enum nvkm_subdev_type, int, u32 addr, struct nvkm_nvdec **); - -int r535_nvdec_new(const struct nvkm_engine_func *, struct nvkm_device *, - enum nvkm_subdev_type, int, struct nvkm_nvdec **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/r535.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/r535.c deleted file mode 100644 index 75a24f3e6617..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/r535.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <core/object.h> -#include <subdev/gsp.h> -#include <engine/fifo.h> - -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h> - -struct r535_nvdec_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_nvdec_obj_dtor(struct nvkm_object *object) -{ - struct r535_nvdec_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_nvdec_obj = { - .dtor = r535_nvdec_obj_dtor, -}; - -static int -r535_nvdec_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) -{ - struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); - struct r535_nvdec_obj *obj; - NV_BSP_ALLOCATION_PARAMETERS *args; - - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_nvdec_obj, oclass, &obj->object); - *pobject = &obj->object; - - args = nvkm_gsp_rm_alloc_get(&chan->rm.object, oclass->handle, oclass->base.oclass, - sizeof(*args), &obj->rm); - if (WARN_ON(IS_ERR(args))) - return PTR_ERR(args); - - args->size = sizeof(*args); - args->engineInstance = oclass->engine->subdev.inst; - - return nvkm_gsp_rm_alloc_wr(&obj->rm, args); -} - -static void * -r535_nvdec_dtor(struct nvkm_engine *engine) -{ - struct nvkm_nvdec *nvdec = nvkm_nvdec(engine); - - kfree(nvdec->engine.func); - return nvdec; -} - -int -r535_nvdec_new(const struct nvkm_engine_func *hw, struct nvkm_device *device, - enum nvkm_subdev_type type, int inst, struct nvkm_nvdec **pnvdec) -{ - struct nvkm_engine_func *rm; - int nclass; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_nvdec_dtor; - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_nvdec_obj_ctor; - } - - if (!(*pnvdec = kzalloc(sizeof(**pnvdec), GFP_KERNEL))) { - kfree(rm); - return -ENOMEM; - } - - return nvkm_engine_ctor(rm, device, type, inst, true, &(*pnvdec)->engine); -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/tu102.c index 808c8e010b9e..fe95b6e22f21 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/tu102.c @@ -23,22 +23,12 @@ #include <subdev/gsp.h> -#include <nvif/class.h> - -static const struct nvkm_engine_func -tu102_nvdec = { - .sclass = { - { -1, -1, NVC4B0_VIDEO_DECODER }, - {} - } -}; - int tu102_nvdec_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_nvdec **pnvdec) { if (nvkm_gsp_rm(device->gsp)) - return r535_nvdec_new(&tu102_nvdec, device, type, inst, pnvdec); + return -ENODEV; return nvkm_nvdec_new_(gm107_nvdec_fwif, device, type, inst, 0, pnvdec); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild index 2c1495b730f3..6dcb20d1d156 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/Kbuild @@ -2,7 +2,3 @@ nvkm-y += nvkm/engine/nvenc/base.o nvkm-y += nvkm/engine/nvenc/gm107.o nvkm-y += nvkm/engine/nvenc/tu102.o -nvkm-y += nvkm/engine/nvenc/ga102.o -nvkm-y += nvkm/engine/nvenc/ad102.o - -nvkm-y += nvkm/engine/nvenc/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ga102.c deleted file mode 100644 index 6463ab8e5871..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ga102.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga102_nvenc = { - .sclass = { - { -1, -1, NVC7B7_VIDEO_ENCODER }, - {} - } -}; - -int -ga102_nvenc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_nvenc **pnvenc) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvenc_new(&ga102_nvenc, device, type, inst, pnvenc); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/priv.h index 7917affc6505..b097e3f2867b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/priv.h @@ -18,7 +18,4 @@ extern const struct nvkm_nvenc_fwif gm107_nvenc_fwif[]; int nvkm_nvenc_new_(const struct nvkm_nvenc_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_nvenc **pnvenc); - -int r535_nvenc_new(const struct nvkm_engine_func *, struct nvkm_device *, - enum nvkm_subdev_type, int, struct nvkm_nvenc **); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/r535.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/r535.c deleted file mode 100644 index c8a2a9196ce5..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/r535.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <core/object.h> -#include <subdev/gsp.h> -#include <engine/fifo.h> - -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h> - -struct r535_nvenc_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_nvenc_obj_dtor(struct nvkm_object *object) -{ - struct r535_nvenc_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_nvenc_obj = { - .dtor = r535_nvenc_obj_dtor, -}; - -static int -r535_nvenc_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) -{ - struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); - struct r535_nvenc_obj *obj; - NV_MSENC_ALLOCATION_PARAMETERS *args; - - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_nvenc_obj, oclass, &obj->object); - *pobject = &obj->object; - - args = nvkm_gsp_rm_alloc_get(&chan->rm.object, oclass->handle, oclass->base.oclass, - sizeof(*args), &obj->rm); - if (WARN_ON(IS_ERR(args))) - return PTR_ERR(args); - - args->size = sizeof(*args); - args->engineInstance = oclass->engine->subdev.inst; - - return nvkm_gsp_rm_alloc_wr(&obj->rm, args); -} - -static void * -r535_nvenc_dtor(struct nvkm_engine *engine) -{ - struct nvkm_nvenc *nvenc = nvkm_nvenc(engine); - - kfree(nvenc->engine.func); - return nvenc; -} - -int -r535_nvenc_new(const struct nvkm_engine_func *hw, struct nvkm_device *device, - enum nvkm_subdev_type type, int inst, struct nvkm_nvenc **pnvenc) -{ - struct nvkm_engine_func *rm; - int nclass; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_nvenc_dtor; - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_nvenc_obj_ctor; - } - - if (!(*pnvenc = kzalloc(sizeof(**pnvenc), GFP_KERNEL))) { - kfree(rm); - return -ENOMEM; - } - - return nvkm_engine_ctor(rm, device, type, inst, true, &(*pnvenc)->engine); -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/tu102.c index 933864423bb3..8a436b398749 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/tu102.c @@ -23,22 +23,12 @@ #include <subdev/gsp.h> -#include <nvif/class.h> - -static const struct nvkm_engine_func -tu102_nvenc = { - .sclass = { - { -1, -1, NVC4B7_VIDEO_ENCODER }, - {} - } -}; - int tu102_nvenc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_nvenc **pnvenc) { if (nvkm_gsp_rm(device->gsp)) - return r535_nvenc_new(&tu102_nvenc, device, type, inst, pnvenc); + return -ENODEV; return nvkm_nvenc_new_(gm107_nvenc_fwif, device, type, inst, pnvenc); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild deleted file mode 100644 index 1408f664add6..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/Kbuild +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: MIT -nvkm-y += nvkm/engine/nvjpg/ga100.o -nvkm-y += nvkm/engine/nvjpg/ad102.o - -nvkm-y += nvkm/engine/nvjpg/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ad102.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ad102.c deleted file mode 100644 index 62705dc6494c..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ad102.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ad102_nvjpg = { - .sclass = { - { -1, -1, NVC9D1_VIDEO_NVJPG }, - {} - } -}; - -int -ad102_nvjpg_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_engine **pengine) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvjpg_new(&ad102_nvjpg, device, type, inst, pengine); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ga100.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ga100.c deleted file mode 100644 index f550eb07da5a..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/ga100.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga100_nvjpg = { - .sclass = { - { -1, -1, NVC4D1_VIDEO_NVJPG }, - {} - } -}; - -int -ga100_nvjpg_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_engine **pengine) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvjpg_new(&ga100_nvjpg, device, type, inst, pengine); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/priv.h deleted file mode 100644 index 1e80cf70033a..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/priv.h +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVKM_NVJPG_PRIV_H__ -#define __NVKM_NVJPG_PRIV_H__ -#include <engine/nvjpg.h> - -int r535_nvjpg_new(const struct nvkm_engine_func *, struct nvkm_device *, - enum nvkm_subdev_type, int, struct nvkm_engine **); -#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/r535.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/r535.c deleted file mode 100644 index 1babddc4eb80..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvjpg/r535.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <core/object.h> -#include <subdev/gsp.h> -#include <engine/fifo.h> - -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h> - -struct r535_nvjpg_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_nvjpg_obj_dtor(struct nvkm_object *object) -{ - struct r535_nvjpg_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_nvjpg_obj = { - .dtor = r535_nvjpg_obj_dtor, -}; - -static int -r535_nvjpg_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) -{ - struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); - struct r535_nvjpg_obj *obj; - NV_NVJPG_ALLOCATION_PARAMETERS *args; - - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_nvjpg_obj, oclass, &obj->object); - *pobject = &obj->object; - - args = nvkm_gsp_rm_alloc_get(&chan->rm.object, oclass->handle, oclass->base.oclass, - sizeof(*args), &obj->rm); - if (WARN_ON(IS_ERR(args))) - return PTR_ERR(args); - - args->size = sizeof(*args); - args->engineInstance = oclass->engine->subdev.inst; - - return nvkm_gsp_rm_alloc_wr(&obj->rm, args); -} - -static void * -r535_nvjpg_dtor(struct nvkm_engine *engine) -{ - kfree(engine->func); - return engine; -} - -int -r535_nvjpg_new(const struct nvkm_engine_func *hw, struct nvkm_device *device, - enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) -{ - struct nvkm_engine_func *rm; - int nclass, ret; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_nvjpg_dtor; - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_nvjpg_obj_ctor; - } - - ret = nvkm_engine_new_(rm, device, type, inst, true, pengine); - if (ret) - kfree(rm); - - return ret; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild deleted file mode 100644 index 99f1713d7e51..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/Kbuild +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: MIT -nvkm-y += nvkm/engine/ofa/ga100.o -nvkm-y += nvkm/engine/ofa/ga102.o -nvkm-y += nvkm/engine/ofa/ad102.o - -nvkm-y += nvkm/engine/ofa/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ad102.c b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ad102.c deleted file mode 100644 index 7ac87ef26aec..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ad102.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ad102_ofa = { - .sclass = { - { -1, -1, NVC9FA_VIDEO_OFA }, - {} - } -}; - -int -ad102_ofa_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_engine **pengine) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_ofa_new(&ad102_ofa, device, type, inst, pengine); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga100.c b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga100.c deleted file mode 100644 index ef474f61a1b5..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga100.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga100_ofa = { - .sclass = { - { -1, -1, NVC6FA_VIDEO_OFA }, - {} - } -}; - -int -ga100_ofa_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_engine **pengine) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_ofa_new(&ga100_ofa, device, type, inst, pengine); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga102.c deleted file mode 100644 index bea255529993..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/ga102.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <subdev/gsp.h> - -#include <nvif/class.h> - -static const struct nvkm_engine_func -ga102_ofa = { - .sclass = { - { -1, -1, NVC7FA_VIDEO_OFA }, - {} - } -}; - -int -ga102_ofa_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_engine **pengine) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_ofa_new(&ga102_ofa, device, type, inst, pengine); - - return -ENODEV; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/priv.h deleted file mode 100644 index caf29e6bddb4..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/priv.h +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVKM_OFA_PRIV_H__ -#define __NVKM_OFA_PRIV_H__ -#include <engine/ofa.h> - -int r535_ofa_new(const struct nvkm_engine_func *, struct nvkm_device *, - enum nvkm_subdev_type, int, struct nvkm_engine **); -#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/r535.c b/drivers/gpu/drm/nouveau/nvkm/engine/ofa/r535.c deleted file mode 100644 index 438dc692eefe..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ofa/r535.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2023 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "priv.h" - -#include <core/object.h> -#include <subdev/gsp.h> -#include <subdev/mmu.h> -#include <engine/fifo.h> - -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h> - -struct r535_ofa_obj { - struct nvkm_object object; - struct nvkm_gsp_object rm; -}; - -static void * -r535_ofa_obj_dtor(struct nvkm_object *object) -{ - struct r535_ofa_obj *obj = container_of(object, typeof(*obj), object); - - nvkm_gsp_rm_free(&obj->rm); - return obj; -} - -static const struct nvkm_object_func -r535_ofa_obj = { - .dtor = r535_ofa_obj_dtor, -}; - -static int -r535_ofa_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, - struct nvkm_object **pobject) -{ - struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); - struct r535_ofa_obj *obj; - NV_OFA_ALLOCATION_PARAMETERS *args; - - if (!(obj = kzalloc(sizeof(*obj), GFP_KERNEL))) - return -ENOMEM; - - nvkm_object_ctor(&r535_ofa_obj, oclass, &obj->object); - *pobject = &obj->object; - - args = nvkm_gsp_rm_alloc_get(&chan->rm.object, oclass->handle, oclass->base.oclass, - sizeof(*args), &obj->rm); - if (WARN_ON(IS_ERR(args))) - return PTR_ERR(args); - - args->size = sizeof(*args); - - return nvkm_gsp_rm_alloc_wr(&obj->rm, args); -} - -static void * -r535_ofa_dtor(struct nvkm_engine *engine) -{ - kfree(engine->func); - return engine; -} - -int -r535_ofa_new(const struct nvkm_engine_func *hw, struct nvkm_device *device, - enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) -{ - struct nvkm_engine_func *rm; - int nclass, ret; - - for (nclass = 0; hw->sclass[nclass].oclass; nclass++); - - if (!(rm = kzalloc(sizeof(*rm) + (nclass + 1) * sizeof(rm->sclass[0]), GFP_KERNEL))) - return -ENOMEM; - - rm->dtor = r535_ofa_dtor; - for (int i = 0; i < nclass; i++) { - rm->sclass[i].minver = hw->sclass[i].minver; - rm->sclass[i].maxver = hw->sclass[i].maxver; - rm->sclass[i].oclass = hw->sclass[i].oclass; - rm->sclass[i].ctor = r535_ofa_obj_ctor; - } - - ret = nvkm_engine_new_(rm, device, type, inst, true, pengine); - if (ret) - kfree(rm); - - return ret; -} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild index 4c2f6fc4ef58..c19ea4ea9bd3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild @@ -9,6 +9,7 @@ include $(src)/nvkm/subdev/fault/Kbuild include $(src)/nvkm/subdev/fb/Kbuild include $(src)/nvkm/subdev/fuse/Kbuild include $(src)/nvkm/subdev/gpio/Kbuild +include $(src)/nvkm/subdev/fsp/Kbuild include $(src)/nvkm/subdev/gsp/Kbuild include $(src)/nvkm/subdev/i2c/Kbuild include $(src)/nvkm/subdev/iccsense/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild index 9754c6872543..8faee3317a74 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild @@ -7,5 +7,3 @@ nvkm-y += nvkm/subdev/bar/gk20a.o nvkm-y += nvkm/subdev/bar/gm107.o nvkm-y += nvkm/subdev/bar/gm20b.o nvkm-y += nvkm/subdev/bar/tu102.o - -nvkm-y += nvkm/subdev/bar/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 51070b7dda85..e5e60915029c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -82,7 +82,7 @@ gf100_bar_bar2_init(struct nvkm_bar *base) static int gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, - struct lock_class_key *key, int bar_nr) + struct lock_class_key *key, enum nvkm_bar_id bar_id) { struct nvkm_device *device = bar->base.subdev.device; resource_size_t bar_len; @@ -93,14 +93,14 @@ gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, if (ret) return ret; - bar_len = device->func->resource_size(device, bar_nr); + bar_len = device->func->resource_size(device, bar_id); if (!bar_len) return -ENOMEM; - if (bar_nr == 3 && bar->bar2_halve) + if (bar_id == NVKM_BAR2_INST && bar->bar2_halve) bar_len >>= 1; ret = nvkm_vmm_new(device, 0, bar_len, NULL, 0, key, - (bar_nr == 3) ? "bar2" : "bar1", &bar_vm->vmm); + (bar_id == NVKM_BAR2_INST) ? "bar2" : "bar1", &bar_vm->vmm); if (ret) return ret; @@ -110,7 +110,7 @@ gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, /* * Bootstrap page table lookup. */ - if (bar_nr == 3) { + if (bar_id == NVKM_BAR2_INST) { ret = nvkm_vmm_boot(bar_vm->vmm); if (ret) return ret; @@ -129,7 +129,7 @@ gf100_bar_oneinit(struct nvkm_bar *base) /* BAR2 */ if (bar->base.func->bar2.init) { - ret = gf100_bar_oneinit_bar(bar, &bar->bar[0], &bar2_lock, 3); + ret = gf100_bar_oneinit_bar(bar, &bar->bar[0], &bar2_lock, NVKM_BAR2_INST); if (ret) return ret; @@ -138,7 +138,7 @@ gf100_bar_oneinit(struct nvkm_bar *base) } /* BAR1 */ - ret = gf100_bar_oneinit_bar(bar, &bar->bar[1], &bar1_lock, 1); + ret = gf100_bar_oneinit_bar(bar, &bar->bar[1], &bar1_lock, NVKM_BAR1_FB); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 27d8a1be43e4..6a881becb02c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -127,7 +127,7 @@ nv50_bar_oneinit(struct nvkm_bar *base) /* BAR2 */ start = 0x0100000000ULL; - size = device->func->resource_size(device, 3); + size = device->func->resource_size(device, NVKM_BAR2_INST); if (!size) return -ENOMEM; limit = start + size; @@ -167,7 +167,7 @@ nv50_bar_oneinit(struct nvkm_bar *base) /* BAR1 */ start = 0x0000000000ULL; - size = device->func->resource_size(device, 1); + size = device->func->resource_size(device, NVKM_BAR1_FB); if (!size) return -ENOMEM; limit = start + size; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h index 6c5bbff12eb4..b918e22df5a8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h @@ -47,8 +47,8 @@ static inline struct io_mapping * fbmem_init(struct nvkm_device *dev) { - return io_mapping_create_wc(dev->func->resource_addr(dev, 1), - dev->func->resource_size(dev, 1)); + return io_mapping_create_wc(dev->func->resource_addr(dev, NVKM_BAR1_FB), + dev->func->resource_size(dev, NVKM_BAR1_FB)); } static inline void diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c index c123e5893d76..cd2fbc0472d8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c @@ -50,7 +50,7 @@ nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); struct nvkm_device *device = buffer->fault->subdev.device; *type = NVKM_OBJECT_MAP_IO; - *addr = device->func->resource_addr(device, 3) + buffer->addr; + *addr = device->func->resource_addr(device, NVKM_BAR2_INST) + buffer->addr; *size = nvkm_memory_size(buffer->mem); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild index d1611ad3bf81..8d8a5382d1b1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild @@ -35,6 +35,9 @@ nvkm-y += nvkm/subdev/fb/gv100.o nvkm-y += nvkm/subdev/fb/tu102.o nvkm-y += nvkm/subdev/fb/ga100.o nvkm-y += nvkm/subdev/fb/ga102.o +nvkm-y += nvkm/subdev/fb/gh100.o +nvkm-y += nvkm/subdev/fb/gb100.o +nvkm-y += nvkm/subdev/fb/gb202.o nvkm-y += nvkm/subdev/fb/r535.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c index 25f82b372bca..2819780050d8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c @@ -25,7 +25,7 @@ #include <subdev/gsp.h> #include <engine/nvdec.h> -static u64 +u64 ga102_fb_vidmem_size(struct nvkm_fb *fb) { return (u64)nvkm_rd32(fb->subdev.device, 0x1183a4) << 20; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb100.c new file mode 100644 index 000000000000..1c78c8853617 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb100.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gb100/dev_hshub_base.h> + +static void +gb100_fb_sysmem_flush_page_init(struct nvkm_fb *fb) +{ + const u32 addr_hi = upper_32_bits(fb->sysmem.flush_page_addr); + const u32 addr_lo = lower_32_bits(fb->sysmem.flush_page_addr); + const u32 hshub = DRF_LO(NV_PFB_HSHUB0); + struct nvkm_device *device = fb->subdev.device; + + nvkm_wr32(device, hshub + NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_HI, addr_hi); + nvkm_wr32(device, hshub + NV_PFB_HSHUB_PCIE_FLUSH_SYSMEM_ADDR_LO, addr_lo); + nvkm_wr32(device, hshub + NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_HI, addr_hi); + nvkm_wr32(device, hshub + NV_PFB_HSHUB_EG_PCIE_FLUSH_SYSMEM_ADDR_LO, addr_lo); +} + +static const struct nvkm_fb_func +gb100_fb = { + .sysmem.flush_page_init = gb100_fb_sysmem_flush_page_init, + .vidmem.size = ga102_fb_vidmem_size, +}; + +int +gb100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) +{ + return r535_fb_new(&gb100_fb, device, type, inst, pfb); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb202.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb202.c new file mode 100644 index 000000000000..848505026d02 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gb202.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gb10b/dev_fbhub.h> + +static void +gb202_fb_sysmem_flush_page_init(struct nvkm_fb *fb) +{ + struct nvkm_device *device = fb->subdev.device; + const u64 addr = fb->sysmem.flush_page_addr; + + nvkm_wr32(device, NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_HI, upper_32_bits(addr)); + nvkm_wr32(device, NV_PFB_FBHUB0_PCIE_FLUSH_SYSMEM_ADDR_LO, lower_32_bits(addr)); +} + +static const struct nvkm_fb_func +gb202_fb = { + .sysmem.flush_page_init = gb202_fb_sysmem_flush_page_init, + .vidmem.size = ga102_fb_vidmem_size, +}; + +int +gb202_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) +{ + return r535_fb_new(&gb202_fb, device, type, inst, pfb); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gh100.c new file mode 100644 index 000000000000..2d8c51f882d5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gh100.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gh100/dev_fb.h> + +static void +gh100_fb_sysmem_flush_page_init(struct nvkm_fb *fb) +{ + const u64 addr = fb->sysmem.flush_page_addr >> NV_PFB_NISO_FLUSH_SYSMEM_ADDR_SHIFT; + struct nvkm_device *device = fb->subdev.device; + + nvkm_wr32(device, NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_HI, upper_32_bits(addr)); + nvkm_wr32(device, NV_PFB_FBHUB_PCIE_FLUSH_SYSMEM_ADDR_LO, lower_32_bits(addr)); +} + +static const struct nvkm_fb_func +gh100_fb = { + .sysmem.flush_page_init = gh100_fb_sysmem_flush_page_init, + .vidmem.size = ga102_fb_vidmem_size, +}; + +int +gh100_fb_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) +{ + return r535_fb_new(&gh100_fb, device, type, inst, pfb); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h index 35c55dfba23d..ebe996503ab2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h @@ -98,4 +98,6 @@ int gp102_fb_vpr_scrub(struct nvkm_fb *); int gv100_fb_init_page(struct nvkm_fb *); bool tu102_fb_vpr_scrub_required(struct nvkm_fb *); + +u64 ga102_fb_vidmem_size(struct nvkm_fb *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild new file mode 100644 index 000000000000..1a9ded3a86f8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/Kbuild @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + +nvkm-y += nvkm/subdev/fsp/base.o +nvkm-y += nvkm/subdev/fsp/gh100.o +nvkm-y += nvkm/subdev/fsp/gb100.o +nvkm-y += nvkm/subdev/fsp/gb202.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c new file mode 100644 index 000000000000..e366a980baa9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +int +nvkm_fsp_boot_gsp_fmc(struct nvkm_fsp *fsp, u64 args_addr, u32 rsvd_size, bool resume, + u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig) +{ + return fsp->func->cot.boot_gsp_fmc(fsp, args_addr, rsvd_size, resume, + img_addr, hash, pkey, sig); +} + +bool +nvkm_fsp_verify_gsp_fmc(struct nvkm_fsp *fsp, u32 hash_size, u32 pkey_size, u32 sig_size) +{ + return hash_size == fsp->func->cot.size_hash && + pkey_size == fsp->func->cot.size_pkey && + sig_size == fsp->func->cot.size_sig; +} + +static int +nvkm_fsp_preinit(struct nvkm_subdev *subdev) +{ + struct nvkm_fsp *fsp = nvkm_fsp(subdev); + + return fsp->func->wait_secure_boot(fsp); +} + +static void * +nvkm_fsp_dtor(struct nvkm_subdev *subdev) +{ + struct nvkm_fsp *fsp = nvkm_fsp(subdev); + + nvkm_falcon_dtor(&fsp->falcon); + return fsp; +} + +static const struct nvkm_falcon_func +nvkm_fsp_flcn = { + .emem_pio = &gp102_flcn_emem_pio, +}; + +static const struct nvkm_subdev_func +nvkm_fsp = { + .dtor = nvkm_fsp_dtor, + .preinit = nvkm_fsp_preinit, +}; + +int +nvkm_fsp_new_(const struct nvkm_fsp_func *func, + struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_fsp **pfsp) +{ + struct nvkm_fsp *fsp; + + fsp = *pfsp = kzalloc(sizeof(*fsp), GFP_KERNEL); + if (!fsp) + return -ENOMEM; + + fsp->func = func; + nvkm_subdev_ctor(&nvkm_fsp, device, type, inst, &fsp->subdev); + + return nvkm_falcon_ctor(&nvkm_fsp_flcn, &fsp->subdev, "fsp", 0x8f2000, &fsp->falcon); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb100.c new file mode 100644 index 000000000000..e06636bf54b6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb100.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +static const struct nvkm_fsp_func +gb100_fsp = { + .wait_secure_boot = gh100_fsp_wait_secure_boot, + .cot = { + .version = 2, + .size_hash = 48, + .size_pkey = 97, + .size_sig = 96, + .boot_gsp_fmc = gh100_fsp_boot_gsp_fmc, + }, +}; + +int +gb100_fsp_new(struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_fsp **pfsp) +{ + return nvkm_fsp_new_(&gb100_fsp, device, type, inst, pfsp); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb202.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb202.c new file mode 100644 index 000000000000..3438aac6383e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gb202.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gb202/dev_therm.h> + +static int +gb202_fsp_wait_secure_boot(struct nvkm_fsp *fsp) +{ + struct nvkm_device *device = fsp->subdev.device; + unsigned timeout_ms = 4000; + + do { + u32 status = NVKM_RD32(device, NV_THERM, I2CS_SCRATCH, FSP_BOOT_COMPLETE_STATUS); + + if (status == NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_SUCCESS) + return 0; + + usleep_range(1000, 2000); + } while (timeout_ms--); + + return -ETIMEDOUT; +} + +static const struct nvkm_fsp_func +gb202_fsp = { + .wait_secure_boot = gb202_fsp_wait_secure_boot, + .cot = { + .version = 2, + .size_hash = 48, + .size_pkey = 97, + .size_sig = 96, + .boot_gsp_fmc = gh100_fsp_boot_gsp_fmc, + }, +}; + +int +gb202_fsp_new(struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_fsp **pfsp) +{ + return nvkm_fsp_new_(&gb202_fsp, device, type, inst, pfsp); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c new file mode 100644 index 000000000000..2815be4bf5de --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/gh100.c @@ -0,0 +1,275 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gh100/dev_fsp_pri.h> +#include <nvhw/ref/gh100/dev_therm.h> + +#include <nvrm/nvtypes.h> + +#define MCTP_HEADER_VERSION 3:0 +#define MCTP_HEADER_RSVD 7:4 + +#define MCTP_HEADER_DEID 15:8 +#define MCTP_HEADER_SEID 23:16 + +#define MCTP_HEADER_TAG 26:24 +#define MCTP_HEADER_TO 27:27 +#define MCTP_HEADER_SEQ 29:28 +#define MCTP_HEADER_EOM 30:30 +#define MCTP_HEADER_SOM 31:31 + +#define MCTP_MSG_HEADER_TYPE 6:0 +#define MCTP_MSG_HEADER_IC 7:7 + +#define MCTP_MSG_HEADER_VENDOR_ID 23:8 +#define MCTP_MSG_HEADER_NVDM_TYPE 31:24 + +#define MCTP_MSG_HEADER_TYPE_VENDOR_PCI 0x7e +#define MCTP_MSG_HEADER_VENDOR_ID_NV 0x10de + +#define NVDM_TYPE_COT 0x14 +#define NVDM_TYPE_FSP_RESPONSE 0x15 + +#pragma pack(1) +typedef struct nvdm_payload_cot +{ + NvU16 version; + NvU16 size; + NvU64 gspFmcSysmemOffset; + NvU64 frtsSysmemOffset; + NvU32 frtsSysmemSize; + + // Note this is an offset from the end of FB + NvU64 frtsVidmemOffset; + NvU32 frtsVidmemSize; + + // Authentication related fields + NvU32 hash384[12]; + NvU32 publicKey[96]; + NvU32 signature[96]; + + NvU64 gspBootArgsSysmemOffset; +} NVDM_PAYLOAD_COT; +#pragma pack() + +#pragma pack(1) +typedef struct +{ + NvU32 taskId; + NvU32 commandNvdmType; + NvU32 errorCode; +} NVDM_PAYLOAD_COMMAND_RESPONSE; +#pragma pack() + +static u32 +gh100_fsp_poll(struct nvkm_fsp *fsp) +{ + struct nvkm_device *device = fsp->subdev.device; + u32 head, tail; + + head = nvkm_rd32(device, NV_PFSP_MSGQ_HEAD(0)); + tail = nvkm_rd32(device, NV_PFSP_MSGQ_TAIL(0)); + + if (head == tail) + return 0; + + return (tail - head) + sizeof(u32); /* TAIL points at last DWORD written. */ +} + +static int +gh100_fsp_recv(struct nvkm_fsp *fsp, u8 *packet, u32 max_packet_size) +{ + struct nvkm_device *device = fsp->subdev.device; + u32 packet_size; + int ret; + + packet_size = gh100_fsp_poll(fsp); + if (!packet_size || WARN_ON(packet_size % 4 || packet_size > max_packet_size)) + return -EINVAL; + + ret = nvkm_falcon_pio_rd(&fsp->falcon, 0, EMEM, 0, packet, 0, packet_size); + if (ret) + return ret; + + nvkm_wr32(device, NV_PFSP_MSGQ_TAIL(0), 0); + nvkm_wr32(device, NV_PFSP_MSGQ_HEAD(0), 0); + + return packet_size; +} + +static int +gh100_fsp_wait(struct nvkm_fsp *fsp) +{ + int time = 1000; + + do { + if (gh100_fsp_poll(fsp)) + return 0; + + usleep_range(1000, 2000); + } while(time--); + + return -ETIMEDOUT; +} + +static int +gh100_fsp_send(struct nvkm_fsp *fsp, const u8 *packet, u32 packet_size) +{ + struct nvkm_device *device = fsp->subdev.device; + int time = 1000, ret; + + if (WARN_ON(packet_size % sizeof(u32))) + return -EINVAL; + + /* Ensure any previously sent message has been consumed. */ + do { + u32 head = nvkm_rd32(device, NV_PFSP_QUEUE_HEAD(0)); + u32 tail = nvkm_rd32(device, NV_PFSP_QUEUE_TAIL(0)); + + if (tail == head) + break; + + usleep_range(1000, 2000); + } while(time--); + + if (time < 0) + return -ETIMEDOUT; + + /* Write message to EMEM. */ + ret = nvkm_falcon_pio_wr(&fsp->falcon, packet, 0, 0, EMEM, 0, packet_size, 0, false); + if (ret) + return ret; + + /* Update queue pointers - TAIL points at last DWORD written. */ + nvkm_wr32(device, NV_PFSP_QUEUE_TAIL(0), packet_size - sizeof(u32)); + nvkm_wr32(device, NV_PFSP_QUEUE_HEAD(0), 0); + return 0; +} + +static int +gh100_fsp_send_sync(struct nvkm_fsp *fsp, u8 nvdm_type, const u8 *packet, u32 packet_size) +{ + struct nvkm_subdev *subdev = &fsp->subdev; + struct { + u32 mctp_header; + u32 nvdm_header; + NVDM_PAYLOAD_COMMAND_RESPONSE response; + } reply; + int ret; + + ret = gh100_fsp_send(fsp, packet, packet_size); + if (ret) + return ret; + + ret = gh100_fsp_wait(fsp); + if (ret) + return ret; + + ret = gh100_fsp_recv(fsp, (u8 *)&reply, sizeof(reply)); + if (ret < 0) + return ret; + + if (NVVAL_TEST(reply.mctp_header, MCTP, HEADER, SOM, !=, 1) || + NVVAL_TEST(reply.mctp_header, MCTP, HEADER, EOM, !=, 1)) { + nvkm_error(subdev, "unexpected MCTP header in reply: 0x%08x\n", reply.mctp_header); + return -EIO; + } + + if (NVDEF_TEST(reply.nvdm_header, MCTP, MSG_HEADER, TYPE, !=, VENDOR_PCI) || + NVDEF_TEST(reply.nvdm_header, MCTP, MSG_HEADER, VENDOR_ID, !=, NV) || + NVVAL_TEST(reply.nvdm_header, MCTP, MSG_HEADER, NVDM_TYPE, !=, NVDM_TYPE_FSP_RESPONSE)) { + nvkm_error(subdev, "unexpected NVDM header in reply: 0x%08x\n", reply.nvdm_header); + return -EIO; + } + + if (reply.response.commandNvdmType != nvdm_type) { + nvkm_error(subdev, "expected NVDM type 0x%02x in reply, got 0x%02x\n", + nvdm_type, reply.response.commandNvdmType); + return -EIO; + } + + if (reply.response.errorCode) { + nvkm_error(subdev, "NVDM command 0x%02x failed with error 0x%08x\n", + nvdm_type, reply.response.errorCode); + return -EIO; + } + + return 0; +} + +int +gh100_fsp_boot_gsp_fmc(struct nvkm_fsp *fsp, u64 args_addr, u32 rsvd_size, bool resume, + u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig) +{ + struct { + u32 mctp_header; + u32 nvdm_header; + NVDM_PAYLOAD_COT cot; + } msg = {}; + + msg.mctp_header = NVVAL(MCTP, HEADER, SOM, 1) | + NVVAL(MCTP, HEADER, EOM, 1) | + NVVAL(MCTP, HEADER, SEID, 0) | + NVVAL(MCTP, HEADER, SEQ, 0); + + msg.nvdm_header = NVDEF(MCTP, MSG_HEADER, TYPE, VENDOR_PCI) | + NVDEF(MCTP, MSG_HEADER, VENDOR_ID, NV) | + NVVAL(MCTP, MSG_HEADER, NVDM_TYPE, NVDM_TYPE_COT); + + msg.cot.version = fsp->func->cot.version; + msg.cot.size = sizeof(msg.cot); + msg.cot.gspFmcSysmemOffset = img_addr; + if (!resume) { + msg.cot.frtsVidmemOffset = ALIGN(rsvd_size, 0x200000); + msg.cot.frtsVidmemSize = 0x100000; + } + + memcpy(msg.cot.hash384, hash, fsp->func->cot.size_hash); + memcpy(msg.cot.publicKey, pkey, fsp->func->cot.size_pkey); + memcpy(msg.cot.signature, sig, fsp->func->cot.size_sig); + + msg.cot.gspBootArgsSysmemOffset = args_addr; + + return gh100_fsp_send_sync(fsp, NVDM_TYPE_COT, (const u8 *)&msg, sizeof(msg)); +} + +int +gh100_fsp_wait_secure_boot(struct nvkm_fsp *fsp) +{ + struct nvkm_device *device = fsp->subdev.device; + unsigned timeout_ms = 4000; + + do { + u32 status = NVKM_RD32(device, NV_THERM, I2CS_SCRATCH, FSP_BOOT_COMPLETE_STATUS); + + if (status == NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_SUCCESS) + return 0; + + usleep_range(1000, 2000); + } while (timeout_ms--); + + return -ETIMEDOUT; +} + +static const struct nvkm_fsp_func +gh100_fsp = { + .wait_secure_boot = gh100_fsp_wait_secure_boot, + .cot = { + .version = 1, + .size_hash = 48, + .size_pkey = 384, + .size_sig = 384, + .boot_gsp_fmc = gh100_fsp_boot_gsp_fmc, + }, +}; + +int +gh100_fsp_new(struct nvkm_device *device, + enum nvkm_subdev_type type, int inst, struct nvkm_fsp **pfsp) +{ + return nvkm_fsp_new_(&gh100_fsp, device, type, inst, pfsp); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h new file mode 100644 index 000000000000..f0b2c605c33d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/priv.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_FSP_PRIV_H__ +#define __NVKM_FSP_PRIV_H__ +#define nvkm_fsp(p) container_of((p), struct nvkm_fsp, subdev) +#include <subdev/fsp.h> + +struct nvkm_fsp_func { + int (*wait_secure_boot)(struct nvkm_fsp *); + + struct { + u32 version; + u32 size_hash; + u32 size_pkey; + u32 size_sig; + int (*boot_gsp_fmc)(struct nvkm_fsp *, u64 args_addr, u32 rsvd_size, bool resume, + u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig); + } cot; +}; + +int nvkm_fsp_new_(const struct nvkm_fsp_func *, + struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fsp **); + +int gh100_fsp_wait_secure_boot(struct nvkm_fsp *); +int gh100_fsp_boot_gsp_fmc(struct nvkm_fsp *, u64 args_addr, u32 rsvd_size, bool resume, + u64 img_addr, const u8 *hash, const u8 *pkey, const u8 *sig); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild index 16bf2f1bb780..e9c948b67bbd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/Kbuild @@ -7,6 +7,9 @@ nvkm-y += nvkm/subdev/gsp/tu102.o nvkm-y += nvkm/subdev/gsp/tu116.o nvkm-y += nvkm/subdev/gsp/ga100.o nvkm-y += nvkm/subdev/gsp/ga102.o +nvkm-y += nvkm/subdev/gsp/gh100.o nvkm-y += nvkm/subdev/gsp/ad102.o +nvkm-y += nvkm/subdev/gsp/gb100.o +nvkm-y += nvkm/subdev/gsp/gb202.o -nvkm-y += nvkm/subdev/gsp/r535.o +include $(src)/nvkm/subdev/gsp/rm/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c index c849c6299c52..eb765da0876e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ad102.c @@ -22,30 +22,27 @@ #include "priv.h" static const struct nvkm_gsp_func -ad102_gsp_r535_113_01 = { +ad102_gsp = { .flcn = &ga102_gsp_flcn, .fwsec = &ga102_gsp_fwsec, .sig_section = ".fwsignature_ad10x", - .wpr_heap.os_carveout_size = 20 << 20, - .wpr_heap.base_size = 8 << 20, - .wpr_heap.min_size = 84 << 20, - .booter.ctor = ga102_gsp_booter_ctor, .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = ga102_gsp_reset, - .rm = &r535_gsp_rm, + .rm.gpu = &ad10x_gpu, }; static struct nvkm_gsp_fwif ad102_gsps[] = { - { 0, r535_gsp_load, &ad102_gsp_r535_113_01, "535.113.01", true }, + { 1, tu102_gsp_load, &ad102_gsp, &r570_rm_ga102, "570.144", true }, + { 0, tu102_gsp_load, &ad102_gsp, &r535_rm_ga102, "535.113.01", true }, {} }; @@ -55,3 +52,15 @@ ad102_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { return nvkm_gsp_new_(ad102_gsps, device, type, inst, pgsp); } + +NVKM_GSP_FIRMWARE_BOOTER(ad102, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ad103, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ad104, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ad106, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ad107, 535.113.01); + +NVKM_GSP_FIRMWARE_BOOTER(ad102, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(ad103, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(ad104, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(ad106, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(ad107, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c index da1bebb896f7..d23243a83a4c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c @@ -52,7 +52,7 @@ nvkm_gsp_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_gsp *gsp = nvkm_gsp(subdev); - if (!gsp->func->fini) + if (!gsp->func->fini || !gsp->running) return 0; return gsp->func->fini(gsp, suspend); @@ -80,6 +80,21 @@ nvkm_gsp_oneinit(struct nvkm_subdev *subdev) return gsp->func->oneinit(gsp); } +void +nvkm_gsp_dtor_fws(struct nvkm_gsp *gsp) +{ + nvkm_firmware_put(gsp->fws.fmc); + gsp->fws.fmc = NULL; + nvkm_firmware_put(gsp->fws.bl); + gsp->fws.bl = NULL; + nvkm_firmware_put(gsp->fws.booter.unload); + gsp->fws.booter.unload = NULL; + nvkm_firmware_put(gsp->fws.booter.load); + gsp->fws.booter.load = NULL; + nvkm_firmware_put(gsp->fws.rm); + gsp->fws.rm = NULL; +} + static void * nvkm_gsp_dtor(struct nvkm_subdev *subdev) { @@ -89,6 +104,7 @@ nvkm_gsp_dtor(struct nvkm_subdev *subdev) gsp->func->dtor(gsp); nvkm_falcon_dtor(&gsp->falcon); + kfree(gsp->rm); return gsp; } @@ -101,6 +117,16 @@ nvkm_gsp = { }; int +nvkm_gsp_load_fw(struct nvkm_gsp *gsp, const char *name, const char *ver, + const struct firmware **pfw) +{ + char fwname[64]; + + snprintf(fwname, sizeof(fwname), "gsp/%s-%s", name, ver); + return nvkm_firmware_get(&gsp->subdev, fwname, 0, pfw); +} + +int nvkm_gsp_new_(const struct nvkm_gsp_fwif *fwif, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gsp **pgsp) { @@ -116,7 +142,19 @@ nvkm_gsp_new_(const struct nvkm_gsp_fwif *fwif, struct nvkm_device *device, return PTR_ERR(fwif); gsp->func = fwif->func; - gsp->rm = gsp->func->rm; + + if (fwif->rm) { + nvkm_info(&gsp->subdev, "RM version: %s\n", fwif->ver); + + gsp->rm = kzalloc(sizeof(*gsp->rm), GFP_KERNEL); + if (!gsp->rm) + return -ENOMEM; + + gsp->rm->device = device; + gsp->rm->gpu = fwif->func->rm.gpu; + gsp->rm->wpr = fwif->rm->wpr; + gsp->rm->api = fwif->rm->api; + } return nvkm_falcon_ctor(gsp->func->flcn, &gsp->subdev, gsp->subdev.name, 0x110000, &gsp->falcon); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c index 223f68b532ef..d201e8697226 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c @@ -39,29 +39,27 @@ ga100_gsp_flcn = { }; static const struct nvkm_gsp_func -ga100_gsp_r535_113_01 = { +ga100_gsp = { .flcn = &ga100_gsp_flcn, .fwsec = &tu102_gsp_fwsec, .sig_section = ".fwsignature_ga100", - .wpr_heap.base_size = 8 << 20, - .wpr_heap.min_size = 64 << 20, - .booter.ctor = tu102_gsp_booter_ctor, .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, - .rm = &r535_gsp_rm, + .rm.gpu = &ga100_gpu, }; static struct nvkm_gsp_fwif ga100_gsps[] = { - { 0, r535_gsp_load, &ga100_gsp_r535_113_01, "535.113.01" }, + { 1, tu102_gsp_load, &ga100_gsp, &r570_rm_tu102, "570.144" }, + { 0, tu102_gsp_load, &ga100_gsp, &r535_rm_tu102, "535.113.01" }, { -1, gv100_gsp_nofw, &gv100_gsp }, {} }; @@ -72,3 +70,6 @@ ga100_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { return nvkm_gsp_new_(ga100_gsps, device, type, inst, pgsp); } + +NVKM_GSP_FIRMWARE_BOOTER(ga100, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ga100, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c index 4c4b4168a266..917f7e2f6c46 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c @@ -150,25 +150,21 @@ ga102_gsp_flcn = { }; static const struct nvkm_gsp_func -ga102_gsp_r535_113_01 = { +ga102_gsp_r535 = { .flcn = &ga102_gsp_flcn, .fwsec = &ga102_gsp_fwsec, .sig_section = ".fwsignature_ga10x", - .wpr_heap.os_carveout_size = 20 << 20, - .wpr_heap.base_size = 8 << 20, - .wpr_heap.min_size = 84 << 20, - .booter.ctor = ga102_gsp_booter_ctor, .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = ga102_gsp_reset, - .rm = &r535_gsp_rm, + .rm.gpu = &ga1xx_gpu, }; static const struct nvkm_gsp_func @@ -178,7 +174,8 @@ ga102_gsp = { static struct nvkm_gsp_fwif ga102_gsps[] = { - { 0, r535_gsp_load, &ga102_gsp_r535_113_01, "535.113.01" }, + { 1, tu102_gsp_load, &ga102_gsp_r535, &r570_rm_ga102, "570.144" }, + { 0, tu102_gsp_load, &ga102_gsp_r535, &r535_rm_ga102, "535.113.01" }, { -1, gv100_gsp_nofw, &ga102_gsp }, {} }; @@ -189,3 +186,15 @@ ga102_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { return nvkm_gsp_new_(ga102_gsps, device, type, inst, pgsp); } + +NVKM_GSP_FIRMWARE_BOOTER(ga102, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ga103, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ga104, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ga106, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(ga107, 535.113.01); + +NVKM_GSP_FIRMWARE_BOOTER(ga102, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(ga103, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(ga104, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(ga106, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(ga107, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb100.c new file mode 100644 index 000000000000..12a3f2c1ed82 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb100.c @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +static const struct nvkm_gsp_func +gb100_gsp = { + .flcn = &ga102_gsp_flcn, + + .sig_section = ".fwsignature_gb10x", + + .dtor = r535_gsp_dtor, + .oneinit = gh100_gsp_oneinit, + .init = gh100_gsp_init, + .fini = gh100_gsp_fini, + + .rm.gpu = &gb10x_gpu, +}; + +static struct nvkm_gsp_fwif +gb100_gsps[] = { + { 0, gh100_gsp_load, &gb100_gsp, &r570_rm_gb10x, "570.144", true }, + {} +}; + +int +gb100_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_gsp **pgsp) +{ + return nvkm_gsp_new_(gb100_gsps, device, type, inst, pgsp); +} + +NVKM_GSP_FIRMWARE_FMC(gb100, 570.144); +NVKM_GSP_FIRMWARE_FMC(gb102, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb202.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb202.c new file mode 100644 index 000000000000..c1d718172ddf --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gb202.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +static const struct nvkm_gsp_func +gb202_gsp = { + .flcn = &ga102_gsp_flcn, + + .sig_section = ".fwsignature_gb20x", + + .dtor = r535_gsp_dtor, + .oneinit = gh100_gsp_oneinit, + .init = gh100_gsp_init, + .fini = gh100_gsp_fini, + + .rm.gpu = &gb20x_gpu, +}; + +static struct nvkm_gsp_fwif +gb202_gsps[] = { + { 0, gh100_gsp_load, &gb202_gsp, &r570_rm_gb20x, "570.144", true }, + {} +}; + +int +gb202_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_gsp **pgsp) +{ + return nvkm_gsp_new_(gb202_gsps, device, type, inst, pgsp); +} + +NVKM_GSP_FIRMWARE_FMC(gb202, 570.144); +NVKM_GSP_FIRMWARE_FMC(gb203, 570.144); +NVKM_GSP_FIRMWARE_FMC(gb205, 570.144); +NVKM_GSP_FIRMWARE_FMC(gb206, 570.144); +NVKM_GSP_FIRMWARE_FMC(gb207, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c new file mode 100644 index 000000000000..ce31e8248807 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/gh100.c @@ -0,0 +1,358 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <linux/elf.h> +#include <linux/crc32.h> + +#include <subdev/fb.h> +#include <subdev/fsp.h> + +#include <rm/r570/nvrm/gsp.h> + +#include <nvhw/drf.h> +#include <nvhw/ref/gh100/dev_falcon_v4.h> +#include <nvhw/ref/gh100/dev_riscv_pri.h> + +int +gh100_gsp_fini(struct nvkm_gsp *gsp, bool suspend) +{ + struct nvkm_falcon *falcon = &gsp->falcon; + int ret, time = 4000; + + /* Shutdown RM. */ + ret = r535_gsp_fini(gsp, suspend); + if (ret && suspend) + return ret; + + /* Wait for RISC-V to halt. */ + do { + u32 data = nvkm_falcon_rd32(falcon, falcon->addr2 + NV_PRISCV_RISCV_CPUCTL); + + if (NVVAL_GET(data, NV_PRISCV, RISCV_CPUCTL, HALTED)) + return 0; + + usleep_range(1000, 2000); + } while(time--); + + return -ETIMEDOUT; +} + +static bool +gh100_gsp_lockdown_released(struct nvkm_gsp *gsp, u32 *mbox0) +{ + u32 data; + + /* Wait for GSP access via BAR0 to be allowed. */ + *mbox0 = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_MAILBOX0); + + if (*mbox0 && (*mbox0 & 0xffffff00) == 0xbadf4100) + return false; + + /* Check if an error code has been reported. */ + if (*mbox0) { + u32 mbox1 = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_MAILBOX1); + + /* Any value that's not GSP_FMC_BOOT_PARAMS addr is an error. */ + if ((((u64)mbox1 << 32) | *mbox0) != gsp->fmc.args.addr) + return true; + } + + /* Check if lockdown has been released. */ + data = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_HWCFG2); + return !NVVAL_GET(data, NV_PFALCON, FALCON_HWCFG2, RISCV_BR_PRIV_LOCKDOWN); +} + +int +gh100_gsp_init(struct nvkm_gsp *gsp) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + struct nvkm_device *device = subdev->device; + const bool resume = gsp->sr.meta.data != NULL; + struct nvkm_gsp_mem *meta; + GSP_FMC_BOOT_PARAMS *args; + int ret, time = 4000; + u32 rsvd_size; + u32 mbox0; + + if (!resume) { + ret = nvkm_gsp_mem_ctor(gsp, sizeof(*args), &gsp->fmc.args); + if (ret) + return ret; + + meta = &gsp->wpr_meta; + } else { + gsp->rm->api->gsp->set_rmargs(gsp, true); + meta = &gsp->sr.meta; + } + + args = gsp->fmc.args.data; + + args->bootGspRmParams.gspRmDescOffset = meta->addr; + args->bootGspRmParams.gspRmDescSize = meta->size; + args->bootGspRmParams.target = GSP_DMA_TARGET_COHERENT_SYSTEM; + args->bootGspRmParams.bIsGspRmBoot = 1; + + args->gspRmParams.target = GSP_DMA_TARGET_NONCOHERENT_SYSTEM; + args->gspRmParams.bootArgsOffset = gsp->libos.addr; + + rsvd_size = gsp->fb.heap.size; + if (gsp->rm->wpr->rsvd_size_pmu) + rsvd_size = ALIGN(rsvd_size + gsp->rm->wpr->rsvd_size_pmu, 0x200000); + + ret = nvkm_fsp_boot_gsp_fmc(device->fsp, gsp->fmc.args.addr, rsvd_size, resume, + gsp->fmc.fw.addr, gsp->fmc.hash, gsp->fmc.pkey, gsp->fmc.sig); + if (ret) + return ret; + + do { + if (gh100_gsp_lockdown_released(gsp, &mbox0)) + break; + + usleep_range(1000, 2000); + } while(time--); + + if (time < 0) { + nvkm_error(subdev, "GSP-FMC boot timed out\n"); + return -ETIMEDOUT; + } + + if (mbox0) { + nvkm_error(subdev, "GSP-FMC boot failed (mbox: 0x%08x)\n", mbox0); + return -EIO; + } + + return r535_gsp_init(gsp); +} + +static int +gh100_gsp_wpr_meta_init(struct nvkm_gsp *gsp) +{ + GspFwWprMeta *meta; + int ret; + + ret = nvkm_gsp_mem_ctor(gsp, sizeof(*meta), &gsp->wpr_meta); + if (ret) + return ret; + + gsp->fb.size = nvkm_fb_vidmem_size(gsp->subdev.device); + gsp->fb.bios.vga_workspace.size = 128 * 1024; + gsp->fb.heap.size = gsp->rm->wpr->heap_size_non_wpr; + + meta = gsp->wpr_meta.data; + + meta->magic = GSP_FW_WPR_META_MAGIC; + meta->revision = GSP_FW_WPR_META_REVISION; + + meta->sizeOfRadix3Elf = gsp->fw.len; + meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr; + + meta->sizeOfBootloader = gsp->boot.fw.size; + meta->sysmemAddrOfBootloader = gsp->boot.fw.addr; + meta->bootloaderCodeOffset = gsp->boot.code_offset; + meta->bootloaderDataOffset = gsp->boot.data_offset; + meta->bootloaderManifestOffset = gsp->boot.manifest_offset; + + meta->sysmemAddrOfSignature = gsp->sig.addr; + meta->sizeOfSignature = gsp->sig.size; + + meta->nonWprHeapSize = gsp->fb.heap.size; + meta->gspFwHeapSize = tu102_gsp_wpr_heap_size(gsp); + meta->frtsSize = 0x100000; + meta->vgaWorkspaceSize = gsp->fb.bios.vga_workspace.size; + meta->pmuReservedSize = gsp->rm->wpr->rsvd_size_pmu; + return 0; +} + +/* The sh_flags value for the binary blobs in the ELF image */ +#define FMC_SHF_FLAGS (SHF_MASKPROC | SHF_MASKOS | SHF_OS_NONCONFORMING | SHF_ALLOC) + +#define ELF_HDR_SIZE ((u8)sizeof(struct elf32_hdr)) +#define ELF_SHDR_SIZE ((u8)sizeof(struct elf32_shdr)) + +/* The FMC ELF header must be exactly this */ +static const u8 elf_header[] = { + 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 1, 0, 0, 0, /* e_type, e_machine, e_version */ + 0, 0, 0, 0, 0, 0, 0, 0, /* e_entry, e_phoff */ + + ELF_HDR_SIZE, 0, 0, 0, 0, 0, 0, 0, /* e_shoff, e_flags */ + ELF_HDR_SIZE, 0, 0, 0, /* e_ehsize, e_phentsize */ + 0, 0, ELF_SHDR_SIZE, 0, /* e_phnum, e_shentsize */ + + 6, 0, 1, 0, /* e_shnum, e_shstrndx */ +}; + +/** + * elf_validate_sections - validate each section in the FMC ELF image + * @elf: ELF image + * @length: size of the entire ELF image + */ +static bool +elf_validate_sections(const void *elf, size_t length) +{ + const struct elf32_hdr *ehdr = elf; + const struct elf32_shdr *shdr = elf + ehdr->e_shoff; + + /* The offset of the first section */ + Elf32_Off section_begin = ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize; + + if (section_begin > length) + return false; + + /* The first section header is the null section, so skip it */ + for (unsigned int i = 1; i < ehdr->e_shnum; i++) { + if (i == ehdr->e_shstrndx) { + if (shdr[i].sh_type != SHT_STRTAB) + return false; + if (shdr[i].sh_flags != SHF_STRINGS) + return false; + } else { + if (shdr[i].sh_type != SHT_PROGBITS) + return false; + if (shdr[i].sh_flags != FMC_SHF_FLAGS) + return false; + } + + /* Ensure that each section is inside the image */ + if (shdr[i].sh_offset < section_begin || + (u64)shdr[i].sh_offset + shdr[i].sh_size > length) + return false; + + /* Non-zero sh_info is a CRC */ + if (shdr[i].sh_info) { + /* The kernel's CRC32 needs a pre- and post-xor to match standard CRCs */ + u32 crc32 = crc32_le(~0, elf + shdr[i].sh_offset, shdr[i].sh_size) ^ ~0; + + if (shdr[i].sh_info != crc32) + return false; + } + } + + return true; +} + +/** + * elf_section - return a pointer to the data for a given section + * @elf: ELF image + * @name: section name to search for + * @len: pointer to returned length of found section + */ +static const void * +elf_section(const void *elf, const char *name, unsigned int *len) +{ + const struct elf32_hdr *ehdr = elf; + const struct elf32_shdr *shdr = elf + ehdr->e_shoff; + const char *names = elf + shdr[ehdr->e_shstrndx].sh_offset; + + for (unsigned int i = 1; i < ehdr->e_shnum; i++) { + if (!strcmp(&names[shdr[i].sh_name], name)) { + *len = shdr[i].sh_size; + return elf + shdr[i].sh_offset; + } + } + + return NULL; +} + +int +gh100_gsp_oneinit(struct nvkm_gsp *gsp) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + struct nvkm_device *device = subdev->device; + struct nvkm_fsp *fsp = device->fsp; + const void *fw = gsp->fws.fmc->data; + const void *hash, *sig, *pkey, *img; + unsigned int img_len = 0, hash_len = 0, pkey_len = 0, sig_len = 0; + int ret; + + if (gsp->fws.fmc->size < ELF_HDR_SIZE || + memcmp(fw, elf_header, sizeof(elf_header)) || + !elf_validate_sections(fw, gsp->fws.fmc->size)) { + nvkm_error(subdev, "fmc firmware image is invalid\n"); + return -ENODATA; + } + + hash = elf_section(fw, "hash", &hash_len); + sig = elf_section(fw, "signature", &sig_len); + pkey = elf_section(fw, "publickey", &pkey_len); + img = elf_section(fw, "image", &img_len); + + if (!hash || !sig || !pkey || !img) { + nvkm_error(subdev, "fmc firmware image is invalid\n"); + return -ENODATA; + } + + if (!nvkm_fsp_verify_gsp_fmc(fsp, hash_len, pkey_len, sig_len)) + return -EINVAL; + + /* Load GSP-FMC FW into memory. */ + ret = nvkm_gsp_mem_ctor(gsp, img_len, &gsp->fmc.fw); + if (ret) + return ret; + + memcpy(gsp->fmc.fw.data, img, img_len); + + gsp->fmc.hash = kmemdup(hash, hash_len, GFP_KERNEL); + gsp->fmc.pkey = kmemdup(pkey, pkey_len, GFP_KERNEL); + gsp->fmc.sig = kmemdup(sig, sig_len, GFP_KERNEL); + if (!gsp->fmc.hash || !gsp->fmc.pkey || !gsp->fmc.sig) + return -ENOMEM; + + ret = r535_gsp_oneinit(gsp); + if (ret) + return ret; + + return gh100_gsp_wpr_meta_init(gsp); +} + +static const struct nvkm_gsp_func +gh100_gsp = { + .flcn = &ga102_gsp_flcn, + + .sig_section = ".fwsignature_gh100", + + .dtor = r535_gsp_dtor, + .oneinit = gh100_gsp_oneinit, + .init = gh100_gsp_init, + .fini = gh100_gsp_fini, + + .rm.gpu = &gh100_gpu, +}; + +int +gh100_gsp_load(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif *fwif) +{ + int ret; + + ret = tu102_gsp_load_rm(gsp, fwif); + if (ret) + goto done; + + ret = nvkm_gsp_load_fw(gsp, "fmc", fwif->ver, &gsp->fws.fmc); + +done: + if (ret) + nvkm_gsp_dtor_fws(gsp); + + return ret; +} + +static struct nvkm_gsp_fwif +gh100_gsps[] = { + { 0, gh100_gsp_load, &gh100_gsp, &r570_rm_gh100, "570.144", true }, + {} +}; + +int +gh100_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_gsp **pgsp) +{ + return nvkm_gsp_new_(gh100_gsps, device, type, inst, pgsp); +} + +NVKM_GSP_FIRMWARE_FMC(gh100, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h index 9f4a62375a27..4f14e85fc69e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h @@ -2,6 +2,7 @@ #ifndef __NVKM_GSP_PRIV_H__ #define __NVKM_GSP_PRIV_H__ #include <subdev/gsp.h> +#include <rm/gpu.h> enum nvkm_acr_lsf_id; int nvkm_gsp_fwsec_frts(struct nvkm_gsp *); @@ -11,12 +12,32 @@ struct nvkm_gsp_fwif { int version; int (*load)(struct nvkm_gsp *, int ver, const struct nvkm_gsp_fwif *); const struct nvkm_gsp_func *func; + const struct nvkm_rm_impl *rm; const char *ver; bool enable; }; +int nvkm_gsp_load_fw(struct nvkm_gsp *, const char *name, const char *ver, + const struct firmware **); +void nvkm_gsp_dtor_fws(struct nvkm_gsp *); + int gv100_gsp_nofw(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); -int r535_gsp_load(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); + +int tu102_gsp_load(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); +int tu102_gsp_load_rm(struct nvkm_gsp *, const struct nvkm_gsp_fwif *); + +int gh100_gsp_load(struct nvkm_gsp *, int, const struct nvkm_gsp_fwif *); + +#define NVKM_GSP_FIRMWARE_BOOTER(chip,vers) \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_load-"#vers".bin"); \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_unload-"#vers".bin"); \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/bootloader-"#vers".bin"); \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/gsp-"#vers".bin") + +#define NVKM_GSP_FIRMWARE_FMC(chip,vers) \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/fmc-"#vers".bin"); \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/bootloader-"#vers".bin"); \ +MODULE_FIRMWARE("nvidia/"#chip"/gsp/gsp-"#vers".bin") struct nvkm_gsp_func { const struct nvkm_falcon_func *flcn; @@ -25,12 +46,6 @@ struct nvkm_gsp_func { char *sig_section; struct { - u32 os_carveout_size; - u32 base_size; - u64 min_size; - } wpr_heap; - - struct { int (*ctor)(struct nvkm_gsp *, const char *name, const struct firmware *, struct nvkm_falcon *, struct nvkm_falcon_fw *); } booter; @@ -41,7 +56,9 @@ struct nvkm_gsp_func { int (*fini)(struct nvkm_gsp *, bool suspend); int (*reset)(struct nvkm_gsp *); - const struct nvkm_gsp_rm *rm; + struct { + const struct nvkm_rm_gpu *gpu; + } rm; }; extern const struct nvkm_falcon_func tu102_gsp_flcn; @@ -49,7 +66,10 @@ extern const struct nvkm_falcon_fw_func tu102_gsp_fwsec; int tu102_gsp_booter_ctor(struct nvkm_gsp *, const char *, const struct firmware *, struct nvkm_falcon *, struct nvkm_falcon_fw *); int tu102_gsp_oneinit(struct nvkm_gsp *); +int tu102_gsp_init(struct nvkm_gsp *); +int tu102_gsp_fini(struct nvkm_gsp *, bool suspend); int tu102_gsp_reset(struct nvkm_gsp *); +u64 tu102_gsp_wpr_heap_size(struct nvkm_gsp *); extern const struct nvkm_falcon_func ga102_gsp_flcn; extern const struct nvkm_falcon_fw_func ga102_gsp_fwsec; @@ -57,11 +77,14 @@ int ga102_gsp_booter_ctor(struct nvkm_gsp *, const char *, const struct firmware struct nvkm_falcon *, struct nvkm_falcon_fw *); int ga102_gsp_reset(struct nvkm_gsp *); +int gh100_gsp_oneinit(struct nvkm_gsp *); +int gh100_gsp_init(struct nvkm_gsp *); +int gh100_gsp_fini(struct nvkm_gsp *, bool suspend); + void r535_gsp_dtor(struct nvkm_gsp *); int r535_gsp_oneinit(struct nvkm_gsp *); int r535_gsp_init(struct nvkm_gsp *); int r535_gsp_fini(struct nvkm_gsp *, bool suspend); -extern const struct nvkm_gsp_rm r535_gsp_rm; int nvkm_gsp_new_(const struct nvkm_gsp_fwif *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild new file mode 100644 index 000000000000..04037394a2da --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/Kbuild @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +nvkm-y += nvkm/subdev/gsp/rm/client.o +nvkm-y += nvkm/subdev/gsp/rm/engine.o +nvkm-y += nvkm/subdev/gsp/rm/gr.o +nvkm-y += nvkm/subdev/gsp/rm/nvdec.o +nvkm-y += nvkm/subdev/gsp/rm/nvenc.o + +nvkm-y += nvkm/subdev/gsp/rm/tu1xx.o +nvkm-y += nvkm/subdev/gsp/rm/ga100.o +nvkm-y += nvkm/subdev/gsp/rm/ga1xx.o +nvkm-y += nvkm/subdev/gsp/rm/ad10x.o +nvkm-y += nvkm/subdev/gsp/rm/gh100.o +nvkm-y += nvkm/subdev/gsp/rm/gb10x.o +nvkm-y += nvkm/subdev/gsp/rm/gb20x.o + +include $(src)/nvkm/subdev/gsp/rm/r535/Kbuild +include $(src)/nvkm/subdev/gsp/rm/r570/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c new file mode 100644 index 000000000000..e1ce6355c35f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ad10x.c @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +#include <engine/fifo/priv.h> + +#include <nvif/class.h> + +const struct nvkm_rm_gpu +ad10x_gpu = { + .disp.class = { + .root = AD102_DISP, + .caps = GV100_DISP_CAPS, + .core = AD102_DISP_CORE_CHANNEL_DMA, + .wndw = GA102_DISP_WINDOW_CHANNEL_DMA, + .wimm = GA102_DISP_WINDOW_IMM_CHANNEL_DMA, + .curs = GA102_DISP_CURSOR, + }, + + .usermode.class = AMPERE_USERMODE_A, + + .fifo.chan = { + .class = AMPERE_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, + }, + + .ce.class = AMPERE_DMA_COPY_B, + .gr.class = { + .i2m = KEPLER_INLINE_TO_MEMORY_B, + .twod = FERMI_TWOD_A, + .threed = ADA_A, + .compute = ADA_COMPUTE_A, + }, + .nvdec.class = NVC9B0_VIDEO_DECODER, + .nvenc.class = NVC9B7_VIDEO_ENCODER, + .ofa.class = NVC9FA_VIDEO_OFA, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/client.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/client.c new file mode 100644 index 000000000000..72d3e3ca84c2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/client.c @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "rm.h" + +void +nvkm_gsp_client_dtor(struct nvkm_gsp_client *client) +{ + const unsigned int id = client->object.handle - NVKM_RM_CLIENT(0); + struct nvkm_gsp *gsp = client->gsp; + + if (!gsp) + return; + + if (client->object.client) + nvkm_gsp_rm_free(&client->object); + + mutex_lock(&gsp->client_id.mutex); + idr_remove(&gsp->client_id.idr, id); + mutex_unlock(&gsp->client_id.mutex); + + client->gsp = NULL; +} + +int +nvkm_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client) +{ + int id, ret; + + if (WARN_ON(!gsp->rm)) + return -ENOSYS; + + mutex_lock(&gsp->client_id.mutex); + id = idr_alloc(&gsp->client_id.idr, client, 0, NVKM_RM_CLIENT_MASK + 1, GFP_KERNEL); + mutex_unlock(&gsp->client_id.mutex); + if (id < 0) + return id; + + client->gsp = gsp; + client->object.client = client; + INIT_LIST_HEAD(&client->events); + + ret = gsp->rm->api->client->ctor(client, NVKM_RM_CLIENT(id)); + if (ret) + nvkm_gsp_client_dtor(client); + + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c new file mode 100644 index 000000000000..3b0e83b2f57f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c @@ -0,0 +1,189 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "engine.h" +#include "gpu.h" + +#include <core/object.h> +#include <engine/fifo/chan.h> + +struct nvkm_rm_engine { + struct nvkm_engine engine; + + struct nvkm_engine_func func; +}; + +struct nvkm_rm_engine_obj { + struct nvkm_object object; + struct nvkm_gsp_object rm; +}; + +static void* +nvkm_rm_engine_obj_dtor(struct nvkm_object *object) +{ + struct nvkm_rm_engine_obj *obj = container_of(object, typeof(*obj), object); + + nvkm_gsp_rm_free(&obj->rm); + return obj; +} + +static const struct nvkm_object_func +nvkm_rm_engine_obj = { + .dtor = nvkm_rm_engine_obj_dtor, +}; + +int +nvkm_rm_engine_obj_new(struct nvkm_gsp_object *chan, int chid, const struct nvkm_oclass *oclass, + struct nvkm_object **pobject) +{ + struct nvkm_rm *rm = chan->client->gsp->rm; + const int inst = oclass->engine->subdev.inst; + const u32 class = oclass->base.oclass; + const u32 handle = oclass->handle; + struct nvkm_rm_engine_obj *obj; + int ret; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) + return -ENOMEM; + + switch (oclass->engine->subdev.type) { + case NVKM_ENGINE_CE: + ret = rm->api->ce->alloc(chan, handle, class, inst, &obj->rm); + break; + case NVKM_ENGINE_GR: + ret = nvkm_gsp_rm_alloc(chan, handle, class, 0, &obj->rm); + break; + case NVKM_ENGINE_NVDEC: + ret = rm->api->nvdec->alloc(chan, handle, class, inst, &obj->rm); + break; + case NVKM_ENGINE_NVENC: + ret = rm->api->nvenc->alloc(chan, handle, class, inst, &obj->rm); + break; + case NVKM_ENGINE_NVJPG: + ret = rm->api->nvjpg->alloc(chan, handle, class, inst, &obj->rm); + break; + case NVKM_ENGINE_OFA: + ret = rm->api->ofa->alloc(chan, handle, class, inst, &obj->rm); + break; + default: + ret = -EINVAL; + WARN_ON(1); + break; + } + + if (ret) { + kfree(obj); + return ret; + } + + nvkm_object_ctor(&nvkm_rm_engine_obj, oclass, &obj->object); + *pobject = &obj->object; + return 0; +} + +static int +nvkm_rm_engine_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) +{ + struct nvkm_chan *chan = nvkm_uchan_chan(oclass->parent); + + return nvkm_rm_engine_obj_new(&chan->rm.object, chan->id, oclass, pobject); +} + +static void * +nvkm_rm_engine_dtor(struct nvkm_engine *engine) +{ + kfree(engine->func); + return engine; +} + +int +nvkm_rm_engine_ctor(void *(*dtor)(struct nvkm_engine *), struct nvkm_rm *rm, + enum nvkm_subdev_type type, int inst, + const u32 *class, int nclass, struct nvkm_engine *engine) +{ + struct nvkm_engine_func *func; + + func = kzalloc(struct_size(func, sclass, nclass + 1), GFP_KERNEL); + if (!func) + return -ENOMEM; + + func->dtor = dtor; + + for (int i = 0; i < nclass; i++) { + func->sclass[i].oclass = class[i]; + func->sclass[i].minver = -1; + func->sclass[i].maxver = 0; + func->sclass[i].ctor = nvkm_rm_engine_obj_ctor; + } + + nvkm_engine_ctor(func, rm->device, type, inst, true, engine); + return 0; +} + +static int +nvkm_rm_engine_new_(struct nvkm_rm *rm, enum nvkm_subdev_type type, int inst, u32 class, + struct nvkm_engine **pengine) +{ + struct nvkm_engine *engine; + int ret; + + engine = kzalloc(sizeof(*engine), GFP_KERNEL); + if (!engine) + return -ENOMEM; + + ret = nvkm_rm_engine_ctor(nvkm_rm_engine_dtor, rm, type, inst, &class, 1, engine); + if (ret) { + kfree(engine); + return ret; + } + + *pengine = engine; + return 0; +} + +int +nvkm_rm_engine_new(struct nvkm_rm *rm, enum nvkm_subdev_type type, int inst) +{ + const struct nvkm_rm_gpu *gpu = rm->gpu; + struct nvkm_device *device = rm->device; + + switch (type) { + case NVKM_ENGINE_CE: + if (WARN_ON(inst >= ARRAY_SIZE(device->ce))) + return -EINVAL; + + return nvkm_rm_engine_new_(rm, type, inst, gpu->ce.class, &device->ce[inst]); + case NVKM_ENGINE_GR: + if (inst != 0) + return -ENODEV; /* MiG not supported, just ignore. */ + + return nvkm_rm_gr_new(rm); + case NVKM_ENGINE_NVDEC: + if (WARN_ON(inst >= ARRAY_SIZE(device->nvdec))) + return -EINVAL; + + return nvkm_rm_nvdec_new(rm, inst); + case NVKM_ENGINE_NVENC: + if (WARN_ON(inst >= ARRAY_SIZE(device->nvenc))) + return -EINVAL; + + return nvkm_rm_nvenc_new(rm, inst); + case NVKM_ENGINE_NVJPG: + if (WARN_ON(inst >= ARRAY_SIZE(device->nvjpg))) + return -EINVAL; + + return nvkm_rm_engine_new_(rm, type, inst, gpu->nvjpg.class, &device->nvjpg[inst]); + case NVKM_ENGINE_OFA: + if (WARN_ON(inst >= ARRAY_SIZE(device->ofa))) + return -EINVAL; + + return nvkm_rm_engine_new_(rm, type, inst, gpu->ofa.class, &device->ofa[inst]); + default: + break; + } + + return -ENODEV; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.h new file mode 100644 index 000000000000..5b8c9c3901d4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_RM_ENGINE_H__ +#define __NVKM_RM_ENGINE_H__ +#include "gpu.h" + +int nvkm_rm_engine_ctor(void *(*dtor)(struct nvkm_engine *), struct nvkm_rm *, + enum nvkm_subdev_type type, int inst, + const u32 *class, int nclass, struct nvkm_engine *); +int nvkm_rm_engine_new(struct nvkm_rm *, enum nvkm_subdev_type, int inst); + +int nvkm_rm_engine_obj_new(struct nvkm_gsp_object *chan, int chid, const struct nvkm_oclass *, + struct nvkm_object **); + +int nvkm_rm_gr_new(struct nvkm_rm *); +int nvkm_rm_nvdec_new(struct nvkm_rm *, int inst); +int nvkm_rm_nvenc_new(struct nvkm_rm *, int inst); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c new file mode 100644 index 000000000000..a48c6134075d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga100.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +#include <engine/fifo/priv.h> + +#include <nvif/class.h> + +const struct nvkm_rm_gpu +ga100_gpu = { + .usermode.class = AMPERE_USERMODE_A, + + .fifo.chan = { + .class = AMPERE_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, + }, + + .ce.class = AMPERE_DMA_COPY_A, + .gr.class = { + .i2m = KEPLER_INLINE_TO_MEMORY_B, + .twod = FERMI_TWOD_A, + .threed = AMPERE_A, + .compute = AMPERE_COMPUTE_A, + }, + .nvdec.class = NVC6B0_VIDEO_DECODER, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c new file mode 100644 index 000000000000..50536ad7f85d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/ga1xx.c @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +#include <engine/fifo/priv.h> + +#include <nvif/class.h> + +const struct nvkm_rm_gpu +ga1xx_gpu = { + .disp.class = { + .root = GA102_DISP, + .caps = GV100_DISP_CAPS, + .core = GA102_DISP_CORE_CHANNEL_DMA, + .wndw = GA102_DISP_WINDOW_CHANNEL_DMA, + .wimm = GA102_DISP_WINDOW_IMM_CHANNEL_DMA, + .curs = GA102_DISP_CURSOR, + }, + + .usermode.class = AMPERE_USERMODE_A, + + .fifo.chan = { + .class = AMPERE_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, + }, + + .ce.class = AMPERE_DMA_COPY_B, + .gr.class = { + .i2m = KEPLER_INLINE_TO_MEMORY_B, + .twod = FERMI_TWOD_A, + .threed = AMPERE_B, + .compute = AMPERE_COMPUTE_B, + }, + .nvdec.class = NVC7B0_VIDEO_DECODER, + .nvenc.class = NVC7B7_VIDEO_ENCODER, + .ofa.class = NVC7FA_VIDEO_OFA, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c new file mode 100644 index 000000000000..2f517dcd721a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb10x.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +#include <engine/fifo/priv.h> + +#include <nvif/class.h> + +const struct nvkm_rm_gpu +gb10x_gpu = { + .usermode.class = HOPPER_USERMODE_A, + + .fifo.chan = { + .class = BLACKWELL_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, + }, + + .ce.class = BLACKWELL_DMA_COPY_A, + .gr.class = { + .i2m = BLACKWELL_INLINE_TO_MEMORY_A, + .twod = FERMI_TWOD_A, + .threed = BLACKWELL_A, + .compute = BLACKWELL_COMPUTE_A, + }, + .nvdec.class = NVCDB0_VIDEO_DECODER, + .nvjpg.class = NVCDD1_VIDEO_NVJPG, + .ofa.class = NVCDFA_VIDEO_OFA, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb20x.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb20x.c new file mode 100644 index 000000000000..950471d9996e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gb20x.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +#include <engine/ce/priv.h> +#include <engine/fifo/priv.h> + +#include <nvif/class.h> + +const struct nvkm_rm_gpu +gb20x_gpu = { + .disp.class = { + .root = GB202_DISP, + .caps = GB202_DISP_CAPS, + .core = GB202_DISP_CORE_CHANNEL_DMA, + .wndw = GB202_DISP_WINDOW_CHANNEL_DMA, + .wimm = GB202_DISP_WINDOW_IMM_CHANNEL_DMA, + .curs = GB202_DISP_CURSOR, + }, + + .usermode.class = BLACKWELL_USERMODE_A, + + .fifo.chan = { + .class = BLACKWELL_CHANNEL_GPFIFO_B, + .doorbell_handle = gb202_chan_doorbell_handle, + }, + + .ce = { + .class = BLACKWELL_DMA_COPY_B, + .grce_mask = gb202_ce_grce_mask, + }, + .gr.class = { + .i2m = BLACKWELL_INLINE_TO_MEMORY_A, + .twod = FERMI_TWOD_A, + .threed = BLACKWELL_B, + .compute = BLACKWELL_COMPUTE_B, + }, + .nvdec.class = NVCFB0_VIDEO_DECODER, + .nvenc.class = NVCFB7_VIDEO_ENCODER, + .nvjpg.class = NVCFD1_VIDEO_NVJPG, + .ofa.class = NVCFFA_VIDEO_OFA, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c new file mode 100644 index 000000000000..49e2c54e1aa8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gh100.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +#include <engine/fifo/priv.h> + +#include <nvif/class.h> + +const struct nvkm_rm_gpu +gh100_gpu = { + .usermode.class = HOPPER_USERMODE_A, + + .fifo.chan = { + .class = HOPPER_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, + }, + + .ce.class = HOPPER_DMA_COPY_A, + .gr.class = { + .i2m = KEPLER_INLINE_TO_MEMORY_B, + .twod = FERMI_TWOD_A, + .threed = HOPPER_A, + .compute = HOPPER_COMPUTE_A, + }, + .nvdec.class = NVB8B0_VIDEO_DECODER, + .nvjpg.class = NVB8D1_VIDEO_NVJPG, + .ofa.class = NVB8FA_VIDEO_OFA, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h new file mode 100644 index 000000000000..46a6325641b7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gpu.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_RM_GPU_H__ +#define __NVKM_RM_GPU_H__ +#include "rm.h" + +struct nvkm_rm_gpu { + struct { + struct { + u32 root; + u32 caps; + u32 core; + u32 wndw; + u32 wimm; + u32 curs; + } class; + } disp; + + struct { + u32 class; + } usermode; + + struct { + struct { + u32 class; + u32 (*doorbell_handle)(struct nvkm_chan *); + } chan; + } fifo; + + struct { + u32 class; + u32 (*grce_mask)(struct nvkm_device *); + } ce; + + struct { + struct { + u32 i2m; + u32 twod; + u32 threed; + u32 compute; + } class; + } gr; + + struct { + u32 class; + } nvdec; + + struct { + u32 class; + } nvenc; + + struct { + u32 class; + } nvjpg; + + struct { + u32 class; + } ofa; +}; + +extern const struct nvkm_rm_gpu tu1xx_gpu; +extern const struct nvkm_rm_gpu ga100_gpu; +extern const struct nvkm_rm_gpu ga1xx_gpu; +extern const struct nvkm_rm_gpu ad10x_gpu; +extern const struct nvkm_rm_gpu gh100_gpu; +extern const struct nvkm_rm_gpu gb10x_gpu; +extern const struct nvkm_rm_gpu gb20x_gpu; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c new file mode 100644 index 000000000000..f40b8fcc2bcb --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gr.h" + +#include <engine/fifo.h> +#include <engine/gr/priv.h> + +static int +nvkm_rm_gr_obj_ctor(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) +{ + struct r535_gr_chan *chan = container_of(oclass->parent, typeof(*chan), object); + + return nvkm_rm_engine_obj_new(&chan->chan->rm.object, chan->chan->id, oclass, pobject); +} + +static int +nvkm_rm_gr_fini(struct nvkm_gr *base, bool suspend) +{ + struct nvkm_rm *rm = base->engine.subdev.device->gsp->rm; + struct r535_gr *gr = container_of(base, typeof(*gr), base); + + if (rm->api->gr->scrubber.fini) + rm->api->gr->scrubber.fini(gr); + + return 0; +} + +static int +nvkm_rm_gr_init(struct nvkm_gr *base) +{ + struct nvkm_rm *rm = base->engine.subdev.device->gsp->rm; + struct r535_gr *gr = container_of(base, typeof(*gr), base); + int ret; + + if (rm->api->gr->scrubber.init) { + ret = rm->api->gr->scrubber.init(gr); + if (ret) + return ret; + } + + return 0; +} + +int +nvkm_rm_gr_new(struct nvkm_rm *rm) +{ + const u32 classes[] = { + rm->gpu->gr.class.i2m, + rm->gpu->gr.class.twod, + rm->gpu->gr.class.threed, + rm->gpu->gr.class.compute, + }; + struct nvkm_gr_func *func; + struct r535_gr *gr; + + func = kzalloc(struct_size(func, sclass, ARRAY_SIZE(classes) + 1), GFP_KERNEL); + if (!func) + return -ENOMEM; + + func->dtor = r535_gr_dtor; + func->oneinit = r535_gr_oneinit; + func->init = nvkm_rm_gr_init; + func->fini = nvkm_rm_gr_fini; + func->units = r535_gr_units; + func->chan_new = r535_gr_chan_new; + + for (int i = 0; i < ARRAY_SIZE(classes); i++) { + func->sclass[i].oclass = classes[i]; + func->sclass[i].minver = -1; + func->sclass[i].maxver = 0; + func->sclass[i].ctor = nvkm_rm_gr_obj_ctor; + } + + gr = kzalloc(sizeof(*gr), GFP_KERNEL); + if (!gr) { + kfree(func); + return -ENOMEM; + } + + nvkm_gr_ctor(func, rm->device, NVKM_ENGINE_GR, 0, true, &gr->base); + gr->scrubber.chid = -1; + rm->device->gr = &gr->base; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.h new file mode 100644 index 000000000000..24980f23aab9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_RM_GR_H__ +#define __NVKM_RM_GR_H__ +#include "engine.h" + +#include <core/object.h> +#include <engine/gr.h> + +#define R515_GR_MAX_CTXBUFS 9 + +struct r535_gr_chan { + struct nvkm_object object; + struct r535_gr *gr; + + struct nvkm_vmm *vmm; + struct nvkm_chan *chan; + + struct nvkm_memory *mem[R515_GR_MAX_CTXBUFS]; + struct nvkm_vma *vma[R515_GR_MAX_CTXBUFS]; +}; + +struct r535_gr { + struct nvkm_gr base; + + struct { + u16 bufferId; + u32 size; + u8 page; + u8 align; + bool global; + bool init; + bool ro; + } ctxbuf[R515_GR_MAX_CTXBUFS]; + int ctxbuf_nr; + + struct nvkm_memory *ctxbuf_mem[R515_GR_MAX_CTXBUFS]; + + struct { + int chid; + struct nvkm_memory *inst; + struct nvkm_vmm *vmm; + struct nvkm_gsp_object chan; + struct nvkm_gsp_object threed; + struct { + struct nvkm_memory *mem[R515_GR_MAX_CTXBUFS]; + struct nvkm_vma *vma[R515_GR_MAX_CTXBUFS]; + } ctxbuf; + bool enabled; + } scrubber; +}; + +struct NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO; +void r535_gr_get_ctxbuf_info(struct r535_gr *, int i, + struct NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO *); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h new file mode 100644 index 000000000000..3bdb5ad320d7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/handles.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_RM_HANDLES_H__ +#define __NVKM_RM_HANDLES_H__ + +/* RMAPI handles for various objects allocated from GSP-RM with RM_ALLOC. */ + +#define NVKM_RM_CLIENT(id) (0xc1d00000 | (id)) +#define NVKM_RM_CLIENT_MASK 0x0000ffff +#define NVKM_RM_DEVICE 0xde1d0000 +#define NVKM_RM_SUBDEVICE 0x5d1d0000 +#define NVKM_RM_DISP 0x00730000 +#define NVKM_RM_VASPACE 0x90f10000 +#define NVKM_RM_CHAN(chid) (0xf1f00000 | (chid)) +#define NVKM_RM_THREED 0x97000000 +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c new file mode 100644 index 000000000000..d9fbfc377864 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "engine.h" +#include <engine/nvdec.h> + +static void * +nvkm_rm_nvdec_dtor(struct nvkm_engine *engine) +{ + return container_of(engine, struct nvkm_nvdec, engine); +} + +int +nvkm_rm_nvdec_new(struct nvkm_rm *rm, int inst) +{ + struct nvkm_nvdec *nvdec; + int ret; + + nvdec = kzalloc(sizeof(*nvdec), GFP_KERNEL); + if (!nvdec) + return -ENOMEM; + + ret = nvkm_rm_engine_ctor(nvkm_rm_nvdec_dtor, rm, NVKM_ENGINE_NVDEC, inst, + &rm->gpu->nvdec.class, 1, &nvdec->engine); + if (ret) { + kfree(nvdec); + return ret; + } + + rm->device->nvdec[inst] = nvdec; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c new file mode 100644 index 000000000000..6dfa7b789e07 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "engine.h" +#include <engine/nvenc.h> + +static void * +nvkm_rm_nvenc_dtor(struct nvkm_engine *engine) +{ + return container_of(engine, struct nvkm_nvenc, engine); +} + +int +nvkm_rm_nvenc_new(struct nvkm_rm *rm, int inst) +{ + struct nvkm_nvenc *nvenc; + int ret; + + nvenc = kzalloc(sizeof(*nvenc), GFP_KERNEL); + if (!nvenc) + return -ENOMEM; + + ret = nvkm_rm_engine_ctor(nvkm_rm_nvenc_dtor, rm, NVKM_ENGINE_NVENC, inst, + &rm->gpu->nvenc.class, 1, &nvenc->engine); + if (ret) { + kfree(nvenc); + return ret; + } + + rm->device->nvenc[inst] = nvenc; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild new file mode 100644 index 000000000000..a5f6b2abfd33 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/Kbuild @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + +nvkm-y += nvkm/subdev/gsp/rm/r535/rm.o +nvkm-y += nvkm/subdev/gsp/rm/r535/gsp.o +nvkm-y += nvkm/subdev/gsp/rm/r535/rpc.o +nvkm-y += nvkm/subdev/gsp/rm/r535/ctrl.o +nvkm-y += nvkm/subdev/gsp/rm/r535/alloc.o +nvkm-y += nvkm/subdev/gsp/rm/r535/client.o +nvkm-y += nvkm/subdev/gsp/rm/r535/device.o + +nvkm-y += nvkm/subdev/gsp/rm/r535/bar.o +nvkm-y += nvkm/subdev/gsp/rm/r535/fbsr.o +nvkm-y += nvkm/subdev/gsp/rm/r535/vmm.o + +nvkm-y += nvkm/subdev/gsp/rm/r535/disp.o + +nvkm-y += nvkm/subdev/gsp/rm/r535/fifo.o +nvkm-y += nvkm/subdev/gsp/rm/r535/ce.o +nvkm-y += nvkm/subdev/gsp/rm/r535/gr.o +nvkm-y += nvkm/subdev/gsp/rm/r535/nvdec.o +nvkm-y += nvkm/subdev/gsp/rm/r535/nvenc.o +nvkm-y += nvkm/subdev/gsp/rm/r535/nvjpg.o +nvkm-y += nvkm/subdev/gsp/rm/r535/ofa.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c new file mode 100644 index 000000000000..46e3a29f2ad7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c @@ -0,0 +1,112 @@ +/* + * Copyright 2023 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include <rm/rpc.h> + +#include "nvrm/alloc.h" +#include "nvrm/rpcfn.h" + +static int +r535_gsp_rpc_rm_free(struct nvkm_gsp_object *object) +{ + struct nvkm_gsp_client *client = object->client; + struct nvkm_gsp *gsp = client->gsp; + rpc_free_v03_00 *rpc; + + nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x free\n", + client->object.handle, object->handle); + + rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc)); + if (WARN_ON(IS_ERR_OR_NULL(rpc))) + return -EIO; + + rpc->params.hRoot = client->object.handle; + rpc->params.hObjectParent = 0; + rpc->params.hObjectOld = object->handle; + return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV); +} + +static void +r535_gsp_rpc_rm_alloc_done(struct nvkm_gsp_object *object, void *params) +{ + rpc_gsp_rm_alloc_v03_00 *rpc = to_payload_hdr(params, rpc); + + nvkm_gsp_rpc_done(object->client->gsp, rpc); +} + +static void * +r535_gsp_rpc_rm_alloc_push(struct nvkm_gsp_object *object, void *params) +{ + rpc_gsp_rm_alloc_v03_00 *rpc = to_payload_hdr(params, rpc); + struct nvkm_gsp *gsp = object->client->gsp; + void *ret = NULL; + + rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, sizeof(*rpc)); + if (IS_ERR_OR_NULL(rpc)) + return rpc; + + if (rpc->status) { + ret = ERR_PTR(r535_rpc_status_to_errno(rpc->status)); + if (PTR_ERR(ret) != -EAGAIN && PTR_ERR(ret) != -EBUSY) + nvkm_error(&gsp->subdev, "RM_ALLOC: 0x%x\n", rpc->status); + } + + nvkm_gsp_rpc_done(gsp, rpc); + + return ret; +} + +static void * +r535_gsp_rpc_rm_alloc_get(struct nvkm_gsp_object *object, u32 oclass, + u32 params_size) +{ + struct nvkm_gsp_client *client = object->client; + struct nvkm_gsp *gsp = client->gsp; + rpc_gsp_rm_alloc_v03_00 *rpc; + + nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x new obj:0x%08x\n", + client->object.handle, object->parent->handle, + object->handle); + + nvkm_debug(&gsp->subdev, "cls:0x%08x params_size:%d\n", oclass, + params_size); + + rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_ALLOC, + sizeof(*rpc) + params_size); + if (IS_ERR(rpc)) + return rpc; + + rpc->hClient = client->object.handle; + rpc->hParent = object->parent->handle; + rpc->hObject = object->handle; + rpc->hClass = oclass; + rpc->status = 0; + rpc->paramsSize = params_size; + return rpc->params; +} + +const struct nvkm_rm_api_alloc +r535_alloc = { + .get = r535_gsp_rpc_rm_alloc_get, + .push = r535_gsp_rpc_rm_alloc_push, + .done = r535_gsp_rpc_rm_alloc_done, + .free = r535_gsp_rpc_rm_free, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c index 90186f98065c..d06bf95b9a4a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "gf100.h" +#include <subdev/bar/gf100.h> #include <core/mm.h> #include <subdev/fb.h> @@ -27,14 +27,20 @@ #include <subdev/instmem.h> #include <subdev/mmu/vmm.h> -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/nvidia/generated/g_rpc-structures.h> -#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h> -#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_headers.h> +#include "nvrm/bar.h" +#include "nvrm/rpcfn.h" static void r535_bar_flush(struct nvkm_bar *bar) { + /* Use NV_PFLUSH in resume path - needed on R570 to flush writes before + * BAR2 page tables have been restored. + */ + if (unlikely(!bar->bar2)) { + g84_bar_flush(bar); + return; + } + ioread32_native(bar->flushBAR2); } @@ -44,7 +50,7 @@ r535_bar_bar2_wait(struct nvkm_bar *base) } static int -r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u64 addr) +r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u8 page_shift, u64 pdbe) { rpc_update_bar_pde_v15_00 *rpc; @@ -53,8 +59,8 @@ r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u64 addr) return -EIO; rpc->info.barType = NV_RPC_UPDATE_PDE_BAR_2; - rpc->info.entryValue = addr ? ((addr >> 4) | 2) : 0; /* PD3 entry format! */ - rpc->info.entryLevelShift = 47; //XXX: probably fetch this from mmu! + rpc->info.entryValue = pdbe; + rpc->info.entryLevelShift = page_shift; return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV); } @@ -62,12 +68,13 @@ r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u64 addr) static void r535_bar_bar2_fini(struct nvkm_bar *bar) { + struct nvkm_vmm *vmm = gf100_bar(bar)->bar[0].vmm; struct nvkm_gsp *gsp = bar->subdev.device->gsp; bar->flushBAR2 = bar->flushBAR2PhysMode; nvkm_done(bar->flushFBZero); - WARN_ON(r535_bar_bar2_update_pde(gsp, 0)); + WARN_ON(r535_bar_bar2_update_pde(gsp, vmm->func->page[0].shift, 0)); } static void @@ -76,8 +83,18 @@ r535_bar_bar2_init(struct nvkm_bar *bar) struct nvkm_device *device = bar->subdev.device; struct nvkm_vmm *vmm = gf100_bar(bar)->bar[0].vmm; struct nvkm_gsp *gsp = device->gsp; - - WARN_ON(r535_bar_bar2_update_pde(gsp, vmm->pd->pde[0]->pt[0]->addr)); + struct nvkm_memory *pdb = vmm->pd->pt[0]->memory; + u32 pdb_offset = vmm->pd->pt[0]->base; + u32 pdbe_lo, pdbe_hi; + u64 pdbe; + + nvkm_kmap(pdb); + pdbe_lo = nvkm_ro32(pdb, pdb_offset + 0); + pdbe_hi = nvkm_ro32(pdb, pdb_offset + 4); + pdbe = ((u64)pdbe_hi << 32) | pdbe_lo; + nvkm_done(pdb); + + WARN_ON(r535_bar_bar2_update_pde(gsp, vmm->func->page[0].shift, pdbe)); vmm->rm.bar2_pdb = gsp->bar.rm_bar2_pdb; if (!bar->flushFBZero) { @@ -174,7 +191,7 @@ r535_bar_new_(const struct nvkm_bar_func *hw, struct nvkm_device *device, } *pbar = bar; - bar->flushBAR2PhysMode = ioremap(device->func->resource_addr(device, 3), PAGE_SIZE); + bar->flushBAR2PhysMode = ioremap(device->func->resource_addr(device, NVKM_BAR2_INST), PAGE_SIZE); if (!bar->flushBAR2PhysMode) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c new file mode 100644 index 000000000000..2d1ce9db2dcf --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ce.c @@ -0,0 +1,46 @@ +/* + * Copyright 2023 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include <rm/engine.h> + +#include "nvrm/ce.h" +#include "nvrm/engine.h" + +static int +r535_ce_alloc(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *ce) +{ + NVC0B5_ALLOCATION_PARAMETERS *args; + + args = nvkm_gsp_rm_alloc_get(chan, handle, class, sizeof(*args), ce); + if (WARN_ON(IS_ERR(args))) + return PTR_ERR(args); + + args->version = 1; + args->engineType = NV2080_ENGINE_TYPE_COPY0 + inst; + + return nvkm_gsp_rm_alloc_wr(ce, args); +} + +const struct nvkm_rm_api_engine +r535_ce = { + .alloc = r535_ce_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c index 932934227b9c..ec71f683e609 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/client.c @@ -19,26 +19,27 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include <rm/rm.h> -#include <subdev/gsp.h> +#include "nvrm/client.h" -#include <nvif/class.h> +static int +r535_gsp_client_ctor(struct nvkm_gsp_client *client, u32 handle) +{ + NV0000_ALLOC_PARAMETERS *args; -static const struct nvkm_engine_func -ga100_nvdec = { - .sclass = { - { -1, -1, NVC6B0_VIDEO_DECODER }, - {} - } -}; + args = nvkm_gsp_rm_alloc_get(&client->object, handle, NV01_ROOT, sizeof(*args), + &client->object); + if (IS_ERR(args)) + return PTR_ERR(args); -int -ga100_nvdec_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_nvdec **pnvdec) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvdec_new(&ga100_nvdec, device, type, inst, pnvdec); + args->hClient = client->object.handle; + args->processID = ~0; - return -ENODEV; + return nvkm_gsp_rm_alloc_wr(&client->object, args); } + +const struct nvkm_rm_api_client +r535_client = { + .ctor = r535_gsp_client_ctor, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c new file mode 100644 index 000000000000..70b9ee911c5e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c @@ -0,0 +1,93 @@ +/* + * Copyright 2023 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include <rm/rpc.h> + +#include "nvrm/ctrl.h" +#include "nvrm/rpcfn.h" + +static void +r535_gsp_rpc_rm_ctrl_done(struct nvkm_gsp_object *object, void *params) +{ + rpc_gsp_rm_control_v03_00 *rpc = to_payload_hdr(params, rpc); + + if (!params) + return; + nvkm_gsp_rpc_done(object->client->gsp, rpc); +} + +static int +r535_gsp_rpc_rm_ctrl_push(struct nvkm_gsp_object *object, void **params, u32 repc) +{ + rpc_gsp_rm_control_v03_00 *rpc = to_payload_hdr((*params), rpc); + struct nvkm_gsp *gsp = object->client->gsp; + int ret = 0; + + rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, repc); + if (IS_ERR_OR_NULL(rpc)) { + *params = NULL; + return PTR_ERR(rpc); + } + + if (rpc->status) { + ret = r535_rpc_status_to_errno(rpc->status); + if (ret != -EAGAIN && ret != -EBUSY) + nvkm_error(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x failed: 0x%08x\n", + object->client->object.handle, object->handle, rpc->cmd, rpc->status); + } + + if (repc) + *params = rpc->params; + else + nvkm_gsp_rpc_done(gsp, rpc); + + return ret; +} + +static void * +r535_gsp_rpc_rm_ctrl_get(struct nvkm_gsp_object *object, u32 cmd, u32 params_size) +{ + struct nvkm_gsp_client *client = object->client; + struct nvkm_gsp *gsp = client->gsp; + rpc_gsp_rm_control_v03_00 *rpc; + + nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x params_size:%d\n", + client->object.handle, object->handle, cmd, params_size); + + rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_CONTROL, + sizeof(*rpc) + params_size); + if (IS_ERR(rpc)) + return rpc; + + rpc->hClient = client->object.handle; + rpc->hObject = object->handle; + rpc->cmd = cmd; + rpc->status = 0; + rpc->paramsSize = params_size; + return rpc->params; +} + +const struct nvkm_rm_api_ctrl +r535_ctrl = { + .get = r535_gsp_rpc_rm_ctrl_get, + .push = r535_gsp_rpc_rm_ctrl_push, + .done = r535_gsp_rpc_rm_ctrl_done, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c new file mode 100644 index 000000000000..f830e12a8f6e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/device.c @@ -0,0 +1,148 @@ +/* + * Copyright 2023 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include <rm/rm.h> + +#include "nvrm/device.h" +#include "nvrm/event.h" + +static void +r535_gsp_event_dtor(struct nvkm_gsp_event *event) +{ + struct nvkm_gsp_device *device = event->device; + struct nvkm_gsp_client *client = device->object.client; + struct nvkm_gsp *gsp = client->gsp; + + mutex_lock(&gsp->client_id.mutex); + if (event->func) { + list_del(&event->head); + event->func = NULL; + } + mutex_unlock(&gsp->client_id.mutex); + + nvkm_gsp_rm_free(&event->object); + event->device = NULL; +} + +static int +r535_gsp_device_event_get(struct nvkm_gsp_event *event) +{ + struct nvkm_gsp_device *device = event->device; + NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_get(&device->subdevice, + NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->event = event->id; + ctrl->action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT; + return nvkm_gsp_rm_ctrl_wr(&device->subdevice, ctrl); +} + +static int +r535_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id, + nvkm_gsp_event_func func, struct nvkm_gsp_event *event) +{ + struct nvkm_gsp_client *client = device->object.client; + struct nvkm_gsp *gsp = client->gsp; + NV0005_ALLOC_PARAMETERS *args; + int ret; + + args = nvkm_gsp_rm_alloc_get(&device->subdevice, handle, + NV01_EVENT_KERNEL_CALLBACK_EX, sizeof(*args), + &event->object); + if (IS_ERR(args)) + return PTR_ERR(args); + + args->hParentClient = client->object.handle; + args->hSrcResource = 0; + args->hClass = NV01_EVENT_KERNEL_CALLBACK_EX; + args->notifyIndex = NV01_EVENT_CLIENT_RM | id; + args->data = NULL; + + ret = nvkm_gsp_rm_alloc_wr(&event->object, args); + if (ret) + return ret; + + event->device = device; + event->id = id; + + ret = r535_gsp_device_event_get(event); + if (ret) { + nvkm_gsp_event_dtor(event); + return ret; + } + + mutex_lock(&gsp->client_id.mutex); + event->func = func; + list_add(&event->head, &client->events); + mutex_unlock(&gsp->client_id.mutex); + return 0; +} + +static void +r535_gsp_device_dtor(struct nvkm_gsp_device *device) +{ + nvkm_gsp_rm_free(&device->subdevice); + nvkm_gsp_rm_free(&device->object); +} + +static int +r535_gsp_subdevice_ctor(struct nvkm_gsp_device *device) +{ + NV2080_ALLOC_PARAMETERS *args; + + return nvkm_gsp_rm_alloc(&device->object, NVKM_RM_SUBDEVICE, NV20_SUBDEVICE_0, + sizeof(*args), &device->subdevice); +} + +static int +r535_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device) +{ + NV0080_ALLOC_PARAMETERS *args; + int ret; + + args = nvkm_gsp_rm_alloc_get(&client->object, NVKM_RM_DEVICE, NV01_DEVICE_0, sizeof(*args), + &device->object); + if (IS_ERR(args)) + return PTR_ERR(args); + + args->hClientShare = client->object.handle; + + ret = nvkm_gsp_rm_alloc_wr(&device->object, args); + if (ret) + return ret; + + ret = r535_gsp_subdevice_ctor(device); + if (ret) + nvkm_gsp_rm_free(&device->object); + + return ret; +} + +const struct nvkm_rm_api_device +r535_device = { + .ctor = r535_gsp_device_ctor, + .dtor = r535_gsp_device_dtor, + .event.ctor = r535_gsp_device_event_ctor, + .event.dtor = r535_gsp_event_dtor, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c index 99110ab2f44d..7e9e2d3564da 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c @@ -19,13 +19,13 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" -#include "chan.h" -#include "conn.h" -#include "dp.h" -#include "head.h" -#include "ior.h" -#include "outp.h" +#include <engine/disp/priv.h> +#include <engine/disp/chan.h> +#include <engine/disp/conn.h> +#include <engine/disp/dp.h> +#include <engine/disp/head.h> +#include <engine/disp/ior.h> +#include <engine/disp/outp.h> #include <core/ramht.h> #include <subdev/bios.h> @@ -34,19 +34,11 @@ #include <subdev/mmu.h> #include <subdev/vfn.h> +#include <rm/gpu.h> + #include <nvhw/drf.h> -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080_notification.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dfp.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073dp.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073specific.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0073/ctrl0073system.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080internal.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h> -#include <nvrm/535.113.01/nvidia/generated/g_allclasses.h> -#include <nvrm/535.113.01/nvidia/generated/g_mem_desc_nvoc.h> -#include <nvrm/535.113.01/nvidia/inc/kernel/os/nv_memory_type.h> +#include "nvrm/disp.h" #include <linux/acpi.h> @@ -78,9 +70,9 @@ r535_chan_fini(struct nvkm_disp_chan *chan) } static int -r535_chan_push(struct nvkm_disp_chan *chan) +r535_disp_chan_set_pushbuf(struct nvkm_disp *disp, s32 oclass, int inst, struct nvkm_memory *memory) { - struct nvkm_gsp *gsp = chan->disp->engine.subdev.device->gsp; + struct nvkm_gsp *gsp = disp->rm.objcom.client->gsp; NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS *ctrl; ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice, @@ -89,8 +81,8 @@ r535_chan_push(struct nvkm_disp_chan *chan) if (IS_ERR(ctrl)) return PTR_ERR(ctrl); - if (chan->memory) { - switch (nvkm_memory_target(chan->memory)) { + if (memory) { + switch (nvkm_memory_target(memory)) { case NVKM_MEM_TARGET_NCOH: ctrl->addressSpace = ADDR_SYSMEM; ctrl->cacheSnoop = 0; @@ -107,13 +99,13 @@ r535_chan_push(struct nvkm_disp_chan *chan) return -EINVAL; } - ctrl->physicalAddr = nvkm_memory_addr(chan->memory); - ctrl->limit = nvkm_memory_size(chan->memory) - 1; + ctrl->physicalAddr = nvkm_memory_addr(memory); + ctrl->limit = nvkm_memory_size(memory) - 1; } - ctrl->hclass = chan->object.oclass; - ctrl->channelInstance = chan->head; - ctrl->valid = ((chan->object.oclass & 0xff) != 0x7a) ? 1 : 0; + ctrl->hclass = oclass; + ctrl->channelInstance = inst; + ctrl->valid = ((oclass & 0xff) != 0x7a) ? 1 : 0; return nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl); } @@ -121,10 +113,11 @@ r535_chan_push(struct nvkm_disp_chan *chan) static int r535_curs_init(struct nvkm_disp_chan *chan) { + const struct nvkm_rm_api *rmapi = chan->disp->rm.objcom.client->gsp->rm->api; NV50VAIO_CHANNELPIO_ALLOCATION_PARAMETERS *args; int ret; - ret = r535_chan_push(chan); + ret = rmapi->disp->chan.set_pushbuf(chan->disp, chan->object.oclass, chan->head, NULL); if (ret) return ret; @@ -172,25 +165,34 @@ r535_dmac_fini(struct nvkm_disp_chan *chan) } static int -r535_dmac_init(struct nvkm_disp_chan *chan) +r535_dmac_alloc(struct nvkm_disp *disp, u32 oclass, int inst, u32 put_offset, + struct nvkm_gsp_object *dmac) { NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS *args; - int ret; - - ret = r535_chan_push(chan); - if (ret) - return ret; - args = nvkm_gsp_rm_alloc_get(&chan->disp->rm.object, - (chan->object.oclass << 16) | chan->head, - chan->object.oclass, sizeof(*args), &chan->rm.object); + args = nvkm_gsp_rm_alloc_get(&disp->rm.object, (oclass << 16) | inst, oclass, + sizeof(*args), dmac); if (IS_ERR(args)) return PTR_ERR(args); - args->channelInstance = chan->head; - args->offset = chan->suspend_put; + args->channelInstance = inst; + args->offset = put_offset; - return nvkm_gsp_rm_alloc_wr(&chan->rm.object, args); + return nvkm_gsp_rm_alloc_wr(dmac, args); +} + +static int +r535_dmac_init(struct nvkm_disp_chan *chan) +{ + const struct nvkm_rm_api *rmapi = chan->disp->rm.objcom.client->gsp->rm->api; + int ret; + + ret = rmapi->disp->chan.set_pushbuf(chan->disp, chan->object.oclass, chan->head, chan->memory); + if (ret) + return ret; + + return rmapi->disp->chan.dmac_alloc(chan->disp, chan->object.oclass, chan->head, + chan->suspend_put, &chan->rm.object); } static int @@ -260,47 +262,47 @@ r535_core = { }; static int -r535_sor_bl_set(struct nvkm_ior *sor, int lvl) +r535_bl_ctrl(struct nvkm_disp *disp, unsigned display_id, bool set, int *pval) { - struct nvkm_disp *disp = sor->disp; + u32 cmd = set ? NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS : + NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS; NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS *ctrl; + int ret; - ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, - NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS, - sizeof(*ctrl)); + ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, cmd, sizeof(*ctrl)); if (IS_ERR(ctrl)) return PTR_ERR(ctrl); - ctrl->displayId = BIT(sor->asy.outp->index); - ctrl->brightness = lvl; + ctrl->displayId = BIT(display_id); + ctrl->brightness = *pval; - return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl); + ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); + if (ret) + return ret; + + *pval = ctrl->brightness; + + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return 0; } static int -r535_sor_bl_get(struct nvkm_ior *sor) +r535_sor_bl_set(struct nvkm_ior *sor, int lvl) { struct nvkm_disp *disp = sor->disp; - NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS *ctrl; - int ret, lvl; - - ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, - NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS, - sizeof(*ctrl)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); + const struct nvkm_rm_api *rmapi = disp->engine.subdev.device->gsp->rm->api; - ctrl->displayId = BIT(sor->asy.outp->index); + return rmapi->disp->bl_ctrl(disp, sor->asy.outp->index, true, &lvl); +} - ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); - if (ret) { - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); - return ret; - } +static int +r535_sor_bl_get(struct nvkm_ior *sor) +{ + struct nvkm_disp *disp = sor->disp; + const struct nvkm_rm_api *rmapi = disp->engine.subdev.device->gsp->rm->api; + int lvl, ret = rmapi->disp->bl_ctrl(disp, sor->asy.outp->index, false, &lvl); - lvl = ctrl->brightness; - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); - return lvl; + return (ret == 0) ? lvl : ret; } static const struct nvkm_ior_func_bl @@ -730,7 +732,7 @@ r535_outp_acquire(struct nvkm_outp *outp, bool hda) } static int -r535_disp_head_displayid(struct nvkm_disp *disp, int head, u32 *displayid) +r535_disp_get_active(struct nvkm_disp *disp, unsigned head, u32 *displayid) { NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS *ctrl; int ret; @@ -763,7 +765,9 @@ r535_outp_inherit(struct nvkm_outp *outp) int ret; list_for_each_entry(head, &disp->heads, head) { - ret = r535_disp_head_displayid(disp, head->id, &displayid); + const struct nvkm_rm_api *rmapi = disp->rm.objcom.client->gsp->rm->api; + + ret = rmapi->disp->get_active(disp, head->id, &displayid); if (WARN_ON(ret)) return NULL; @@ -858,10 +862,9 @@ r535_outp_dfp_get_info(struct nvkm_outp *outp) } static int -r535_outp_detect(struct nvkm_outp *outp) +r535_disp_get_connect_state(struct nvkm_disp *disp, unsigned display_id) { NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS *ctrl; - struct nvkm_disp *disp = outp->disp; int ret; ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, @@ -870,23 +873,29 @@ r535_outp_detect(struct nvkm_outp *outp) return PTR_ERR(ctrl); ctrl->subDeviceInstance = 0; - ctrl->displayMask = BIT(outp->index); + ctrl->displayMask = BIT(display_id); ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); - if (ret) { - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); - return ret; - } + if (ret == 0 && (ctrl->displayMask & BIT(display_id))) + ret = 1; + + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return ret; +} - if (ctrl->displayMask & BIT(outp->index)) { +static int +r535_outp_detect(struct nvkm_outp *outp) +{ + const struct nvkm_rm_api *rmapi = outp->disp->rm.objcom.client->gsp->rm->api; + int ret; + + ret = rmapi->disp->get_connect_state(outp->disp, outp->index); + if (ret == 1) { ret = r535_outp_dfp_get_info(outp); if (ret == 0) ret = 1; - } else { - ret = 0; } - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); return ret; } @@ -1029,15 +1038,11 @@ r535_dp_train(struct nvkm_outp *outp, bool retrain) } static int -r535_dp_rates(struct nvkm_outp *outp) +r535_dp_set_indexed_link_rates(struct nvkm_outp *outp) { NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS *ctrl; struct nvkm_disp *disp = outp->disp; - if (outp->conn->info.type != DCB_CONNECTOR_eDP || - !outp->dp.rates || outp->dp.rate[0].dpcd < 0) - return 0; - if (WARN_ON(outp->dp.rates > ARRAY_SIZE(ctrl->linkRateTbl))) return -EINVAL; @@ -1054,6 +1059,18 @@ r535_dp_rates(struct nvkm_outp *outp) } static int +r535_dp_rates(struct nvkm_outp *outp) +{ + struct nvkm_rm *rm = outp->disp->rm.objcom.client->gsp->rm; + + if (outp->conn->info.type != DCB_CONNECTOR_eDP || + !outp->dp.rates || outp->dp.rate[0].dpcd < 0) + return 0; + + return rm->api->disp->dp.set_indexed_link_rates(outp); +} + +static int r535_dp_aux_xfer(struct nvkm_outp *outp, u8 type, u32 addr, u8 *data, u8 *psize) { struct nvkm_disp *disp = outp->disp; @@ -1151,6 +1168,49 @@ r535_dp = { }; static int +r535_dp_get_caps(struct nvkm_disp *disp, int *plink_bw, bool *pmst, bool *pwm) +{ + NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS *ctrl; + int ret; + + ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, + NV0073_CTRL_CMD_DP_GET_CAPS, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->sorIndex = ~0; + + ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); + if (ret) { + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return ret; + } + + switch (NVVAL_GET(ctrl->maxLinkRate, NV0073_CTRL_CMD, DP_GET_CAPS, MAX_LINK_RATE)) { + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62: + *plink_bw = 0x06; + break; + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70: + *plink_bw = 0x0a; + break; + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40: + *plink_bw = 0x14; + break; + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10: + *plink_bw = 0x1e; + break; + default: + *plink_bw = 0x00; + break; + } + + *pmst = ctrl->bIsMultistreamSupported; + *pwm = ctrl->bHasIncreasedWatermarkLimits; + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return 0; +} + +static int r535_tmds_edid_get(struct nvkm_outp *outp, u8 *data, u16 *psize) { NV0073_CTRL_SPECIFIC_GET_EDID_V2_PARAMS *ctrl; @@ -1194,6 +1254,7 @@ r535_tmds = { static int r535_outp_new(struct nvkm_disp *disp, u32 id) { + const struct nvkm_rm_api *rmapi = disp->rm.objcom.client->gsp->rm->api; NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS *ctrl; enum nvkm_ior_proto proto; struct dcb_output dcbE = {}; @@ -1278,43 +1339,11 @@ r535_outp_new(struct nvkm_disp *disp, u32 id) if (ret) return ret; } else { - NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS *ctrl; bool mst, wm; - ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, - NV0073_CTRL_CMD_DP_GET_CAPS, sizeof(*ctrl)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); - - ctrl->sorIndex = ~0; - - ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); - if (ret) { - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + ret = rmapi->disp->dp.get_caps(disp, &dcbE.dpconf.link_bw, &mst, &wm); + if (ret) return ret; - } - - switch (NVVAL_GET(ctrl->maxLinkRate, NV0073_CTRL_CMD, DP_GET_CAPS, MAX_LINK_RATE)) { - case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62: - dcbE.dpconf.link_bw = 0x06; - break; - case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70: - dcbE.dpconf.link_bw = 0x0a; - break; - case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40: - dcbE.dpconf.link_bw = 0x14; - break; - case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10: - dcbE.dpconf.link_bw = 0x1e; - break; - default: - dcbE.dpconf.link_bw = 0x00; - break; - } - - mst = ctrl->bIsMultistreamSupported; - wm = ctrl->bHasIncreasedWatermarkLimits; - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); if (WARN_ON(!dcbE.dpconf.link_bw)) return -EINVAL; @@ -1441,11 +1470,47 @@ r535_disp_init(struct nvkm_disp *disp) } static int +r535_disp_get_supported(struct nvkm_disp *disp, unsigned long *pmask) +{ + NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom, + NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + *pmask = ctrl->displayMask; + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return 0; +} + +static int +r535_disp_get_static_info(struct nvkm_disp *disp) +{ + NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS *ctrl; + struct nvkm_gsp *gsp = disp->rm.objcom.client->gsp; + + ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO, + sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + disp->wndw.mask = ctrl->windowPresentMask; + disp->wndw.nr = fls(disp->wndw.mask); + + nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); + return 0; +} + +static int r535_disp_oneinit(struct nvkm_disp *disp) { struct nvkm_device *device = disp->engine.subdev.device; struct nvkm_gsp *gsp = device->gsp; + const struct nvkm_rm_api *rmapi = gsp->rm->api; NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS *ctrl; + unsigned long mask; int ret, i; /* RAMIN. */ @@ -1476,24 +1541,14 @@ r535_disp_oneinit(struct nvkm_disp *disp) if (ret) return ret; - ret = nvkm_gsp_rm_alloc(&disp->rm.device.object, 0x00730000, NV04_DISPLAY_COMMON, 0, + ret = nvkm_gsp_rm_alloc(&disp->rm.device.object, NVKM_RM_DISP, NV04_DISPLAY_COMMON, 0, &disp->rm.objcom); if (ret) return ret; - { - NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS *ctrl; - - ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, - NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO, - sizeof(*ctrl)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); - - disp->wndw.mask = ctrl->windowPresentMask; - disp->wndw.nr = fls(disp->wndw.mask); - nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); - } + ret = rmapi->disp->get_static_info(disp); + if (ret) + return ret; /* */ { @@ -1622,25 +1677,14 @@ r535_disp_oneinit(struct nvkm_disp *disp) return ret; } - /* */ - { - NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS *ctrl; - unsigned long mask; - int i; - - ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom, - NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED, sizeof(*ctrl)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); - - mask = ctrl->displayMask; - nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + ret = rmapi->disp->get_supported(disp, &mask); + if (ret) + return ret; - for_each_set_bit(i, &mask, 32) { - ret = r535_outp_new(disp, i); - if (ret) - return ret; - } + for_each_set_bit(i, &mask, 32) { + ret = r535_outp_new(disp, i); + if (ret) + return ret; } ret = nvkm_event_init(&r535_disp_event, &gsp->subdev, 3, 32, &disp->rm.event); @@ -1686,6 +1730,7 @@ int r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_disp **pdisp) { + const struct nvkm_rm_gpu *gpu = device->gsp->rm->gpu; struct nvkm_disp_func *rm; int ret; @@ -1701,20 +1746,26 @@ r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device, rm->sor.new = r535_sor_new; rm->ramht_size = hw->ramht_size; - rm->root = hw->root; + rm->root.oclass = gpu->disp.class.root; - for (int i = 0; hw->user[i].ctor; i++) { - switch (hw->user[i].base.oclass & 0xff) { - case 0x73: rm->user[i] = hw->user[i]; break; - case 0x7d: rm->user[i] = hw->user[i]; rm->user[i].chan = &r535_core; break; - case 0x7e: rm->user[i] = hw->user[i]; rm->user[i].chan = &r535_wndw; break; - case 0x7b: rm->user[i] = hw->user[i]; rm->user[i].chan = &r535_wimm; break; - case 0x7a: rm->user[i] = hw->user[i]; rm->user[i].chan = &r535_curs; break; - default: - WARN_ON(1); - continue; - } - } + rm->user[0].base.oclass = gpu->disp.class.caps; + rm->user[0].ctor = gv100_disp_caps_new; + + rm->user[1].base.oclass = gpu->disp.class.core; + rm->user[1].ctor = nvkm_disp_core_new; + rm->user[1].chan = &r535_core; + + rm->user[2].base.oclass = gpu->disp.class.wndw; + rm->user[2].ctor = nvkm_disp_wndw_new; + rm->user[2].chan = &r535_wndw; + + rm->user[3].base.oclass = gpu->disp.class.wimm; + rm->user[3].ctor = nvkm_disp_wndw_new; + rm->user[3].chan = &r535_wimm; + + rm->user[4].base.oclass = gpu->disp.class.curs; + rm->user[4].ctor = nvkm_disp_chan_new; + rm->user[4].chan = &r535_curs; ret = nvkm_disp_new_(rm, device, type, inst, pdisp); if (ret) @@ -1723,3 +1774,20 @@ r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device, mutex_init(&(*pdisp)->super.mutex); //XXX return ret; } + +const struct nvkm_rm_api_disp +r535_disp = { + .get_static_info = r535_disp_get_static_info, + .get_supported = r535_disp_get_supported, + .get_connect_state = r535_disp_get_connect_state, + .get_active = r535_disp_get_active, + .bl_ctrl = r535_bl_ctrl, + .dp = { + .get_caps = r535_dp_get_caps, + .set_indexed_link_rates = r535_dp_set_indexed_link_rates, + }, + .chan = { + .set_pushbuf = r535_disp_chan_set_pushbuf, + .dmac_alloc = r535_dmac_alloc, + } +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c index 35ba1798ee6e..150e22fde2ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c @@ -19,19 +19,13 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" - +#include <subdev/instmem/priv.h> #include <subdev/gsp.h> #include <nvhw/drf.h> -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl84a0.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080internal.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h> -#include <nvrm/535.113.01/nvidia/generated/g_fbsr_nvoc.h> -#include <nvrm/535.113.01/nvidia/generated/g_rpc-structures.h> -#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h> +#include "nvrm/fbsr.h" +#include "nvrm/rpcfn.h" struct fbsr_item { const char *type; @@ -54,9 +48,9 @@ struct fbsr { u64 sys_offset; }; -static int -fbsr_memlist(struct nvkm_gsp_device *device, u32 handle, enum nvkm_memory_target aper, - u64 phys, u64 size, struct sg_table *sgt, struct nvkm_gsp_object *object) +int +r535_fbsr_memlist(struct nvkm_gsp_device *device, u32 handle, enum nvkm_memory_target aper, + u64 phys, u64 size, struct sg_table *sgt, struct nvkm_gsp_object *object) { struct nvkm_gsp_client *client = device->object.client; struct nvkm_gsp *gsp = client->gsp; @@ -123,8 +117,8 @@ fbsr_send(struct fbsr *fbsr, struct fbsr_item *item) struct nvkm_gsp_object memlist; int ret; - ret = fbsr_memlist(&fbsr->device, fbsr->hmemory, NVKM_MEM_TARGET_VRAM, - item->addr, item->size, NULL, &memlist); + ret = r535_fbsr_memlist(&fbsr->device, fbsr->hmemory, NVKM_MEM_TARGET_VRAM, + item->addr, item->size, NULL, &memlist); if (ret) return ret; @@ -161,8 +155,8 @@ fbsr_init(struct fbsr *fbsr, struct sg_table *sgt, u64 items_size) struct nvkm_gsp_object memlist; int ret; - ret = fbsr_memlist(&fbsr->device, fbsr->hmemory, NVKM_MEM_TARGET_HOST, - 0, fbsr->size, sgt, &memlist); + ret = r535_fbsr_memlist(&fbsr->device, fbsr->hmemory, NVKM_MEM_TARGET_HOST, + 0, fbsr->size, sgt, &memlist); if (ret) return ret; @@ -206,22 +200,19 @@ fbsr_inst(struct fbsr *fbsr, const char *type, struct nvkm_memory *memory) return fbsr_vram(fbsr, type, nvkm_memory_addr(memory), nvkm_memory_size(memory)); } -static void -r535_instmem_resume(struct nvkm_instmem *imem) +void +r535_fbsr_resume(struct nvkm_gsp *gsp) { /* RM has restored VRAM contents already, so just need to free the sysmem buffer. */ - if (imem->rm.fbsr_valid) { - nvkm_gsp_sg_free(imem->subdev.device, &imem->rm.fbsr); - imem->rm.fbsr_valid = false; - } + nvkm_gsp_sg_free(gsp->subdev.device, &gsp->sr.fbsr); } static int -r535_instmem_suspend(struct nvkm_instmem *imem) +r535_fbsr_suspend(struct nvkm_gsp *gsp) { - struct nvkm_subdev *subdev = &imem->subdev; + struct nvkm_subdev *subdev = &gsp->subdev; struct nvkm_device *device = subdev->device; - struct nvkm_gsp *gsp = device->gsp; + struct nvkm_instmem *imem = device->imem; struct nvkm_instobj *iobj; struct fbsr fbsr = {}; struct fbsr_item *item, *temp; @@ -262,7 +253,7 @@ r535_instmem_suspend(struct nvkm_instmem *imem) fbsr.size += gsp->fb.bios.vga_workspace.size; nvkm_debug(subdev, "fbsr: size: 0x%llx bytes\n", fbsr.size); - ret = nvkm_gsp_sg(gsp->subdev.device, fbsr.size, &imem->rm.fbsr); + ret = nvkm_gsp_sg(gsp->subdev.device, fbsr.size, &gsp->sr.fbsr); if (ret) goto done; @@ -271,7 +262,7 @@ r535_instmem_suspend(struct nvkm_instmem *imem) if (ret) goto done_sgt; - ret = fbsr_init(&fbsr, &imem->rm.fbsr, items_size); + ret = fbsr_init(&fbsr, &gsp->sr.fbsr, items_size); if (WARN_ON(ret)) goto done_sgt; @@ -282,12 +273,10 @@ r535_instmem_suspend(struct nvkm_instmem *imem) goto done_sgt; } - imem->rm.fbsr_valid = true; - /* Cleanup everything except the sysmem backup, which will be removed after resume. */ done_sgt: if (ret) /* ... unless we failed already. */ - nvkm_gsp_sg_free(device, &imem->rm.fbsr); + nvkm_gsp_sg_free(device, &gsp->sr.fbsr); done: list_for_each_entry_safe(item, temp, &fbsr.items, head) { list_del(&item->head); @@ -299,6 +288,12 @@ done: return ret; } +const struct nvkm_rm_api_fbsr +r535_fbsr = { + .suspend = r535_fbsr_suspend, + .resume = r535_fbsr_resume, +}; + static void * r535_instmem_dtor(struct nvkm_instmem *imem) { @@ -319,11 +314,10 @@ r535_instmem_new(const struct nvkm_instmem_func *hw, rm->dtor = r535_instmem_dtor; rm->fini = hw->fini; - rm->suspend = r535_instmem_suspend; - rm->resume = r535_instmem_resume; rm->memory_new = hw->memory_new; rm->memory_wrap = hw->memory_wrap; rm->zero = false; + rm->set_bar0_window_addr = hw->set_bar0_window_addr; ret = nv50_instmem_new_(rm, device, type, inst, pinstmem); if (ret) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 3454c7d29502..1ac5628c5140 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -19,11 +19,11 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" -#include "cgrp.h" -#include "chan.h" -#include "chid.h" -#include "runl.h" +#include <engine/fifo/priv.h> +#include <engine/fifo/cgrp.h> +#include <engine/fifo/chan.h> +#include <engine/fifo/chid.h> +#include <engine/fifo/runl.h> #include <core/gpuobj.h> #include <subdev/gsp.h> @@ -31,24 +31,19 @@ #include <subdev/vfn.h> #include <engine/gr.h> +#include <rm/engine.h> + #include <nvhw/drf.h> -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/alloc/alloc_channel.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080_notification.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080ce.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080fifo.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080internal.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrla06f/ctrla06fgpfifo.h> -#include <nvrm/535.113.01/nvidia/generated/g_kernel_channel_nvoc.h> -#include <nvrm/535.113.01/nvidia/generated/g_kernel_fifo_nvoc.h> -#include <nvrm/535.113.01/nvidia/inc/kernel/gpu/gpu_engine_type.h> +#include "nvrm/fifo.h" +#include "nvrm/engine.h" static u32 r535_chan_doorbell_handle(struct nvkm_chan *chan) { - return (chan->cgrp->runl->id << 16) | chan->id; + struct nvkm_gsp *gsp = chan->rm.object.client->gsp; + + return gsp->rm->gpu->fifo.chan.doorbell_handle(chan); } static void @@ -77,50 +72,29 @@ r535_chan_ramfc_clear(struct nvkm_chan *chan) #define CHID_PER_USERD 8 static int -r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv) +r535_chan_alloc(struct nvkm_gsp_device *device, u32 handle, u32 nv2080_engine_type, u8 runq, + bool priv, int chid, u64 inst_addr, u64 userd_addr, u64 mthdbuf_addr, + struct nvkm_vmm *vmm, u64 gpfifo_offset, u32 gpfifo_length, + struct nvkm_gsp_object *chan) { - struct nvkm_fifo *fifo = chan->cgrp->runl->fifo; - struct nvkm_engn *engn; - struct nvkm_device *device = fifo->engine.subdev.device; + struct nvkm_gsp *gsp = device->object.client->gsp; + struct nvkm_fifo *fifo = gsp->subdev.device->fifo; + const int userd_p = chid / CHID_PER_USERD; + const int userd_i = chid % CHID_PER_USERD; NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS *args; - const int userd_p = chan->id / CHID_PER_USERD; - const int userd_i = chan->id % CHID_PER_USERD; - u32 eT = ~0; - int ret; - - if (unlikely(device->gr && !device->gr->engine.subdev.oneinit)) { - ret = nvkm_subdev_oneinit(&device->gr->engine.subdev); - if (ret) - return ret; - } - - nvkm_runl_foreach_engn(engn, chan->cgrp->runl) { - eT = engn->id; - break; - } - - if (WARN_ON(eT == ~0)) - return -EINVAL; - chan->rm.mthdbuf.ptr = dma_alloc_coherent(fifo->engine.subdev.device->dev, - fifo->rm.mthdbuf_size, - &chan->rm.mthdbuf.addr, GFP_KERNEL); - if (!chan->rm.mthdbuf.ptr) - return -ENOMEM; - - args = nvkm_gsp_rm_alloc_get(&chan->vmm->rm.device.object, 0xf1f00000 | chan->id, - fifo->func->chan.user.oclass, sizeof(*args), - &chan->rm.object); + args = nvkm_gsp_rm_alloc_get(&device->object, handle, + fifo->func->chan.user.oclass, sizeof(*args), chan); if (WARN_ON(IS_ERR(args))) return PTR_ERR(args); - args->gpFifoOffset = offset; - args->gpFifoEntries = length / 8; + args->gpFifoOffset = gpfifo_offset; + args->gpFifoEntries = gpfifo_length / 8; args->flags = NVDEF(NVOS04, FLAGS, CHANNEL_TYPE, PHYSICAL); args->flags |= NVDEF(NVOS04, FLAGS, VPR, FALSE); args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_SKIP_MAP_REFCOUNTING, FALSE); - args->flags |= NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, chan->runq); + args->flags |= NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, runq); if (!priv) args->flags |= NVDEF(NVOS04, FLAGS, PRIVILEGED_CHANNEL, FALSE); else @@ -143,25 +117,25 @@ r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, args->flags |= NVDEF(NVOS04, FLAGS, MAP_CHANNEL, FALSE); args->flags |= NVDEF(NVOS04, FLAGS, SKIP_CTXBUFFER_ALLOC, FALSE); - args->hVASpace = chan->vmm->rm.object.handle; - args->engineType = eT; + args->hVASpace = vmm->rm.object.handle; + args->engineType = nv2080_engine_type; - args->instanceMem.base = chan->inst->addr; - args->instanceMem.size = chan->inst->size; + args->instanceMem.base = inst_addr; + args->instanceMem.size = fifo->func->chan.func->inst->size; args->instanceMem.addressSpace = 2; args->instanceMem.cacheAttrib = 1; - args->userdMem.base = nvkm_memory_addr(chan->userd.mem) + chan->userd.base; + args->userdMem.base = userd_addr; args->userdMem.size = fifo->func->chan.func->userd->size; args->userdMem.addressSpace = 2; args->userdMem.cacheAttrib = 1; - args->ramfcMem.base = chan->inst->addr + 0; + args->ramfcMem.base = inst_addr; args->ramfcMem.size = 0x200; args->ramfcMem.addressSpace = 2; args->ramfcMem.cacheAttrib = 1; - args->mthdbufMem.base = chan->rm.mthdbuf.addr; + args->mthdbufMem.base = mthdbuf_addr; args->mthdbufMem.size = fifo->rm.mthdbuf_size; args->mthdbufMem.addressSpace = 1; args->mthdbufMem.cacheAttrib = 0; @@ -173,7 +147,44 @@ r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, args->internalFlags |= NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, ERROR_NOTIFIER_TYPE, NONE); args->internalFlags |= NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, ECC_ERROR_NOTIFIER_TYPE, NONE); - ret = nvkm_gsp_rm_alloc_wr(&chan->rm.object, args); + return nvkm_gsp_rm_alloc_wr(chan, args); +} + +static int +r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv) +{ + struct nvkm_fifo *fifo = chan->cgrp->runl->fifo; + struct nvkm_engn *engn; + struct nvkm_device *device = fifo->engine.subdev.device; + const struct nvkm_rm_api *rmapi = device->gsp->rm->api; + u32 eT = ~0; + int ret; + + if (unlikely(device->gr && !device->gr->engine.subdev.oneinit)) { + ret = nvkm_subdev_oneinit(&device->gr->engine.subdev); + if (ret) + return ret; + } + + nvkm_runl_foreach_engn(engn, chan->cgrp->runl) { + eT = engn->id; + break; + } + + if (WARN_ON(eT == ~0)) + return -EINVAL; + + chan->rm.mthdbuf.ptr = dma_alloc_coherent(fifo->engine.subdev.device->dev, + fifo->rm.mthdbuf_size, + &chan->rm.mthdbuf.addr, GFP_KERNEL); + if (!chan->rm.mthdbuf.ptr) + return -ENOMEM; + + ret = rmapi->fifo->chan.alloc(&chan->vmm->rm.device, NVKM_RM_CHAN(chan->id), + eT, chan->runq, priv, chan->id, chan->inst->addr, + nvkm_memory_addr(chan->userd.mem) + chan->userd.base, + chan->rm.mthdbuf.addr, chan->vmm, offset, length, + &chan->rm.object); if (ret) return ret; @@ -215,123 +226,8 @@ r535_chan_ramfc = { .priv = true, }; -struct r535_chan_userd { - struct nvkm_memory *mem; - struct nvkm_memory *map; - int chid; - u32 used; - - struct list_head head; -} *userd; - -static void -r535_chan_id_put(struct nvkm_chan *chan) -{ - struct nvkm_runl *runl = chan->cgrp->runl; - struct nvkm_fifo *fifo = runl->fifo; - struct r535_chan_userd *userd; - - mutex_lock(&fifo->userd.mutex); - list_for_each_entry(userd, &fifo->userd.list, head) { - if (userd->map == chan->userd.mem) { - u32 chid = chan->userd.base / chan->func->userd->size; - - userd->used &= ~BIT(chid); - if (!userd->used) { - nvkm_memory_unref(&userd->map); - nvkm_memory_unref(&userd->mem); - nvkm_chid_put(runl->chid, userd->chid, &chan->cgrp->lock); - list_del(&userd->head); - kfree(userd); - } - - break; - } - } - mutex_unlock(&fifo->userd.mutex); - -} - -static int -r535_chan_id_get_locked(struct nvkm_chan *chan, struct nvkm_memory *muserd, u64 ouserd) -{ - const u32 userd_size = CHID_PER_USERD * chan->func->userd->size; - struct nvkm_runl *runl = chan->cgrp->runl; - struct nvkm_fifo *fifo = runl->fifo; - struct r535_chan_userd *userd; - u32 chid; - int ret; - - if (ouserd + chan->func->userd->size >= userd_size || - (ouserd & (chan->func->userd->size - 1))) { - RUNL_DEBUG(runl, "ouserd %llx", ouserd); - return -EINVAL; - } - - chid = div_u64(ouserd, chan->func->userd->size); - - list_for_each_entry(userd, &fifo->userd.list, head) { - if (userd->mem == muserd) { - if (userd->used & BIT(chid)) - return -EBUSY; - break; - } - } - - if (&userd->head == &fifo->userd.list) { - if (nvkm_memory_size(muserd) < userd_size) { - RUNL_DEBUG(runl, "userd too small"); - return -EINVAL; - } - - userd = kzalloc(sizeof(*userd), GFP_KERNEL); - if (!userd) - return -ENOMEM; - - userd->chid = nvkm_chid_get(runl->chid, chan); - if (userd->chid < 0) { - ret = userd->chid; - kfree(userd); - return ret; - } - - userd->mem = nvkm_memory_ref(muserd); - - ret = nvkm_memory_kmap(userd->mem, &userd->map); - if (ret) { - nvkm_chid_put(runl->chid, userd->chid, &chan->cgrp->lock); - kfree(userd); - return ret; - } - - - list_add(&userd->head, &fifo->userd.list); - } - - userd->used |= BIT(chid); - - chan->userd.mem = nvkm_memory_ref(userd->map); - chan->userd.base = ouserd; - - return (userd->chid * CHID_PER_USERD) + chid; -} - -static int -r535_chan_id_get(struct nvkm_chan *chan, struct nvkm_memory *muserd, u64 ouserd) -{ - struct nvkm_fifo *fifo = chan->cgrp->runl->fifo; - int ret; - - mutex_lock(&fifo->userd.mutex); - ret = r535_chan_id_get_locked(chan, muserd, ouserd); - mutex_unlock(&fifo->userd.mutex); - return ret; -} - static const struct nvkm_chan_func r535_chan = { - .id_get = r535_chan_id_get, - .id_put = r535_chan_id_put, .inst = &gf100_chan_inst, .userd = &gv100_chan_userd, .ramfc = &r535_chan_ramfc, @@ -340,10 +236,6 @@ r535_chan = { .doorbell_handle = r535_chan_doorbell_handle, }; -static const struct nvkm_cgrp_func -r535_cgrp = { -}; - static int r535_engn_nonstall(struct nvkm_engn *engn) { @@ -356,7 +248,7 @@ r535_engn_nonstall(struct nvkm_engn *engn) } static const struct nvkm_engn_func -r535_ce = { +r535_engn_ce = { .nonstall = r535_engn_nonstall, }; @@ -376,7 +268,7 @@ r535_gr_ctor(struct nvkm_engn *engn, struct nvkm_vctx *vctx, struct nvkm_chan *c } static const struct nvkm_engn_func -r535_gr = { +r535_engn_gr = { .nonstall = r535_engn_nonstall, .ctor2 = r535_gr_ctor, }; @@ -449,57 +341,86 @@ r535_runl = { .allow = r535_runl_allow, }; -static int -r535_fifo_2080_type(enum nvkm_subdev_type type, int inst) +void +r535_fifo_rc_chid(struct nvkm_fifo *fifo, int chid) { - switch (type) { - case NVKM_ENGINE_GR: return NV2080_ENGINE_TYPE_GR0; - case NVKM_ENGINE_CE: return NV2080_ENGINE_TYPE_COPY0 + inst; - case NVKM_ENGINE_SEC2: return NV2080_ENGINE_TYPE_SEC2; - case NVKM_ENGINE_NVDEC: return NV2080_ENGINE_TYPE_NVDEC0 + inst; - case NVKM_ENGINE_NVENC: return NV2080_ENGINE_TYPE_NVENC0 + inst; - case NVKM_ENGINE_NVJPG: return NV2080_ENGINE_TYPE_NVJPEG0 + inst; - case NVKM_ENGINE_OFA: return NV2080_ENGINE_TYPE_OFA; - case NVKM_ENGINE_SW: return NV2080_ENGINE_TYPE_SW; - default: - break; + struct nvkm_chan *chan; + unsigned long flags; + + chan = nvkm_chan_get_chid(&fifo->engine, chid, &flags); + if (!chan) { + nvkm_error(&fifo->engine.subdev, "rc: chid %d not found!\n", chid); + return; } - WARN_ON(1); - return -EINVAL; + nvkm_chan_error(chan, false); + nvkm_chan_put(&chan, flags); } static int -r535_fifo_engn_type(RM_ENGINE_TYPE rm, enum nvkm_subdev_type *ptype) +r535_fifo_rc_triggered(void *priv, u32 fn, void *repv, u32 repc) { + rpc_rc_triggered_v17_02 *msg = repv; + struct nvkm_gsp *gsp = priv; + + if (WARN_ON(repc < sizeof(*msg))) + return -EINVAL; + + nvkm_error(&gsp->subdev, "rc: engn:%08x chid:%d type:%d scope:%d part:%d\n", + msg->nv2080EngineType, msg->chid, msg->exceptType, msg->scope, + msg->partitionAttributionId); + + r535_fifo_rc_chid(gsp->subdev.device->fifo, msg->chid); + return 0; +} + +static int +r535_fifo_xlat_rm_engine_type(u32 rm, enum nvkm_subdev_type *ptype, int *p2080) +{ +#define RM_ENGINE_TYPE(RM,NVKM,INST) \ + RM_ENGINE_TYPE_##RM: \ + *ptype = NVKM_ENGINE_##NVKM; \ + *p2080 = NV2080_ENGINE_TYPE_##RM; \ + return INST + switch (rm) { - case RM_ENGINE_TYPE_GR0: - *ptype = NVKM_ENGINE_GR; - return 0; - case RM_ENGINE_TYPE_COPY0...RM_ENGINE_TYPE_COPY9: - *ptype = NVKM_ENGINE_CE; - return rm - RM_ENGINE_TYPE_COPY0; - case RM_ENGINE_TYPE_NVDEC0...RM_ENGINE_TYPE_NVDEC7: - *ptype = NVKM_ENGINE_NVDEC; - return rm - RM_ENGINE_TYPE_NVDEC0; - case RM_ENGINE_TYPE_NVENC0...RM_ENGINE_TYPE_NVENC2: - *ptype = NVKM_ENGINE_NVENC; - return rm - RM_ENGINE_TYPE_NVENC0; - case RM_ENGINE_TYPE_SW: - *ptype = NVKM_ENGINE_SW; - return 0; - case RM_ENGINE_TYPE_SEC2: - *ptype = NVKM_ENGINE_SEC2; - return 0; - case RM_ENGINE_TYPE_NVJPEG0...RM_ENGINE_TYPE_NVJPEG7: - *ptype = NVKM_ENGINE_NVJPG; - return rm - RM_ENGINE_TYPE_NVJPEG0; - case RM_ENGINE_TYPE_OFA: - *ptype = NVKM_ENGINE_OFA; - return 0; + case RM_ENGINE_TYPE( GR0, GR, 0); + case RM_ENGINE_TYPE( COPY0, CE, 0); + case RM_ENGINE_TYPE( COPY1, CE, 1); + case RM_ENGINE_TYPE( COPY2, CE, 2); + case RM_ENGINE_TYPE( COPY3, CE, 3); + case RM_ENGINE_TYPE( COPY4, CE, 4); + case RM_ENGINE_TYPE( COPY5, CE, 5); + case RM_ENGINE_TYPE( COPY6, CE, 6); + case RM_ENGINE_TYPE( COPY7, CE, 7); + case RM_ENGINE_TYPE( COPY8, CE, 8); + case RM_ENGINE_TYPE( COPY9, CE, 9); + case RM_ENGINE_TYPE( NVDEC0, NVDEC, 0); + case RM_ENGINE_TYPE( NVDEC1, NVDEC, 1); + case RM_ENGINE_TYPE( NVDEC2, NVDEC, 2); + case RM_ENGINE_TYPE( NVDEC3, NVDEC, 3); + case RM_ENGINE_TYPE( NVDEC4, NVDEC, 4); + case RM_ENGINE_TYPE( NVDEC5, NVDEC, 5); + case RM_ENGINE_TYPE( NVDEC6, NVDEC, 6); + case RM_ENGINE_TYPE( NVDEC7, NVDEC, 7); + case RM_ENGINE_TYPE( NVENC0, NVENC, 0); + case RM_ENGINE_TYPE( NVENC1, NVENC, 1); + case RM_ENGINE_TYPE( NVENC2, NVENC, 2); + case RM_ENGINE_TYPE(NVJPEG0, NVJPG, 0); + case RM_ENGINE_TYPE(NVJPEG1, NVJPG, 1); + case RM_ENGINE_TYPE(NVJPEG2, NVJPG, 2); + case RM_ENGINE_TYPE(NVJPEG3, NVJPG, 3); + case RM_ENGINE_TYPE(NVJPEG4, NVJPG, 4); + case RM_ENGINE_TYPE(NVJPEG5, NVJPG, 5); + case RM_ENGINE_TYPE(NVJPEG6, NVJPG, 6); + case RM_ENGINE_TYPE(NVJPEG7, NVJPG, 7); + case RM_ENGINE_TYPE( SW, SW, 0); + case RM_ENGINE_TYPE( SEC2, SEC2, 0); + case RM_ENGINE_TYPE( OFA, OFA, 0); default: return -EINVAL; } +#undef RM_ENGINE_TYPE } static int @@ -536,16 +457,19 @@ static int r535_fifo_runl_ctor(struct nvkm_fifo *fifo) { struct nvkm_subdev *subdev = &fifo->engine.subdev; - struct nvkm_gsp *gsp = subdev->device->gsp; + struct nvkm_device *device = subdev->device; + struct nvkm_gsp *gsp = device->gsp; + struct nvkm_rm *rm = gsp->rm; struct nvkm_runl *runl; struct nvkm_engn *engn; - u32 cgids = 2048; u32 chids = 2048; + u32 first = rm->api->fifo->rsvd_chids; + u32 count = chids - first; int ret; NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS *ctrl; - if ((ret = nvkm_chid_new(&nvkm_chan_event, subdev, cgids, 0, cgids, &fifo->cgid)) || - (ret = nvkm_chid_new(&nvkm_chan_event, subdev, chids, 0, chids, &fifo->chid))) + if ((ret = nvkm_chid_new(&nvkm_chan_event, subdev, chids, first, count, &fifo->cgid)) || + (ret = nvkm_chid_new(&nvkm_chan_event, subdev, chids, first, count, &fifo->chid))) return ret; ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, @@ -576,25 +500,43 @@ r535_fifo_runl_ctor(struct nvkm_fifo *fifo) if (!runl) continue; - inst = r535_fifo_engn_type(rmid, &type); + inst = rm->api->fifo->xlat_rm_engine_type(rmid, &type, &nv2080); if (inst < 0) { nvkm_warn(subdev, "RM_ENGINE_TYPE 0x%x\n", rmid); nvkm_runl_del(runl); continue; } - nv2080 = r535_fifo_2080_type(type, inst); - if (nv2080 < 0) { + /* Skip SW engine - there's currently no support for NV SW classes. */ + if (type == NVKM_ENGINE_SW) + continue; + + /* Skip lone GRCEs (ones not paired with GR on a runlist), as they + * don't appear to function as async copy engines. + */ + if (type == NVKM_ENGINE_CE && + rm->gpu->ce.grce_mask && + (rm->gpu->ce.grce_mask(device) & BIT(inst)) && + !nvkm_runl_find_engn(engn, runl, engn->engine->subdev.type == NVKM_ENGINE_GR)) { + RUNL_DEBUG(runl, "skip LCE %d - GRCE without GR", inst); + nvkm_runl_del(runl); + continue; + } + + ret = nvkm_rm_engine_new(gsp->rm, type, inst); + if (ret) { nvkm_runl_del(runl); continue; } + engn = NULL; + switch (type) { case NVKM_ENGINE_CE: - engn = nvkm_runl_add(runl, nv2080, &r535_ce, type, inst); + engn = nvkm_runl_add(runl, nv2080, &r535_engn_ce, type, inst); break; case NVKM_ENGINE_GR: - engn = nvkm_runl_add(runl, nv2080, &r535_gr, type, inst); + engn = nvkm_runl_add(runl, nv2080, &r535_engn_gr, type, inst); break; case NVKM_ENGINE_NVDEC: case NVKM_ENGINE_NVENC: @@ -633,7 +575,7 @@ r535_fifo_runl_ctor(struct nvkm_fifo *fifo) nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); } - return r535_fifo_ectx_size(fifo); + return rm->api->fifo->ectx_size(fifo); } static void @@ -646,6 +588,7 @@ int r535_fifo_new(const struct nvkm_fifo_func *hw, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fifo **pfifo) { + const struct nvkm_rm_gpu *gpu = device->gsp->rm->gpu; struct nvkm_fifo_func *rm; if (!(rm = kzalloc(sizeof(*rm), GFP_KERNEL))) @@ -654,12 +597,20 @@ r535_fifo_new(const struct nvkm_fifo_func *hw, struct nvkm_device *device, rm->dtor = r535_fifo_dtor; rm->runl_ctor = r535_fifo_runl_ctor; rm->runl = &r535_runl; - rm->cgrp = hw->cgrp; - rm->cgrp.func = &r535_cgrp; - rm->chan = hw->chan; + rm->chan.user.oclass = gpu->fifo.chan.class; rm->chan.func = &r535_chan; rm->nonstall = &ga100_fifo_nonstall; rm->nonstall_ctor = ga100_fifo_nonstall_ctor; return nvkm_fifo_new_(rm, device, type, inst, pfifo); } + +const struct nvkm_rm_api_fifo +r535_fifo = { + .xlat_rm_engine_type = r535_fifo_xlat_rm_engine_type, + .ectx_size = r535_fifo_ectx_size, + .rc_triggered = r535_fifo_rc_triggered, + .chan = { + .alloc = r535_chan_alloc, + }, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c new file mode 100644 index 000000000000..ddb57d5e73d6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c @@ -0,0 +1,356 @@ +/* + * Copyright 2023 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include <rm/gr.h> + +#include <core/memory.h> +#include <subdev/gsp.h> +#include <subdev/mmu/vmm.h> +#include <engine/fifo/priv.h> +#include <engine/gr/priv.h> + +#include <nvif/if900d.h> + +#include <nvhw/drf.h> + +#include "nvrm/gr.h" +#include "nvrm/vmm.h" + +#define r535_gr(p) container_of((p), struct r535_gr, base) + +static void * +r535_gr_chan_dtor(struct nvkm_object *object) +{ + struct r535_gr_chan *grc = container_of(object, typeof(*grc), object); + struct r535_gr *gr = grc->gr; + + for (int i = 0; i < gr->ctxbuf_nr; i++) { + nvkm_vmm_put(grc->vmm, &grc->vma[i]); + nvkm_memory_unref(&grc->mem[i]); + } + + nvkm_vmm_unref(&grc->vmm); + return grc; +} + +static const struct nvkm_object_func +r535_gr_chan = { + .dtor = r535_gr_chan_dtor, +}; + +int +r535_gr_promote_ctx(struct r535_gr *gr, bool golden, struct nvkm_vmm *vmm, + struct nvkm_memory **pmem, struct nvkm_vma **pvma, + struct nvkm_gsp_object *chan) +{ + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + struct nvkm_device *device = subdev->device; + NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_get(&vmm->rm.device.subdevice, + NV2080_CTRL_CMD_GPU_PROMOTE_CTX, sizeof(*ctrl)); + if (WARN_ON(IS_ERR(ctrl))) + return PTR_ERR(ctrl); + + ctrl->engineType = 1; + ctrl->hChanClient = vmm->rm.client.object.handle; + ctrl->hObject = chan->handle; + + for (int i = 0; i < gr->ctxbuf_nr; i++) { + NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ENTRY *entry = + &ctrl->promoteEntry[ctrl->entryCount]; + const bool alloc = golden || !gr->ctxbuf[i].global; + int ret; + + entry->bufferId = gr->ctxbuf[i].bufferId; + entry->bInitialize = gr->ctxbuf[i].init && alloc; + + if (alloc) { + ret = nvkm_memory_new(device, gr->ctxbuf[i].init ? + NVKM_MEM_TARGET_INST : NVKM_MEM_TARGET_INST_SR_LOST, + gr->ctxbuf[i].size, 1 << gr->ctxbuf[i].page, + gr->ctxbuf[i].init, &pmem[i]); + if (WARN_ON(ret)) + return ret; + + if (gr->ctxbuf[i].bufferId == + NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PRIV_ACCESS_MAP) + entry->bNonmapped = 1; + } else { + if (gr->ctxbuf[i].bufferId == + NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_UNRESTRICTED_PRIV_ACCESS_MAP) + continue; + + pmem[i] = nvkm_memory_ref(gr->ctxbuf_mem[i]); + } + + if (!entry->bNonmapped) { + struct gf100_vmm_map_v0 args = { + .priv = 1, + .ro = gr->ctxbuf[i].ro, + }; + + mutex_lock(&vmm->mutex.vmm); + ret = nvkm_vmm_get_locked(vmm, false, true, false, 0, gr->ctxbuf[i].align, + nvkm_memory_size(pmem[i]), &pvma[i]); + mutex_unlock(&vmm->mutex.vmm); + if (ret) + return ret; + + ret = nvkm_memory_map(pmem[i], 0, vmm, pvma[i], &args, sizeof(args)); + if (ret) + return ret; + + entry->gpuVirtAddr = pvma[i]->addr; + } + + if (entry->bInitialize) { + entry->gpuPhysAddr = nvkm_memory_addr(pmem[i]); + entry->size = gr->ctxbuf[i].size; + entry->physAttr = 4; + } + + nvkm_debug(subdev, + "promote %02d: pa %016llx/%08x sz %016llx va %016llx init:%d nm:%d\n", + entry->bufferId, entry->gpuPhysAddr, entry->physAttr, entry->size, + entry->gpuVirtAddr, entry->bInitialize, entry->bNonmapped); + + ctrl->entryCount++; + } + + return nvkm_gsp_rm_ctrl_wr(&vmm->rm.device.subdevice, ctrl); +} + +int +r535_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *chan, const struct nvkm_oclass *oclass, + struct nvkm_object **pobject) +{ + struct r535_gr *gr = r535_gr(base); + struct r535_gr_chan *grc; + int ret; + + if (!(grc = kzalloc(sizeof(*grc), GFP_KERNEL))) + return -ENOMEM; + + nvkm_object_ctor(&r535_gr_chan, oclass, &grc->object); + grc->gr = gr; + grc->vmm = nvkm_vmm_ref(chan->vmm); + grc->chan = chan; + *pobject = &grc->object; + + ret = r535_gr_promote_ctx(gr, false, grc->vmm, grc->mem, grc->vma, &chan->rm.object); + if (ret) + return ret; + + return 0; +} + +u64 +r535_gr_units(struct nvkm_gr *gr) +{ + struct nvkm_gsp *gsp = gr->engine.subdev.device->gsp; + + return (gsp->gr.tpcs << 8) | gsp->gr.gpcs; +} + +void +r535_gr_get_ctxbuf_info(struct r535_gr *gr, int i, + struct NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO *info) +{ + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + static const struct { + u32 id0; /* NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID */ + u32 id1; /* NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID */ + bool global; + bool init; + bool ro; + } map[] = { +#define _A(n,N,G,I,R) { .id0 = NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_##n, \ + .id1 = NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_##N, \ + .global = (G), .init = (I), .ro = (R) } +#define _B(N,G,I,R) _A(GRAPHICS_##N, N, (G), (I), (R)) + /* global init ro */ + _A( GRAPHICS, MAIN, false, true, false), + _B( PATCH, false, true, false), + _A( GRAPHICS_BUNDLE_CB, BUFFER_BUNDLE_CB, true, false, false), + _B( PAGEPOOL, true, false, false), + _B( ATTRIBUTE_CB, true, false, false), + _B( RTV_CB_GLOBAL, true, false, false), + _B( FECS_EVENT, true, true, false), + _B( PRIV_ACCESS_MAP, true, true, true), +#undef _B +#undef _A + }; + u32 size = info->size; + u8 align, page; + int id; + + for (id = 0; id < ARRAY_SIZE(map); id++) { + if (map[id].id0 == i) + break; + } + + nvkm_debug(subdev, "%02x: size:0x%08x %s\n", i, + size, (id < ARRAY_SIZE(map)) ? "*" : ""); + if (id >= ARRAY_SIZE(map)) + return; + + if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_MAIN) + size = ALIGN(size, 0x1000) + 64 * 0x1000; /* per-subctx headers */ + + if (size >= 1 << 21) page = 21; + else if (size >= 1 << 16) page = 16; + else page = 12; + + if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_ATTRIBUTE_CB) + align = order_base_2(size); + else + align = page; + + if (WARN_ON(gr->ctxbuf_nr == ARRAY_SIZE(gr->ctxbuf))) + return; + + gr->ctxbuf[gr->ctxbuf_nr].bufferId = map[id].id1; + gr->ctxbuf[gr->ctxbuf_nr].size = size; + gr->ctxbuf[gr->ctxbuf_nr].page = page; + gr->ctxbuf[gr->ctxbuf_nr].align = align; + gr->ctxbuf[gr->ctxbuf_nr].global = map[id].global; + gr->ctxbuf[gr->ctxbuf_nr].init = map[id].init; + gr->ctxbuf[gr->ctxbuf_nr].ro = map[id].ro; + gr->ctxbuf_nr++; + + if (map[id].id1 == NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PRIV_ACCESS_MAP) { + if (WARN_ON(gr->ctxbuf_nr == ARRAY_SIZE(gr->ctxbuf))) + return; + + gr->ctxbuf[gr->ctxbuf_nr] = gr->ctxbuf[gr->ctxbuf_nr - 1]; + gr->ctxbuf[gr->ctxbuf_nr].bufferId = + NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_UNRESTRICTED_PRIV_ACCESS_MAP; + gr->ctxbuf_nr++; + } +} + +static int +r535_gr_get_ctxbufs_info(struct r535_gr *gr) +{ + NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS *info; + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + struct nvkm_gsp *gsp = subdev->device->gsp; + + info = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO, + sizeof(*info)); + if (WARN_ON(IS_ERR(info))) + return PTR_ERR(info); + + for (int i = 0; i < ARRAY_SIZE(info->engineContextBuffersInfo[0].engine); i++) + r535_gr_get_ctxbuf_info(gr, i, &info->engineContextBuffersInfo[0].engine[i]); + + nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, info); + return 0; +} + +int +r535_gr_oneinit(struct nvkm_gr *base) +{ + struct r535_gr *gr = container_of(base, typeof(*gr), base); + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + struct nvkm_device *device = subdev->device; + struct nvkm_gsp *gsp = device->gsp; + struct nvkm_rm *rm = gsp->rm; + struct { + struct nvkm_memory *inst; + struct nvkm_vmm *vmm; + struct nvkm_gsp_object chan; + struct nvkm_vma *vma[R515_GR_MAX_CTXBUFS]; + } golden = {}; + struct nvkm_gsp_object threed; + int ret; + + /* Allocate a channel to use for golden context init. */ + ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x12000, 0, true, &golden.inst); + if (ret) + goto done; + + ret = nvkm_vmm_new(device, 0x1000, 0, NULL, 0, NULL, "grGoldenVmm", &golden.vmm); + if (ret) + goto done; + + ret = r535_mmu_vaspace_new(golden.vmm, NVKM_RM_VASPACE, false); + if (ret) + goto done; + + ret = rm->api->fifo->chan.alloc(&golden.vmm->rm.device, NVKM_RM_CHAN(0), + 1, 0, true, rm->api->fifo->rsvd_chids, + nvkm_memory_addr(golden.inst), + nvkm_memory_addr(golden.inst) + 0x1000, + nvkm_memory_addr(golden.inst) + 0x2000, + golden.vmm, 0, 0x1000, &golden.chan); + if (ret) + goto done; + + /* Fetch context buffer info from RM and allocate each of them here to use + * during golden context init (or later as a global context buffer). + * + * Also build the information that'll be used to create channel contexts. + */ + ret = rm->api->gr->get_ctxbufs_info(gr); + if (ret) + goto done; + + /* Promote golden context to RM. */ + ret = r535_gr_promote_ctx(gr, true, golden.vmm, gr->ctxbuf_mem, golden.vma, &golden.chan); + if (ret) + goto done; + + /* Allocate 3D class on channel to trigger golden context init in RM. */ + ret = nvkm_gsp_rm_alloc(&golden.chan, NVKM_RM_THREED, rm->gpu->gr.class.threed, 0, &threed); + if (ret) + goto done; + + /* There's no need to keep the golden channel around, as RM caches the context. */ + nvkm_gsp_rm_free(&threed); +done: + nvkm_gsp_rm_free(&golden.chan); + for (int i = gr->ctxbuf_nr - 1; i >= 0; i--) + nvkm_vmm_put(golden.vmm, &golden.vma[i]); + nvkm_vmm_unref(&golden.vmm); + nvkm_memory_unref(&golden.inst); + return ret; + +} + +void * +r535_gr_dtor(struct nvkm_gr *base) +{ + struct r535_gr *gr = r535_gr(base); + + while (gr->ctxbuf_nr) + nvkm_memory_unref(&gr->ctxbuf_mem[--gr->ctxbuf_nr]); + + kfree(gr->base.func); + return gr; +} + +const struct nvkm_rm_api_gr +r535_gr = { + .get_ctxbufs_info = r535_gr_get_ctxbufs_info, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index 969f6b921fdb..baf42339f93e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -19,9 +19,12 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ +#include <rm/rpc.h> + #include "priv.h" #include <core/pci.h> +#include <subdev/pci/priv.h> #include <subdev/timer.h> #include <subdev/vfn.h> #include <engine/fifo/chan.h> @@ -30,29 +33,11 @@ #include <nvfw/fw.h> -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0000.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0005.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl0080.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl2080.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080event.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080gpu.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl2080/ctrl2080internal.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h> -#include <nvrm/535.113.01/common/shared/msgq/inc/msgq/msgq_priv.h> -#include <nvrm/535.113.01/common/uproc/os/common/include/libos_init_args.h> -#include <nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_sr_meta.h> -#include <nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/gsp/gsp_fw_wpr_meta.h> -#include <nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmRiscvUcode.h> -#include <nvrm/535.113.01/nvidia/arch/nvalloc/common/inc/rmgspseq.h> -#include <nvrm/535.113.01/nvidia/generated/g_allclasses.h> -#include <nvrm/535.113.01/nvidia/generated/g_os_nvoc.h> -#include <nvrm/535.113.01/nvidia/generated/g_rpc-structures.h> -#include <nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_fw_heap.h> -#include <nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_init_args.h> -#include <nvrm/535.113.01/nvidia/inc/kernel/gpu/gsp/gsp_static_config.h> -#include <nvrm/535.113.01/nvidia/inc/kernel/gpu/intr/engine_idx.h> -#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h> +#include "nvrm/gsp.h" +#include "nvrm/rpcfn.h" +#include "nvrm/msgfn.h" +#include "nvrm/event.h" +#include "nvrm/fifo.h" #include <linux/acpi.h> #include <linux/ctype.h> @@ -60,996 +45,6 @@ extern struct dentry *nouveau_debugfs_root; -#define GSP_MSG_MIN_SIZE GSP_PAGE_SIZE -#define GSP_MSG_MAX_SIZE (GSP_MSG_MIN_SIZE * 16) - -/** - * DOC: GSP message queue element - * - * https://github.com/NVIDIA/open-gpu-kernel-modules/blob/535/src/nvidia/inc/kernel/gpu/gsp/message_queue_priv.h - * - * The GSP command queue and status queue are message queues for the - * communication between software and GSP. The software submits the GSP - * RPC via the GSP command queue, GSP writes the status of the submitted - * RPC in the status queue. - * - * A GSP message queue element consists of three parts: - * - * - message element header (struct r535_gsp_msg), which mostly maintains - * the metadata for queuing the element. - * - * - RPC message header (struct nvfw_gsp_rpc), which maintains the info - * of the RPC. E.g., the RPC function number. - * - * - The payload, where the RPC message stays. E.g. the params of a - * specific RPC function. Some RPC functions also have their headers - * in the payload. E.g. rm_alloc, rm_control. - * - * The memory layout of a GSP message element can be illustrated below:: - * - * +------------------------+ - * | Message Element Header | - * | (r535_gsp_msg) | - * | | - * | (r535_gsp_msg.data) | - * | | | - * |----------V-------------| - * | GSP RPC Header | - * | (nvfw_gsp_rpc) | - * | | - * | (nvfw_gsp_rpc.data) | - * | | | - * |----------V-------------| - * | Payload | - * | | - * | header(optional) | - * | params | - * +------------------------+ - * - * The max size of a message queue element is 16 pages (including the - * headers). When a GSP message to be sent is larger than 16 pages, the - * message should be split into multiple elements and sent accordingly. - * - * In the bunch of the split elements, the first element has the expected - * function number, while the rest of the elements are sent with the - * function number NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD. - * - * GSP consumes the elements from the cmdq and always writes the result - * back to the msgq. The result is also formed as split elements. - * - * Terminology: - * - * - gsp_msg(msg): GSP message element (element header + GSP RPC header + - * payload) - * - gsp_rpc(rpc): GSP RPC (RPC header + payload) - * - gsp_rpc_buf: buffer for (GSP RPC header + payload) - * - gsp_rpc_len: size of (GSP RPC header + payload) - * - params_size: size of params in the payload - * - payload_size: size of (header if exists + params) in the payload - */ - -struct r535_gsp_msg { - u8 auth_tag_buffer[16]; - u8 aad_buffer[16]; - u32 checksum; - u32 sequence; - u32 elem_count; - u32 pad; - u8 data[]; -}; - -struct nvfw_gsp_rpc { - u32 header_version; - u32 signature; - u32 length; - u32 function; - u32 rpc_result; - u32 rpc_result_private; - u32 sequence; - union { - u32 spare; - u32 cpuRmGfid; - }; - u8 data[]; -}; - -#define GSP_MSG_HDR_SIZE offsetof(struct r535_gsp_msg, data) - -#define to_gsp_hdr(p, header) \ - container_of((void *)p, typeof(*header), data) - -#define to_payload_hdr(p, header) \ - container_of((void *)p, typeof(*header), params) - -static int -r535_rpc_status_to_errno(uint32_t rpc_status) -{ - switch (rpc_status) { - case 0x55: /* NV_ERR_NOT_READY */ - case 0x66: /* NV_ERR_TIMEOUT_RETRY */ - return -EBUSY; - case 0x51: /* NV_ERR_NO_MEMORY */ - return -ENOMEM; - default: - return -EINVAL; - } -} - -static int -r535_gsp_msgq_wait(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *ptime) -{ - u32 size, rptr = *gsp->msgq.rptr; - int used; - - size = DIV_ROUND_UP(GSP_MSG_HDR_SIZE + gsp_rpc_len, - GSP_PAGE_SIZE); - if (WARN_ON(!size || size >= gsp->msgq.cnt)) - return -EINVAL; - - do { - u32 wptr = *gsp->msgq.wptr; - - used = wptr + gsp->msgq.cnt - rptr; - if (used >= gsp->msgq.cnt) - used -= gsp->msgq.cnt; - if (used >= size) - break; - - usleep_range(1, 2); - } while (--(*ptime)); - - if (WARN_ON(!*ptime)) - return -ETIMEDOUT; - - return used; -} - -static struct r535_gsp_msg * -r535_gsp_msgq_get_entry(struct nvkm_gsp *gsp) -{ - u32 rptr = *gsp->msgq.rptr; - - /* Skip the first page, which is the message queue info */ - return (void *)((u8 *)gsp->shm.msgq.ptr + GSP_PAGE_SIZE + - rptr * GSP_PAGE_SIZE); -} - -/** - * DOC: Receive a GSP message queue element - * - * Receiving a GSP message queue element from the message queue consists of - * the following steps: - * - * - Peek the element from the queue: r535_gsp_msgq_peek(). - * Peek the first page of the element to determine the total size of the - * message before allocating the proper memory. - * - * - Allocate memory for the message. - * Once the total size of the message is determined from the GSP message - * queue element, the caller of r535_gsp_msgq_recv() allocates the - * required memory. - * - * - Receive the message: r535_gsp_msgq_recv(). - * Copy the message into the allocated memory. Advance the read pointer. - * If the message is a large GSP message, r535_gsp_msgq_recv() calls - * r535_gsp_msgq_recv_one_elem() repeatedly to receive continuation parts - * until the complete message is received. - * r535_gsp_msgq_recv() assembles the payloads of cotinuation parts into - * the return of the large GSP message. - * - * - Free the allocated memory: r535_gsp_msg_done(). - * The user is responsible for freeing the memory allocated for the GSP - * message pages after they have been processed. - */ -static void * -r535_gsp_msgq_peek(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) -{ - struct r535_gsp_msg *mqe; - int ret; - - ret = r535_gsp_msgq_wait(gsp, gsp_rpc_len, retries); - if (ret < 0) - return ERR_PTR(ret); - - mqe = r535_gsp_msgq_get_entry(gsp); - - return mqe->data; -} - -struct r535_gsp_msg_info { - int *retries; - u32 gsp_rpc_len; - void *gsp_rpc_buf; - bool continuation; -}; - -static void -r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl); - -static void * -r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp, - struct r535_gsp_msg_info *info) -{ - u8 *buf = info->gsp_rpc_buf; - u32 rptr = *gsp->msgq.rptr; - struct r535_gsp_msg *mqe; - u32 size, expected, len; - int ret; - - expected = info->gsp_rpc_len; - - ret = r535_gsp_msgq_wait(gsp, expected, info->retries); - if (ret < 0) - return ERR_PTR(ret); - - mqe = r535_gsp_msgq_get_entry(gsp); - - if (info->continuation) { - struct nvfw_gsp_rpc *rpc = (struct nvfw_gsp_rpc *)mqe->data; - - if (rpc->function != NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD) { - nvkm_error(&gsp->subdev, - "Not a continuation of a large RPC\n"); - r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); - return ERR_PTR(-EIO); - } - } - - size = ALIGN(expected + GSP_MSG_HDR_SIZE, GSP_PAGE_SIZE); - - len = ((gsp->msgq.cnt - rptr) * GSP_PAGE_SIZE) - sizeof(*mqe); - len = min_t(u32, expected, len); - - if (info->continuation) - memcpy(buf, mqe->data + sizeof(struct nvfw_gsp_rpc), - len - sizeof(struct nvfw_gsp_rpc)); - else - memcpy(buf, mqe->data, len); - - expected -= len; - - if (expected) { - mqe = (void *)((u8 *)gsp->shm.msgq.ptr + 0x1000 + 0 * 0x1000); - memcpy(buf + len, mqe, expected); - } - - rptr = (rptr + DIV_ROUND_UP(size, GSP_PAGE_SIZE)) % gsp->msgq.cnt; - - mb(); - (*gsp->msgq.rptr) = rptr; - return buf; -} - -static void * -r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) -{ - struct r535_gsp_msg *mqe; - const u32 max_rpc_size = GSP_MSG_MAX_SIZE - sizeof(*mqe); - struct nvfw_gsp_rpc *rpc; - struct r535_gsp_msg_info info = {0}; - u32 expected = gsp_rpc_len; - void *buf; - - mqe = r535_gsp_msgq_get_entry(gsp); - rpc = (struct nvfw_gsp_rpc *)mqe->data; - - if (WARN_ON(rpc->length > max_rpc_size)) - return NULL; - - buf = kvmalloc(max_t(u32, rpc->length, expected), GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - - info.gsp_rpc_buf = buf; - info.retries = retries; - info.gsp_rpc_len = rpc->length; - - buf = r535_gsp_msgq_recv_one_elem(gsp, &info); - if (IS_ERR(buf)) { - kvfree(info.gsp_rpc_buf); - info.gsp_rpc_buf = NULL; - return buf; - } - - if (expected <= max_rpc_size) - return buf; - - info.gsp_rpc_buf += info.gsp_rpc_len; - expected -= info.gsp_rpc_len; - - while (expected) { - u32 size; - - rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), info.retries); - if (IS_ERR_OR_NULL(rpc)) { - kfree(buf); - return rpc; - } - - info.gsp_rpc_len = rpc->length; - info.continuation = true; - - rpc = r535_gsp_msgq_recv_one_elem(gsp, &info); - if (IS_ERR_OR_NULL(rpc)) { - kfree(buf); - return rpc; - } - - size = info.gsp_rpc_len - sizeof(*rpc); - expected -= size; - info.gsp_rpc_buf += size; - } - - rpc = buf; - rpc->length = gsp_rpc_len; - return buf; -} - -static int -r535_gsp_cmdq_push(struct nvkm_gsp *gsp, void *rpc) -{ - struct r535_gsp_msg *msg = to_gsp_hdr(rpc, msg); - struct r535_gsp_msg *cqe; - u32 gsp_rpc_len = msg->checksum; - u64 *ptr = (void *)msg; - u64 *end; - u64 csum = 0; - int free, time = 1000000; - u32 wptr, size, step, len; - u32 off = 0; - - len = ALIGN(GSP_MSG_HDR_SIZE + gsp_rpc_len, GSP_PAGE_SIZE); - - end = (u64 *)((char *)ptr + len); - msg->pad = 0; - msg->checksum = 0; - msg->sequence = gsp->cmdq.seq++; - msg->elem_count = DIV_ROUND_UP(len, 0x1000); - - while (ptr < end) - csum ^= *ptr++; - - msg->checksum = upper_32_bits(csum) ^ lower_32_bits(csum); - - wptr = *gsp->cmdq.wptr; - do { - do { - free = *gsp->cmdq.rptr + gsp->cmdq.cnt - wptr - 1; - if (free >= gsp->cmdq.cnt) - free -= gsp->cmdq.cnt; - if (free >= 1) - break; - - usleep_range(1, 2); - } while(--time); - - if (WARN_ON(!time)) { - kvfree(msg); - return -ETIMEDOUT; - } - - cqe = (void *)((u8 *)gsp->shm.cmdq.ptr + 0x1000 + wptr * 0x1000); - step = min_t(u32, free, (gsp->cmdq.cnt - wptr)); - size = min_t(u32, len, step * GSP_PAGE_SIZE); - - memcpy(cqe, (u8 *)msg + off, size); - - wptr += DIV_ROUND_UP(size, 0x1000); - if (wptr == gsp->cmdq.cnt) - wptr = 0; - - off += size; - len -= size; - } while (len); - - nvkm_trace(&gsp->subdev, "cmdq: wptr %d\n", wptr); - wmb(); - (*gsp->cmdq.wptr) = wptr; - mb(); - - nvkm_falcon_wr32(&gsp->falcon, 0xc00, 0x00000000); - - kvfree(msg); - return 0; -} - -static void * -r535_gsp_cmdq_get(struct nvkm_gsp *gsp, u32 gsp_rpc_len) -{ - struct r535_gsp_msg *msg; - u32 size = GSP_MSG_HDR_SIZE + gsp_rpc_len; - - size = ALIGN(size, GSP_MSG_MIN_SIZE); - msg = kvzalloc(size, GFP_KERNEL); - if (!msg) - return ERR_PTR(-ENOMEM); - - msg->checksum = gsp_rpc_len; - return msg->data; -} - -static void -r535_gsp_msg_done(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg) -{ - kvfree(msg); -} - -static void -r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl) -{ - if (gsp->subdev.debug >= lvl) { - nvkm_printk__(&gsp->subdev, lvl, info, - "msg fn:%d len:0x%x/0x%zx res:0x%x resp:0x%x\n", - msg->function, msg->length, msg->length - sizeof(*msg), - msg->rpc_result, msg->rpc_result_private); - print_hex_dump(KERN_INFO, "msg: ", DUMP_PREFIX_OFFSET, 16, 1, - msg->data, msg->length - sizeof(*msg), true); - } -} - -static struct nvfw_gsp_rpc * -r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len) -{ - struct nvkm_subdev *subdev = &gsp->subdev; - struct nvfw_gsp_rpc *rpc; - int retries = 4000000, i; - -retry: - rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), &retries); - if (IS_ERR_OR_NULL(rpc)) - return rpc; - - rpc = r535_gsp_msgq_recv(gsp, gsp_rpc_len, &retries); - if (IS_ERR_OR_NULL(rpc)) - return rpc; - - if (rpc->rpc_result) { - r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); - r535_gsp_msg_done(gsp, rpc); - return ERR_PTR(-EINVAL); - } - - r535_gsp_msg_dump(gsp, rpc, NV_DBG_TRACE); - - if (fn && rpc->function == fn) { - if (gsp_rpc_len) { - if (rpc->length < gsp_rpc_len) { - nvkm_error(subdev, "rpc len %d < %d\n", - rpc->length, gsp_rpc_len); - r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); - r535_gsp_msg_done(gsp, rpc); - return ERR_PTR(-EIO); - } - - return rpc; - } - - r535_gsp_msg_done(gsp, rpc); - return NULL; - } - - for (i = 0; i < gsp->msgq.ntfy_nr; i++) { - struct nvkm_gsp_msgq_ntfy *ntfy = &gsp->msgq.ntfy[i]; - - if (ntfy->fn == rpc->function) { - if (ntfy->func) - ntfy->func(ntfy->priv, ntfy->fn, rpc->data, - rpc->length - sizeof(*rpc)); - break; - } - } - - if (i == gsp->msgq.ntfy_nr) - r535_gsp_msg_dump(gsp, rpc, NV_DBG_WARN); - - r535_gsp_msg_done(gsp, rpc); - if (fn) - goto retry; - - if (*gsp->msgq.rptr != *gsp->msgq.wptr) - goto retry; - - return NULL; -} - -static int -r535_gsp_msg_ntfy_add(struct nvkm_gsp *gsp, u32 fn, nvkm_gsp_msg_ntfy_func func, void *priv) -{ - int ret = 0; - - mutex_lock(&gsp->msgq.mutex); - if (WARN_ON(gsp->msgq.ntfy_nr >= ARRAY_SIZE(gsp->msgq.ntfy))) { - ret = -ENOSPC; - } else { - gsp->msgq.ntfy[gsp->msgq.ntfy_nr].fn = fn; - gsp->msgq.ntfy[gsp->msgq.ntfy_nr].func = func; - gsp->msgq.ntfy[gsp->msgq.ntfy_nr].priv = priv; - gsp->msgq.ntfy_nr++; - } - mutex_unlock(&gsp->msgq.mutex); - return ret; -} - -static int -r535_gsp_rpc_poll(struct nvkm_gsp *gsp, u32 fn) -{ - void *repv; - - mutex_lock(&gsp->cmdq.mutex); - repv = r535_gsp_msg_recv(gsp, fn, 0); - mutex_unlock(&gsp->cmdq.mutex); - if (IS_ERR(repv)) - return PTR_ERR(repv); - - return 0; -} - -static void * -r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn, - enum nvkm_gsp_rpc_reply_policy policy, - u32 gsp_rpc_len) -{ - struct nvfw_gsp_rpc *reply; - void *repv = NULL; - - switch (policy) { - case NVKM_GSP_RPC_REPLY_NOWAIT: - break; - case NVKM_GSP_RPC_REPLY_RECV: - reply = r535_gsp_msg_recv(gsp, fn, gsp_rpc_len); - if (!IS_ERR_OR_NULL(reply)) - repv = reply->data; - else - repv = reply; - break; - case NVKM_GSP_RPC_REPLY_POLL: - repv = r535_gsp_msg_recv(gsp, fn, 0); - break; - } - - return repv; -} - -static void * -r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload, - enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len) -{ - struct nvfw_gsp_rpc *rpc = to_gsp_hdr(payload, rpc); - u32 fn = rpc->function; - int ret; - - if (gsp->subdev.debug >= NV_DBG_TRACE) { - nvkm_trace(&gsp->subdev, "rpc fn:%d len:0x%x/0x%zx\n", rpc->function, - rpc->length, rpc->length - sizeof(*rpc)); - print_hex_dump(KERN_INFO, "rpc: ", DUMP_PREFIX_OFFSET, 16, 1, - rpc->data, rpc->length - sizeof(*rpc), true); - } - - ret = r535_gsp_cmdq_push(gsp, rpc); - if (ret) - return ERR_PTR(ret); - - return r535_gsp_rpc_handle_reply(gsp, fn, policy, gsp_rpc_len); -} - -static void -r535_gsp_event_dtor(struct nvkm_gsp_event *event) -{ - struct nvkm_gsp_device *device = event->device; - struct nvkm_gsp_client *client = device->object.client; - struct nvkm_gsp *gsp = client->gsp; - - mutex_lock(&gsp->client_id.mutex); - if (event->func) { - list_del(&event->head); - event->func = NULL; - } - mutex_unlock(&gsp->client_id.mutex); - - nvkm_gsp_rm_free(&event->object); - event->device = NULL; -} - -static int -r535_gsp_device_event_get(struct nvkm_gsp_event *event) -{ - struct nvkm_gsp_device *device = event->device; - NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS *ctrl; - - ctrl = nvkm_gsp_rm_ctrl_get(&device->subdevice, - NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION, sizeof(*ctrl)); - if (IS_ERR(ctrl)) - return PTR_ERR(ctrl); - - ctrl->event = event->id; - ctrl->action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT; - return nvkm_gsp_rm_ctrl_wr(&device->subdevice, ctrl); -} - -static int -r535_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id, - nvkm_gsp_event_func func, struct nvkm_gsp_event *event) -{ - struct nvkm_gsp_client *client = device->object.client; - struct nvkm_gsp *gsp = client->gsp; - NV0005_ALLOC_PARAMETERS *args; - int ret; - - args = nvkm_gsp_rm_alloc_get(&device->subdevice, handle, - NV01_EVENT_KERNEL_CALLBACK_EX, sizeof(*args), - &event->object); - if (IS_ERR(args)) - return PTR_ERR(args); - - args->hParentClient = client->object.handle; - args->hSrcResource = 0; - args->hClass = NV01_EVENT_KERNEL_CALLBACK_EX; - args->notifyIndex = NV01_EVENT_CLIENT_RM | id; - args->data = NULL; - - ret = nvkm_gsp_rm_alloc_wr(&event->object, args); - if (ret) - return ret; - - event->device = device; - event->id = id; - - ret = r535_gsp_device_event_get(event); - if (ret) { - nvkm_gsp_event_dtor(event); - return ret; - } - - mutex_lock(&gsp->client_id.mutex); - event->func = func; - list_add(&event->head, &client->events); - mutex_unlock(&gsp->client_id.mutex); - return 0; -} - -static void -r535_gsp_device_dtor(struct nvkm_gsp_device *device) -{ - nvkm_gsp_rm_free(&device->subdevice); - nvkm_gsp_rm_free(&device->object); -} - -static int -r535_gsp_subdevice_ctor(struct nvkm_gsp_device *device) -{ - NV2080_ALLOC_PARAMETERS *args; - - return nvkm_gsp_rm_alloc(&device->object, 0x5d1d0000, NV20_SUBDEVICE_0, sizeof(*args), - &device->subdevice); -} - -static int -r535_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device) -{ - NV0080_ALLOC_PARAMETERS *args; - int ret; - - args = nvkm_gsp_rm_alloc_get(&client->object, 0xde1d0000, NV01_DEVICE_0, sizeof(*args), - &device->object); - if (IS_ERR(args)) - return PTR_ERR(args); - - args->hClientShare = client->object.handle; - - ret = nvkm_gsp_rm_alloc_wr(&device->object, args); - if (ret) - return ret; - - ret = r535_gsp_subdevice_ctor(device); - if (ret) - nvkm_gsp_rm_free(&device->object); - - return ret; -} - -static void -r535_gsp_client_dtor(struct nvkm_gsp_client *client) -{ - struct nvkm_gsp *gsp = client->gsp; - - nvkm_gsp_rm_free(&client->object); - - mutex_lock(&gsp->client_id.mutex); - idr_remove(&gsp->client_id.idr, client->object.handle & 0xffff); - mutex_unlock(&gsp->client_id.mutex); - - client->gsp = NULL; -} - -static int -r535_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client) -{ - NV0000_ALLOC_PARAMETERS *args; - int ret; - - mutex_lock(&gsp->client_id.mutex); - ret = idr_alloc(&gsp->client_id.idr, client, 0, 0xffff + 1, GFP_KERNEL); - mutex_unlock(&gsp->client_id.mutex); - if (ret < 0) - return ret; - - client->gsp = gsp; - client->object.client = client; - INIT_LIST_HEAD(&client->events); - - args = nvkm_gsp_rm_alloc_get(&client->object, 0xc1d00000 | ret, NV01_ROOT, sizeof(*args), - &client->object); - if (IS_ERR(args)) { - r535_gsp_client_dtor(client); - return ret; - } - - args->hClient = client->object.handle; - args->processID = ~0; - - ret = nvkm_gsp_rm_alloc_wr(&client->object, args); - if (ret) { - r535_gsp_client_dtor(client); - return ret; - } - - return 0; -} - -static int -r535_gsp_rpc_rm_free(struct nvkm_gsp_object *object) -{ - struct nvkm_gsp_client *client = object->client; - struct nvkm_gsp *gsp = client->gsp; - rpc_free_v03_00 *rpc; - - nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x free\n", - client->object.handle, object->handle); - - rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc)); - if (WARN_ON(IS_ERR_OR_NULL(rpc))) - return -EIO; - - rpc->params.hRoot = client->object.handle; - rpc->params.hObjectParent = 0; - rpc->params.hObjectOld = object->handle; - return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV); -} - -static void -r535_gsp_rpc_rm_alloc_done(struct nvkm_gsp_object *object, void *params) -{ - rpc_gsp_rm_alloc_v03_00 *rpc = to_payload_hdr(params, rpc); - - nvkm_gsp_rpc_done(object->client->gsp, rpc); -} - -static void * -r535_gsp_rpc_rm_alloc_push(struct nvkm_gsp_object *object, void *params) -{ - rpc_gsp_rm_alloc_v03_00 *rpc = to_payload_hdr(params, rpc); - struct nvkm_gsp *gsp = object->client->gsp; - void *ret = NULL; - - rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, sizeof(*rpc)); - if (IS_ERR_OR_NULL(rpc)) - return rpc; - - if (rpc->status) { - ret = ERR_PTR(r535_rpc_status_to_errno(rpc->status)); - if (PTR_ERR(ret) != -EAGAIN && PTR_ERR(ret) != -EBUSY) - nvkm_error(&gsp->subdev, "RM_ALLOC: 0x%x\n", rpc->status); - } - - nvkm_gsp_rpc_done(gsp, rpc); - - return ret; -} - -static void * -r535_gsp_rpc_rm_alloc_get(struct nvkm_gsp_object *object, u32 oclass, - u32 params_size) -{ - struct nvkm_gsp_client *client = object->client; - struct nvkm_gsp *gsp = client->gsp; - rpc_gsp_rm_alloc_v03_00 *rpc; - - nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x new obj:0x%08x\n", - client->object.handle, object->parent->handle, - object->handle); - - nvkm_debug(&gsp->subdev, "cls:0x%08x params_size:%d\n", oclass, - params_size); - - rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_ALLOC, - sizeof(*rpc) + params_size); - if (IS_ERR(rpc)) - return rpc; - - rpc->hClient = client->object.handle; - rpc->hParent = object->parent->handle; - rpc->hObject = object->handle; - rpc->hClass = oclass; - rpc->status = 0; - rpc->paramsSize = params_size; - return rpc->params; -} - -static void -r535_gsp_rpc_rm_ctrl_done(struct nvkm_gsp_object *object, void *params) -{ - rpc_gsp_rm_control_v03_00 *rpc = to_payload_hdr(params, rpc); - - if (!params) - return; - nvkm_gsp_rpc_done(object->client->gsp, rpc); -} - -static int -r535_gsp_rpc_rm_ctrl_push(struct nvkm_gsp_object *object, void **params, u32 repc) -{ - rpc_gsp_rm_control_v03_00 *rpc = to_payload_hdr((*params), rpc); - struct nvkm_gsp *gsp = object->client->gsp; - int ret = 0; - - rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, repc); - if (IS_ERR_OR_NULL(rpc)) { - *params = NULL; - return PTR_ERR(rpc); - } - - if (rpc->status) { - ret = r535_rpc_status_to_errno(rpc->status); - if (ret != -EAGAIN && ret != -EBUSY) - nvkm_error(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x failed: 0x%08x\n", - object->client->object.handle, object->handle, rpc->cmd, rpc->status); - } - - if (repc) - *params = rpc->params; - else - nvkm_gsp_rpc_done(gsp, rpc); - - return ret; -} - -static void * -r535_gsp_rpc_rm_ctrl_get(struct nvkm_gsp_object *object, u32 cmd, u32 params_size) -{ - struct nvkm_gsp_client *client = object->client; - struct nvkm_gsp *gsp = client->gsp; - rpc_gsp_rm_control_v03_00 *rpc; - - nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x params_size:%d\n", - client->object.handle, object->handle, cmd, params_size); - - rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_CONTROL, - sizeof(*rpc) + params_size); - if (IS_ERR(rpc)) - return rpc; - - rpc->hClient = client->object.handle; - rpc->hObject = object->handle; - rpc->cmd = cmd; - rpc->status = 0; - rpc->paramsSize = params_size; - return rpc->params; -} - -static void -r535_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv) -{ - struct nvfw_gsp_rpc *rpc = container_of(repv, typeof(*rpc), data); - - r535_gsp_msg_done(gsp, rpc); -} - -static void * -r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size) -{ - struct nvfw_gsp_rpc *rpc; - - rpc = r535_gsp_cmdq_get(gsp, ALIGN(sizeof(*rpc) + payload_size, - sizeof(u64))); - if (IS_ERR(rpc)) - return ERR_CAST(rpc); - - rpc->header_version = 0x03000000; - rpc->signature = ('C' << 24) | ('P' << 16) | ('R' << 8) | 'V'; - rpc->function = fn; - rpc->rpc_result = 0xffffffff; - rpc->rpc_result_private = 0xffffffff; - rpc->length = sizeof(*rpc) + payload_size; - return rpc->data; -} - -static void * -r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload, - enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len) -{ - struct nvfw_gsp_rpc *rpc = to_gsp_hdr(payload, rpc); - struct r535_gsp_msg *msg = to_gsp_hdr(rpc, msg); - const u32 max_rpc_size = GSP_MSG_MAX_SIZE - sizeof(*msg); - const u32 max_payload_size = max_rpc_size - sizeof(*rpc); - u32 payload_size = rpc->length - sizeof(*rpc); - void *repv; - - mutex_lock(&gsp->cmdq.mutex); - if (payload_size > max_payload_size) { - const u32 fn = rpc->function; - u32 remain_payload_size = payload_size; - - /* Adjust length, and send initial RPC. */ - rpc->length = sizeof(*rpc) + max_payload_size; - msg->checksum = rpc->length; - - repv = r535_gsp_rpc_send(gsp, payload, NVKM_GSP_RPC_REPLY_NOWAIT, 0); - if (IS_ERR(repv)) - goto done; - - payload += max_payload_size; - remain_payload_size -= max_payload_size; - - /* Remaining chunks sent as CONTINUATION_RECORD RPCs. */ - while (remain_payload_size) { - u32 size = min(remain_payload_size, - max_payload_size); - void *next; - - next = r535_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD, size); - if (IS_ERR(next)) { - repv = next; - goto done; - } - - memcpy(next, payload, size); - - repv = r535_gsp_rpc_send(gsp, next, NVKM_GSP_RPC_REPLY_NOWAIT, 0); - if (IS_ERR(repv)) - goto done; - - payload += size; - remain_payload_size -= size; - } - - /* Wait for reply. */ - repv = r535_gsp_rpc_handle_reply(gsp, fn, policy, payload_size + - sizeof(*rpc)); - } else { - repv = r535_gsp_rpc_send(gsp, payload, policy, gsp_rpc_len); - } - -done: - mutex_unlock(&gsp->cmdq.mutex); - return repv; -} - -const struct nvkm_gsp_rm -r535_gsp_rm = { - .rpc_get = r535_gsp_rpc_get, - .rpc_push = r535_gsp_rpc_push, - .rpc_done = r535_gsp_rpc_done, - - .rm_ctrl_get = r535_gsp_rpc_rm_ctrl_get, - .rm_ctrl_push = r535_gsp_rpc_rm_ctrl_push, - .rm_ctrl_done = r535_gsp_rpc_rm_ctrl_done, - - .rm_alloc_get = r535_gsp_rpc_rm_alloc_get, - .rm_alloc_push = r535_gsp_rpc_rm_alloc_push, - .rm_alloc_done = r535_gsp_rpc_rm_alloc_done, - - .rm_free = r535_gsp_rpc_rm_free, - - .client_ctor = r535_gsp_client_ctor, - .client_dtor = r535_gsp_client_dtor, - - .device_ctor = r535_gsp_device_ctor, - .device_dtor = r535_gsp_device_dtor, - - .event_ctor = r535_gsp_device_event_ctor, - .event_dtor = r535_gsp_event_dtor, -}; - static void r535_gsp_msgq_work(struct work_struct *work) { @@ -1092,10 +87,52 @@ r535_gsp_intr(struct nvkm_inth *inth) return IRQ_HANDLED; } +static bool +r535_gsp_xlat_mc_engine_idx(u32 mc_engine_idx, enum nvkm_subdev_type *ptype, int *pinst) +{ + switch (mc_engine_idx) { + case MC_ENGINE_IDX_GSP: + *ptype = NVKM_SUBDEV_GSP; + *pinst = 0; + return true; + case MC_ENGINE_IDX_DISP: + *ptype = NVKM_ENGINE_DISP; + *pinst = 0; + return true; + case MC_ENGINE_IDX_CE0 ... MC_ENGINE_IDX_CE9: + *ptype = NVKM_ENGINE_CE; + *pinst = mc_engine_idx - MC_ENGINE_IDX_CE0; + return true; + case MC_ENGINE_IDX_GR0: + *ptype = NVKM_ENGINE_GR; + *pinst = 0; + return true; + case MC_ENGINE_IDX_NVDEC0 ... MC_ENGINE_IDX_NVDEC7: + *ptype = NVKM_ENGINE_NVDEC; + *pinst = mc_engine_idx - MC_ENGINE_IDX_NVDEC0; + return true; + case MC_ENGINE_IDX_MSENC ... MC_ENGINE_IDX_MSENC2: + *ptype = NVKM_ENGINE_NVENC; + *pinst = mc_engine_idx - MC_ENGINE_IDX_MSENC; + return true; + case MC_ENGINE_IDX_NVJPEG0 ... MC_ENGINE_IDX_NVJPEG7: + *ptype = NVKM_ENGINE_NVJPG; + *pinst = mc_engine_idx - MC_ENGINE_IDX_NVJPEG0; + return true; + case MC_ENGINE_IDX_OFA0: + *ptype = NVKM_ENGINE_OFA; + *pinst = 0; + return true; + default: + return false; + } +} + static int r535_gsp_intr_get_table(struct nvkm_gsp *gsp) { NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_PARAMS *ctrl; + const struct nvkm_rm_api *rmapi = gsp->rm->api; int ret = 0; ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice, @@ -1118,42 +155,8 @@ r535_gsp_intr_get_table(struct nvkm_gsp *gsp) ctrl->table[i].engineIdx, ctrl->table[i].pmcIntrMask, ctrl->table[i].vectorStall, ctrl->table[i].vectorNonStall); - switch (ctrl->table[i].engineIdx) { - case MC_ENGINE_IDX_GSP: - type = NVKM_SUBDEV_GSP; - inst = 0; - break; - case MC_ENGINE_IDX_DISP: - type = NVKM_ENGINE_DISP; - inst = 0; - break; - case MC_ENGINE_IDX_CE0 ... MC_ENGINE_IDX_CE9: - type = NVKM_ENGINE_CE; - inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_CE0; - break; - case MC_ENGINE_IDX_GR0: - type = NVKM_ENGINE_GR; - inst = 0; - break; - case MC_ENGINE_IDX_NVDEC0 ... MC_ENGINE_IDX_NVDEC7: - type = NVKM_ENGINE_NVDEC; - inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_NVDEC0; - break; - case MC_ENGINE_IDX_MSENC ... MC_ENGINE_IDX_MSENC2: - type = NVKM_ENGINE_NVENC; - inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_MSENC; - break; - case MC_ENGINE_IDX_NVJPEG0 ... MC_ENGINE_IDX_NVJPEG7: - type = NVKM_ENGINE_NVJPG; - inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_NVJPEG0; - break; - case MC_ENGINE_IDX_OFA0: - type = NVKM_ENGINE_OFA; - inst = 0; - break; - default: + if (!rmapi->gsp->xlat_mc_engine_idx(ctrl->table[i].engineIdx, &type, &inst)) continue; - } if (WARN_ON(gsp->intr_nr == ARRAY_SIZE(gsp->intr))) { ret = -ENOSPC; @@ -1171,35 +174,14 @@ r535_gsp_intr_get_table(struct nvkm_gsp *gsp) return ret; } -static int -r535_gsp_rpc_get_gsp_static_info(struct nvkm_gsp *gsp) +void +r535_gsp_get_static_info_fb(struct nvkm_gsp *gsp, + const struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS *info) { - GspStaticConfigInfo *rpc; int last_usable = -1; - rpc = nvkm_gsp_rpc_rd(gsp, NV_VGPU_MSG_FUNCTION_GET_GSP_STATIC_INFO, sizeof(*rpc)); - if (IS_ERR(rpc)) - return PTR_ERR(rpc); - - gsp->internal.client.object.client = &gsp->internal.client; - gsp->internal.client.object.parent = NULL; - gsp->internal.client.object.handle = rpc->hInternalClient; - gsp->internal.client.gsp = gsp; - - gsp->internal.device.object.client = &gsp->internal.client; - gsp->internal.device.object.parent = &gsp->internal.client.object; - gsp->internal.device.object.handle = rpc->hInternalDevice; - - gsp->internal.device.subdevice.client = &gsp->internal.client; - gsp->internal.device.subdevice.parent = &gsp->internal.device.object; - gsp->internal.device.subdevice.handle = rpc->hInternalSubdevice; - - gsp->bar.rm_bar1_pdb = rpc->bar1PdeBase; - gsp->bar.rm_bar2_pdb = rpc->bar2PdeBase; - - for (int i = 0; i < rpc->fbRegionInfoParams.numFBRegions; i++) { - NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO *reg = - &rpc->fbRegionInfoParams.fbRegion[i]; + for (int i = 0; i < info->numFBRegions; i++) { + const NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO *reg = &info->fbRegion[i]; nvkm_debug(&gsp->subdev, "fb region %d: " "%016llx-%016llx rsvd:%016llx perf:%08x comp:%d iso:%d prot:%d\n", i, @@ -1221,10 +203,38 @@ r535_gsp_rpc_get_gsp_static_info(struct nvkm_gsp *gsp) } if (last_usable >= 0) { - u32 rsvd_base = rpc->fbRegionInfoParams.fbRegion[last_usable].limit + 1; + u32 rsvd_base = info->fbRegion[last_usable].limit + 1; gsp->fb.rsvd_size = gsp->fb.heap.addr - rsvd_base; } +} + +static int +r535_gsp_get_static_info(struct nvkm_gsp *gsp) +{ + GspStaticConfigInfo *rpc; + + rpc = nvkm_gsp_rpc_rd(gsp, NV_VGPU_MSG_FUNCTION_GET_GSP_STATIC_INFO, sizeof(*rpc)); + if (IS_ERR(rpc)) + return PTR_ERR(rpc); + + gsp->internal.client.object.client = &gsp->internal.client; + gsp->internal.client.object.parent = NULL; + gsp->internal.client.object.handle = rpc->hInternalClient; + gsp->internal.client.gsp = gsp; + + gsp->internal.device.object.client = &gsp->internal.client; + gsp->internal.device.object.parent = &gsp->internal.client.object; + gsp->internal.device.object.handle = rpc->hInternalDevice; + + gsp->internal.device.subdevice.client = &gsp->internal.client; + gsp->internal.device.subdevice.parent = &gsp->internal.device.object; + gsp->internal.device.subdevice.handle = rpc->hInternalSubdevice; + + gsp->bar.rm_bar1_pdb = rpc->bar1PdeBase; + gsp->bar.rm_bar2_pdb = rpc->bar2PdeBase; + + r535_gsp_get_static_info_fb(gsp, &rpc->fbRegionInfoParams); for (int gpc = 0; gpc < ARRAY_SIZE(rpc->tpcInfo); gpc++) { if (rpc->gpcInfo.gpcMask & BIT(gpc)) { @@ -1237,7 +247,7 @@ r535_gsp_rpc_get_gsp_static_info(struct nvkm_gsp *gsp) return 0; } -static void +void nvkm_gsp_mem_dtor(struct nvkm_gsp_mem *mem) { if (mem->data) { @@ -1266,7 +276,7 @@ nvkm_gsp_mem_dtor(struct nvkm_gsp_mem *mem) * so we take a device reference to ensure its lifetime. The reference is * dropped in the destructor. */ -static int +int nvkm_gsp_mem_ctor(struct nvkm_gsp *gsp, size_t size, struct nvkm_gsp_mem *mem) { mem->data = dma_alloc_coherent(gsp->subdev.device->dev, size, &mem->addr, GFP_KERNEL); @@ -1283,9 +293,10 @@ static int r535_gsp_postinit(struct nvkm_gsp *gsp) { struct nvkm_device *device = gsp->subdev.device; + const struct nvkm_rm_api *rmapi = gsp->rm->api; int ret; - ret = r535_gsp_rpc_get_gsp_static_info(gsp); + ret = rmapi->gsp->get_static_info(gsp); if (WARN_ON(ret)) return ret; @@ -1698,7 +709,7 @@ fail: } #if defined(CONFIG_ACPI) && defined(CONFIG_X86) -static void +void r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps) { const guid_t NVOP_DSM_GUID = @@ -1732,7 +743,7 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps) kfree(argv4.buffer.pointer); } -static void +void r535_gsp_acpi_jt(acpi_handle handle, JT_METHOD_DATA *jt) { const guid_t JT_DSM_GUID = @@ -1824,7 +835,7 @@ r535_gsp_acpi_mux(acpi_handle handle, DOD_METHOD_DATA *dod, MUX_METHOD_DATA *mux } } -static void +void r535_gsp_acpi_dod(acpi_handle handle, DOD_METHOD_DATA *dod) { acpi_status status; @@ -1877,7 +888,7 @@ r535_gsp_acpi_info(struct nvkm_gsp *gsp, ACPI_METHOD_DATA *acpi) } static int -r535_gsp_rpc_set_system_info(struct nvkm_gsp *gsp) +r535_gsp_set_system_info(struct nvkm_gsp *gsp) { struct nvkm_device *device = gsp->subdev.device; struct nvkm_device_pci *pdev = container_of(device, typeof(*pdev), device); @@ -1890,13 +901,13 @@ r535_gsp_rpc_set_system_info(struct nvkm_gsp *gsp) if (IS_ERR(info)) return PTR_ERR(info); - info->gpuPhysAddr = device->func->resource_addr(device, 0); - info->gpuPhysFbAddr = device->func->resource_addr(device, 1); - info->gpuPhysInstAddr = device->func->resource_addr(device, 3); + info->gpuPhysAddr = device->func->resource_addr(device, NVKM_BAR0_PRI); + info->gpuPhysFbAddr = device->func->resource_addr(device, NVKM_BAR1_FB); + info->gpuPhysInstAddr = device->func->resource_addr(device, NVKM_BAR2_INST); info->nvDomainBusDeviceFunc = pci_dev_id(pdev->pdev); info->maxUserVa = TASK_SIZE; - info->pciConfigMirrorBase = 0x088000; - info->pciConfigMirrorSize = 0x001000; + info->pciConfigMirrorBase = device->pci->func->cfg.addr; + info->pciConfigMirrorSize = device->pci->func->cfg.size; r535_gsp_acpi_info(gsp, &info->acpiMethodData); return nvkm_gsp_rpc_wr(gsp, info, NVKM_GSP_RPC_REPLY_NOWAIT); @@ -1917,33 +928,6 @@ r535_gsp_msg_os_error_log(void *priv, u32 fn, void *repv, u32 repc) } static int -r535_gsp_msg_rc_triggered(void *priv, u32 fn, void *repv, u32 repc) -{ - rpc_rc_triggered_v17_02 *msg = repv; - struct nvkm_gsp *gsp = priv; - struct nvkm_subdev *subdev = &gsp->subdev; - struct nvkm_chan *chan; - unsigned long flags; - - if (WARN_ON(repc < sizeof(*msg))) - return -EINVAL; - - nvkm_error(subdev, "rc engn:%08x chid:%d type:%d scope:%d part:%d\n", - msg->nv2080EngineType, msg->chid, msg->exceptType, msg->scope, - msg->partitionAttributionId); - - chan = nvkm_chan_get_chid(&subdev->device->fifo->engine, msg->chid / 8, &flags); - if (!chan) { - nvkm_error(subdev, "rc chid:%d not found!\n", msg->chid); - return 0; - } - - nvkm_chan_error(chan, false); - nvkm_chan_put(&chan, flags); - return 0; -} - -static int r535_gsp_msg_mmu_fault_queued(void *priv, u32 fn, void *repv, u32 repc) { struct nvkm_gsp *gsp = priv; @@ -2136,97 +1120,6 @@ r535_gsp_msg_run_cpu_sequencer(void *priv, u32 fn, void *repv, u32 repc) } static int -r535_gsp_booter_unload(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) -{ - struct nvkm_subdev *subdev = &gsp->subdev; - struct nvkm_device *device = subdev->device; - u32 wpr2_hi; - int ret; - - wpr2_hi = nvkm_rd32(device, 0x1fa828); - if (!wpr2_hi) { - nvkm_debug(subdev, "WPR2 not set - skipping booter unload\n"); - return 0; - } - - ret = nvkm_falcon_fw_boot(&gsp->booter.unload, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); - if (WARN_ON(ret)) - return ret; - - wpr2_hi = nvkm_rd32(device, 0x1fa828); - if (WARN_ON(wpr2_hi)) - return -EIO; - - return 0; -} - -static int -r535_gsp_booter_load(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) -{ - int ret; - - ret = nvkm_falcon_fw_boot(&gsp->booter.load, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); - if (ret) - return ret; - - nvkm_falcon_wr32(&gsp->falcon, 0x080, gsp->boot.app_version); - - if (WARN_ON(!nvkm_falcon_riscv_active(&gsp->falcon))) - return -EIO; - - return 0; -} - -static int -r535_gsp_wpr_meta_init(struct nvkm_gsp *gsp) -{ - GspFwWprMeta *meta; - int ret; - - ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->wpr_meta); - if (ret) - return ret; - - meta = gsp->wpr_meta.data; - - meta->magic = GSP_FW_WPR_META_MAGIC; - meta->revision = GSP_FW_WPR_META_REVISION; - - meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr; - meta->sizeOfRadix3Elf = gsp->fb.wpr2.elf.size; - - meta->sysmemAddrOfBootloader = gsp->boot.fw.addr; - meta->sizeOfBootloader = gsp->boot.fw.size; - meta->bootloaderCodeOffset = gsp->boot.code_offset; - meta->bootloaderDataOffset = gsp->boot.data_offset; - meta->bootloaderManifestOffset = gsp->boot.manifest_offset; - - meta->sysmemAddrOfSignature = gsp->sig.addr; - meta->sizeOfSignature = gsp->sig.size; - - meta->gspFwRsvdStart = gsp->fb.heap.addr; - meta->nonWprHeapOffset = gsp->fb.heap.addr; - meta->nonWprHeapSize = gsp->fb.heap.size; - meta->gspFwWprStart = gsp->fb.wpr2.addr; - meta->gspFwHeapOffset = gsp->fb.wpr2.heap.addr; - meta->gspFwHeapSize = gsp->fb.wpr2.heap.size; - meta->gspFwOffset = gsp->fb.wpr2.elf.addr; - meta->bootBinOffset = gsp->fb.wpr2.boot.addr; - meta->frtsOffset = gsp->fb.wpr2.frts.addr; - meta->frtsSize = gsp->fb.wpr2.frts.size; - meta->gspFwWprEnd = ALIGN_DOWN(gsp->fb.bios.vga_workspace.addr, 0x20000); - meta->fbSize = gsp->fb.size; - meta->vgaWorkspaceOffset = gsp->fb.bios.vga_workspace.addr; - meta->vgaWorkspaceSize = gsp->fb.bios.vga_workspace.size; - meta->bootCount = 0; - meta->partitionRpcAddr = 0; - meta->partitionRpcRequestOffset = 0; - meta->partitionRpcReplyOffset = 0; - meta->verified = 0; - return 0; -} - -static int r535_gsp_shared_init(struct nvkm_gsp *gsp) { struct { @@ -2277,23 +1170,11 @@ r535_gsp_shared_init(struct nvkm_gsp *gsp) return 0; } -static int -r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume) +static void +r535_gsp_set_rmargs(struct nvkm_gsp *gsp, bool resume) { - GSP_ARGUMENTS_CACHED *args; - int ret; - - if (!resume) { - ret = r535_gsp_shared_init(gsp); - if (ret) - return ret; + GSP_ARGUMENTS_CACHED *args = gsp->rmargs.data; - ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->rmargs); - if (ret) - return ret; - } - - args = gsp->rmargs.data; args->messageQueueInitArguments.sharedMemPhysAddr = gsp->shm.mem.addr; args->messageQueueInitArguments.pageTableEntryCount = gsp->shm.ptes.nr; args->messageQueueInitArguments.cmdQueueOffset = @@ -2310,7 +1191,24 @@ r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume) args->srInitArguments.flags = 0; args->srInitArguments.bInPMTransition = 1; } +} +static int +r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume) +{ + int ret; + + if (!resume) { + ret = r535_gsp_shared_init(gsp); + if (ret) + return ret; + + ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->rmargs); + if (ret) + return ret; + } + + gsp->rm->api->gsp->set_rmargs(gsp, resume); return 0; } @@ -2803,18 +1701,22 @@ lvl1_fail: return ret; } +static u32 +r535_gsp_sr_data_size(struct nvkm_gsp *gsp) +{ + GspFwWprMeta *meta = gsp->wpr_meta.data; + + return meta->gspFwWprEnd - meta->gspFwWprStart; +} + int r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) { - u32 mbox0 = 0xff, mbox1 = 0xff; + struct nvkm_rm *rm = gsp->rm; int ret; - if (!gsp->running) - return 0; - if (suspend) { - GspFwWprMeta *meta = gsp->wpr_meta.data; - u64 len = meta->gspFwWprEnd - meta->gspFwWprStart; + u32 len = rm->api->gsp->sr_data_size(gsp); GspFwSRMeta *sr; ret = nvkm_gsp_sg(gsp->subdev.device, len, &gsp->sr.sgt); @@ -2835,8 +1737,13 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr; sr->sizeOfSuspendResumeData = len; - mbox0 = lower_32_bits(gsp->sr.meta.addr); - mbox1 = upper_32_bits(gsp->sr.meta.addr); + ret = rm->api->fbsr->suspend(gsp); + if (ret) { + nvkm_gsp_mem_dtor(&gsp->sr.meta); + nvkm_gsp_radix3_dtor(gsp, &gsp->sr.radix3); + nvkm_gsp_sg_free(gsp->subdev.device, &gsp->sr.sgt); + return ret; + } } ret = r535_gsp_rpc_unloading_guest_driver(gsp, suspend); @@ -2844,18 +1751,10 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) return ret; nvkm_msec(gsp->subdev.device, 2000, - if (nvkm_falcon_rd32(&gsp->falcon, 0x040) & 0x80000000) + if (nvkm_falcon_rd32(&gsp->falcon, 0x040) == 0x80000000) break; ); - nvkm_falcon_reset(&gsp->falcon); - - ret = nvkm_gsp_fwsec_sb(gsp); - WARN_ON(ret); - - ret = r535_gsp_booter_unload(gsp, mbox0, mbox1); - WARN_ON(ret); - gsp->running = false; return 0; } @@ -2863,23 +1762,12 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend) int r535_gsp_init(struct nvkm_gsp *gsp) { - u32 mbox0, mbox1; int ret; - if (!gsp->sr.meta.data) { - mbox0 = lower_32_bits(gsp->wpr_meta.addr); - mbox1 = upper_32_bits(gsp->wpr_meta.addr); - } else { - r535_gsp_rmargs_init(gsp, true); - - mbox0 = lower_32_bits(gsp->sr.meta.addr); - mbox1 = upper_32_bits(gsp->sr.meta.addr); - } + nvkm_falcon_wr32(&gsp->falcon, 0x080, gsp->boot.app_version); - /* Execute booter to handle (eventually...) booting GSP-RM. */ - ret = r535_gsp_booter_load(gsp, mbox0, mbox1); - if (WARN_ON(ret)) - goto done; + if (WARN_ON(!nvkm_falcon_riscv_active(&gsp->falcon))) + return -EIO; ret = r535_gsp_rpc_poll(gsp, NV_VGPU_MSG_EVENT_GSP_INIT_DONE); if (ret) @@ -2889,6 +1777,8 @@ r535_gsp_init(struct nvkm_gsp *gsp) done: if (gsp->sr.meta.data) { + gsp->rm->api->fbsr->resume(gsp); + nvkm_gsp_mem_dtor(&gsp->sr.meta); nvkm_gsp_radix3_dtor(gsp, &gsp->sr.radix3); nvkm_gsp_sg_free(gsp->subdev.device, &gsp->sr.sgt); @@ -2950,19 +1840,6 @@ r535_gsp_elf_section(struct nvkm_gsp *gsp, const char *name, const u8 **pdata, u return -ENOENT; } -static void -r535_gsp_dtor_fws(struct nvkm_gsp *gsp) -{ - nvkm_firmware_put(gsp->fws.bl); - gsp->fws.bl = NULL; - nvkm_firmware_put(gsp->fws.booter.unload); - gsp->fws.booter.unload = NULL; - nvkm_firmware_put(gsp->fws.booter.load); - gsp->fws.booter.load = NULL; - nvkm_firmware_put(gsp->fws.rm); - gsp->fws.rm = NULL; -} - #ifdef CONFIG_DEBUG_FS struct r535_gsp_log { @@ -3196,10 +2073,16 @@ r535_gsp_dtor(struct nvkm_gsp *gsp) nvkm_falcon_fw_dtor(&gsp->booter.unload); nvkm_falcon_fw_dtor(&gsp->booter.load); + nvkm_gsp_mem_dtor(&gsp->fmc.args); + kfree(gsp->fmc.sig); + kfree(gsp->fmc.pkey); + kfree(gsp->fmc.hash); + nvkm_gsp_mem_dtor(&gsp->fmc.fw); + mutex_destroy(&gsp->msgq.mutex); mutex_destroy(&gsp->cmdq.mutex); - r535_gsp_dtor_fws(gsp); + nvkm_gsp_dtor_fws(gsp); nvkm_gsp_mem_dtor(&gsp->rmargs); nvkm_gsp_mem_dtor(&gsp->wpr_meta); @@ -3212,10 +2095,17 @@ r535_gsp_dtor(struct nvkm_gsp *gsp) nvkm_gsp_mem_dtor(&gsp->logrm); } +static void +r535_gsp_drop_send_user_shared_data(struct nvkm_gsp *gsp) +{ + r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_SEND_USER_SHARED_DATA, NULL, NULL); +} + int r535_gsp_oneinit(struct nvkm_gsp *gsp) { struct nvkm_device *device = gsp->subdev.device; + const struct nvkm_rm_api *rmapi = gsp->rm->api; const u8 *data; u64 size; int ret; @@ -3223,16 +2113,6 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) mutex_init(&gsp->cmdq.mutex); mutex_init(&gsp->msgq.mutex); - ret = gsp->func->booter.ctor(gsp, "booter-load", gsp->fws.booter.load, - &device->sec2->falcon, &gsp->booter.load); - if (ret) - return ret; - - ret = gsp->func->booter.ctor(gsp, "booter-unload", gsp->fws.booter.unload, - &device->sec2->falcon, &gsp->booter.unload); - if (ret) - return ret; - /* Load GSP firmware from ELF image into DMA-accessible memory. */ ret = r535_gsp_elf_section(gsp, ".fwimage", &data, &size); if (ret) @@ -3261,65 +2141,29 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_RUN_CPU_SEQUENCER, r535_gsp_msg_run_cpu_sequencer, gsp); r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_POST_EVENT, r535_gsp_msg_post_event, gsp); - r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_RC_TRIGGERED, - r535_gsp_msg_rc_triggered, gsp); + r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_RC_TRIGGERED, rmapi->fifo->rc_triggered, gsp); r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_MMU_FAULT_QUEUED, r535_gsp_msg_mmu_fault_queued, gsp); r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_OS_ERROR_LOG, r535_gsp_msg_os_error_log, gsp); r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_PERF_BRIDGELESS_INFO_UPDATE, NULL, NULL); r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_UCODE_LIBOS_PRINT, NULL, NULL); - r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_SEND_USER_SHARED_DATA, NULL, NULL); + if (rmapi->gsp->drop_send_user_shared_data) + rmapi->gsp->drop_send_user_shared_data(gsp); + if (rmapi->gsp->drop_post_nocat_record) + rmapi->gsp->drop_post_nocat_record(gsp); + ret = r535_gsp_rm_boot_ctor(gsp); if (ret) return ret; /* Release FW images - we've copied them to DMA buffers now. */ - r535_gsp_dtor_fws(gsp); - - /* Calculate FB layout. */ - gsp->fb.wpr2.frts.size = 0x100000; - gsp->fb.wpr2.frts.addr = ALIGN_DOWN(gsp->fb.bios.addr, 0x20000) - gsp->fb.wpr2.frts.size; - - gsp->fb.wpr2.boot.size = gsp->boot.fw.size; - gsp->fb.wpr2.boot.addr = ALIGN_DOWN(gsp->fb.wpr2.frts.addr - gsp->fb.wpr2.boot.size, 0x1000); - - gsp->fb.wpr2.elf.size = gsp->fw.len; - gsp->fb.wpr2.elf.addr = ALIGN_DOWN(gsp->fb.wpr2.boot.addr - gsp->fb.wpr2.elf.size, 0x10000); - - { - u32 fb_size_gb = DIV_ROUND_UP_ULL(gsp->fb.size, 1 << 30); - - gsp->fb.wpr2.heap.size = - gsp->func->wpr_heap.os_carveout_size + - gsp->func->wpr_heap.base_size + - ALIGN(GSP_FW_HEAP_PARAM_SIZE_PER_GB_FB * fb_size_gb, 1 << 20) + - ALIGN(GSP_FW_HEAP_PARAM_CLIENT_ALLOC_SIZE, 1 << 20); - - gsp->fb.wpr2.heap.size = max(gsp->fb.wpr2.heap.size, gsp->func->wpr_heap.min_size); - } - - gsp->fb.wpr2.heap.addr = ALIGN_DOWN(gsp->fb.wpr2.elf.addr - gsp->fb.wpr2.heap.size, 0x100000); - gsp->fb.wpr2.heap.size = ALIGN_DOWN(gsp->fb.wpr2.elf.addr - gsp->fb.wpr2.heap.addr, 0x100000); - - gsp->fb.wpr2.addr = ALIGN_DOWN(gsp->fb.wpr2.heap.addr - sizeof(GspFwWprMeta), 0x100000); - gsp->fb.wpr2.size = gsp->fb.wpr2.frts.addr + gsp->fb.wpr2.frts.size - gsp->fb.wpr2.addr; - - gsp->fb.heap.size = 0x100000; - gsp->fb.heap.addr = gsp->fb.wpr2.addr - gsp->fb.heap.size; - - ret = nvkm_gsp_fwsec_frts(gsp); - if (WARN_ON(ret)) - return ret; + nvkm_gsp_dtor_fws(gsp); ret = r535_gsp_libos_init(gsp); if (WARN_ON(ret)) return ret; - ret = r535_gsp_wpr_meta_init(gsp); - if (WARN_ON(ret)) - return ret; - - ret = r535_gsp_rpc_set_system_info(gsp); + ret = rmapi->gsp->set_system_info(gsp); if (WARN_ON(ret)) return ret; @@ -3327,76 +2171,17 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp) if (WARN_ON(ret)) return ret; - /* Reset GSP into RISC-V mode. */ - ret = gsp->func->reset(gsp); - if (WARN_ON(ret)) - return ret; - - nvkm_falcon_wr32(&gsp->falcon, 0x040, lower_32_bits(gsp->libos.addr)); - nvkm_falcon_wr32(&gsp->falcon, 0x044, upper_32_bits(gsp->libos.addr)); - mutex_init(&gsp->client_id.mutex); idr_init(&gsp->client_id.idr); return 0; } -static int -r535_gsp_load_fw(struct nvkm_gsp *gsp, const char *name, const char *ver, - const struct firmware **pfw) -{ - char fwname[64]; - - snprintf(fwname, sizeof(fwname), "gsp/%s-%s", name, ver); - return nvkm_firmware_get(&gsp->subdev, fwname, 0, pfw); -} - -int -r535_gsp_load(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif *fwif) -{ - struct nvkm_subdev *subdev = &gsp->subdev; - int ret; - bool enable_gsp = fwif->enable; - -#if IS_ENABLED(CONFIG_DRM_NOUVEAU_GSP_DEFAULT) - enable_gsp = true; -#endif - if (!nvkm_boolopt(subdev->device->cfgopt, "NvGspRm", enable_gsp)) - return -EINVAL; - - if ((ret = r535_gsp_load_fw(gsp, "gsp", fwif->ver, &gsp->fws.rm)) || - (ret = r535_gsp_load_fw(gsp, "booter_load", fwif->ver, &gsp->fws.booter.load)) || - (ret = r535_gsp_load_fw(gsp, "booter_unload", fwif->ver, &gsp->fws.booter.unload)) || - (ret = r535_gsp_load_fw(gsp, "bootloader", fwif->ver, &gsp->fws.bl))) { - r535_gsp_dtor_fws(gsp); - return ret; - } - - return 0; -} - -#define NVKM_GSP_FIRMWARE(chip) \ -MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_load-535.113.01.bin"); \ -MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_unload-535.113.01.bin"); \ -MODULE_FIRMWARE("nvidia/"#chip"/gsp/bootloader-535.113.01.bin"); \ -MODULE_FIRMWARE("nvidia/"#chip"/gsp/gsp-535.113.01.bin") - -NVKM_GSP_FIRMWARE(tu102); -NVKM_GSP_FIRMWARE(tu104); -NVKM_GSP_FIRMWARE(tu106); - -NVKM_GSP_FIRMWARE(tu116); -NVKM_GSP_FIRMWARE(tu117); - -NVKM_GSP_FIRMWARE(ga100); - -NVKM_GSP_FIRMWARE(ga102); -NVKM_GSP_FIRMWARE(ga103); -NVKM_GSP_FIRMWARE(ga104); -NVKM_GSP_FIRMWARE(ga106); -NVKM_GSP_FIRMWARE(ga107); - -NVKM_GSP_FIRMWARE(ad102); -NVKM_GSP_FIRMWARE(ad103); -NVKM_GSP_FIRMWARE(ad104); -NVKM_GSP_FIRMWARE(ad106); -NVKM_GSP_FIRMWARE(ad107); +const struct nvkm_rm_api_gsp +r535_gsp = { + .set_rmargs = r535_gsp_set_rmargs, + .set_system_info = r535_gsp_set_system_info, + .get_static_info = r535_gsp_get_static_info, + .xlat_mc_engine_idx = r535_gsp_xlat_mc_engine_idx, + .drop_send_user_shared_data = r535_gsp_drop_send_user_shared_data, + .sr_data_size = r535_gsp_sr_data_size, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ad102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvdec.c index 1b4619ff9e8e..a8c42ec0367b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/ad102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvdec.c @@ -19,26 +19,27 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include <rm/engine.h> -#include <subdev/gsp.h> +#include "nvrm/nvdec.h" -#include <nvif/class.h> +static int +r535_nvdec_alloc(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *nvdec) +{ + NV_BSP_ALLOCATION_PARAMETERS *args; -static const struct nvkm_engine_func -ad102_nvenc = { - .sclass = { - { -1, -1, NVC9B7_VIDEO_ENCODER }, - {} - } -}; + args = nvkm_gsp_rm_alloc_get(chan, handle, class, sizeof(*args), nvdec); + if (WARN_ON(IS_ERR(args))) + return PTR_ERR(args); -int -ad102_nvenc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_nvenc **pnvenc) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvenc_new(&ad102_nvenc, device, type, inst, pnvenc); + args->size = sizeof(*args); + args->engineInstance = inst; - return -ENODEV; + return nvkm_gsp_rm_alloc_wr(nvdec, args); } + +const struct nvkm_rm_api_engine +r535_nvdec = { + .alloc = r535_nvdec_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ad102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvenc.c index 7bfa6240d283..acb3ce8bb9de 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ad102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvenc.c @@ -19,28 +19,27 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "gf100.h" +#include <rm/engine.h> -#include <subdev/gsp.h> +#include "nvrm/nvenc.h" -#include <nvif/class.h> +static int +r535_nvenc_alloc(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *nvenc) +{ + NV_MSENC_ALLOCATION_PARAMETERS *args; -static const struct gf100_gr_func -ad102_gr = { - .sclass = { - { -1, -1, FERMI_TWOD_A }, - { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, - { -1, -1, ADA_A }, - { -1, -1, ADA_COMPUTE_A }, - {} - } -}; + args = nvkm_gsp_rm_alloc_get(chan, handle, class, sizeof(*args), nvenc); + if (WARN_ON(IS_ERR(args))) + return PTR_ERR(args); -int -ad102_gr_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_gr **pgr) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_gr_new(&ad102_gr, device, type, inst, pgr); + args->size = sizeof(*args); + args->engineInstance = inst; - return -ENODEV; + return nvkm_gsp_rm_alloc_wr(nvenc, args); } + +const struct nvkm_rm_api_engine +r535_nvenc = { + .alloc = r535_nvenc_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c new file mode 100644 index 000000000000..fbc4080ad8d8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvjpg.c @@ -0,0 +1,45 @@ +/* + * Copyright 2023 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include <rm/engine.h> + +#include "nvrm/nvjpg.h" + +static int +r535_nvjpg_alloc(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *nvjpg) +{ + NV_NVJPG_ALLOCATION_PARAMETERS *args; + + args = nvkm_gsp_rm_alloc_get(chan, handle, class, sizeof(*args), nvjpg); + if (WARN_ON(IS_ERR(args))) + return PTR_ERR(args); + + args->size = sizeof(*args); + args->engineInstance = inst; + + return nvkm_gsp_rm_alloc_wr(nvjpg, args); +} + +const struct nvkm_rm_api_engine +r535_nvjpg = { + .alloc = r535_nvjpg_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/alloc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/alloc.h new file mode 100644 index 000000000000..cbc7e611fbda --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/alloc.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_ALLOC_H__ +#define __NVRM_ALLOC_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +typedef struct rpc_gsp_rm_alloc_v03_00 +{ + NvHandle hClient; + NvHandle hParent; + NvHandle hObject; + NvU32 hClass; + NvU32 status; + NvU32 paramsSize; + NvU32 flags; + NvU8 reserved[4]; + NvU8 params[]; +} rpc_gsp_rm_alloc_v03_00; + +typedef struct NVOS00_PARAMETERS_v03_00 +{ + NvHandle hRoot; + NvHandle hObjectParent; + NvHandle hObjectOld; + NvV32 status; +} NVOS00_PARAMETERS_v03_00; + +typedef struct rpc_free_v03_00 +{ + NVOS00_PARAMETERS_v03_00 params; +} rpc_free_v03_00; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/bar.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/bar.h new file mode 100644 index 000000000000..60b0b08491ee --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/bar.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_BAR_H__ +#define __NVRM_BAR_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +typedef enum +{ + NV_RPC_UPDATE_PDE_BAR_1, + NV_RPC_UPDATE_PDE_BAR_2, + NV_RPC_UPDATE_PDE_BAR_INVALID, +} NV_RPC_UPDATE_PDE_BAR_TYPE; + +typedef struct UpdateBarPde_v15_00 +{ + NV_RPC_UPDATE_PDE_BAR_TYPE barType; + NvU64 entryValue NV_ALIGN_BYTES(8); + NvU64 entryLevelShift NV_ALIGN_BYTES(8); +} UpdateBarPde_v15_00; + +typedef struct rpc_update_bar_pde_v15_00 +{ + UpdateBarPde_v15_00 info; +} rpc_update_bar_pde_v15_00; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ce.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ce.h new file mode 100644 index 000000000000..90b0325203d2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ce.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_CE_H__ +#define __NVRM_CE_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +typedef struct NVC0B5_ALLOCATION_PARAMETERS { + NvU32 version; + NvU32 engineType; +} NVC0B5_ALLOCATION_PARAMETERS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/client.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/client.h new file mode 100644 index 000000000000..df0e63c0cb6b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/client.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_CLIENT_H__ +#define __NVRM_CLIENT_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +#define NV01_ROOT (0x0U) /* finn: Evaluated from "NV0000_ALLOC_PARAMETERS_MESSAGE_ID" */ + +#define NV_PROC_NAME_MAX_LENGTH 100U + +typedef struct NV0000_ALLOC_PARAMETERS { + NvHandle hClient; /* CORERM-2934: hClient must remain the first member until all allocations use these params */ + NvU32 processID; + char processName[NV_PROC_NAME_MAX_LENGTH]; +} NV0000_ALLOC_PARAMETERS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ctrl.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ctrl.h new file mode 100644 index 000000000000..77f10acd82c9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ctrl.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_CTRL_H__ +#define __NVRM_CTRL_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +typedef struct rpc_gsp_rm_control_v03_00 +{ + NvHandle hClient; + NvHandle hObject; + NvU32 cmd; + NvU32 status; + NvU32 paramsSize; + NvU32 flags; + NvU8 params[]; +} rpc_gsp_rm_control_v03_00; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/device.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/device.h new file mode 100644 index 000000000000..3933b9ad61ce --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/device.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_DEVICE_H__ +#define __NVRM_DEVICE_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +#define NV01_DEVICE_0 (0x80U) /* finn: Evaluated from "NV0080_ALLOC_PARAMETERS_MESSAGE_ID" */ + +typedef struct NV0080_ALLOC_PARAMETERS { + NvU32 deviceId; + NvHandle hClientShare; + NvHandle hTargetClient; + NvHandle hTargetDevice; + NvV32 flags; + NV_DECLARE_ALIGNED(NvU64 vaSpaceSize, 8); + NV_DECLARE_ALIGNED(NvU64 vaStartInternal, 8); + NV_DECLARE_ALIGNED(NvU64 vaLimitInternal, 8); + NvV32 vaMode; +} NV0080_ALLOC_PARAMETERS; + +#define NV20_SUBDEVICE_0 (0x2080U) /* finn: Evaluated from "NV2080_ALLOC_PARAMETERS_MESSAGE_ID" */ + +typedef struct NV2080_ALLOC_PARAMETERS { + NvU32 subDeviceId; +} NV2080_ALLOC_PARAMETERS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/disp.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/disp.h new file mode 100644 index 000000000000..7b7539639540 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/disp.h @@ -0,0 +1,741 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_DISP_H__ +#define __NVRM_DISP_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +#define NV2080_CTRL_CMD_INTERNAL_DISPLAY_WRITE_INST_MEM (0x20800a49) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS { + NV_DECLARE_ALIGNED(NvU64 instMemPhysAddr, 8); + NV_DECLARE_ALIGNED(NvU64 instMemSize, 8); + NvU32 instMemAddrSpace; + NvU32 instMemCpuCacheAttr; +} NV2080_CTRL_INTERNAL_DISPLAY_WRITE_INST_MEM_PARAMS; + +#define NV_MEMORY_WRITECOMBINED 2 + +#define NV04_DISPLAY_COMMON (0x00000073) + +#define NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO (0x20800a01) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS { + NvU32 feHwSysCap; + NvU32 windowPresentMask; + NvBool bFbRemapperEnabled; + NvU32 numHeads; + NvBool bPrimaryVga; + NvU32 i2cPort; + NvU32 internalDispActiveMask; +} NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS; + +#define NV2080_CTRL_ACPI_DSM_READ_SIZE (0x1000) /* finn: Evaluated from "(4 * 1024)" */ + +#define NV2080_CTRL_CMD_INTERNAL_INIT_BRIGHTC_STATE_LOAD (0x20800ac6) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_INIT_BRIGHTC_STATE_LOAD_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_INIT_BRIGHTC_STATE_LOAD_PARAMS { + NvU32 status; + NvU16 backLightDataSize; + NvU8 backLightData[NV2080_CTRL_ACPI_DSM_READ_SIZE]; +} NV2080_CTRL_INTERNAL_INIT_BRIGHTC_STATE_LOAD_PARAMS; + +typedef struct NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT_PARAMS { + NvU32 subDeviceInstance; +} NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT_PARAMS; + +#define NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT (0x731365U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_SET_MANUAL_DISPLAYPORT_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_CMD_SYSTEM_GET_NUM_HEADS (0x730102U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_NUM_HEADS_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SYSTEM_GET_NUM_HEADS_PARAMS { + NvU32 subDeviceInstance; + NvU32 flags; + NvU32 numHeads; +} NV0073_CTRL_SYSTEM_GET_NUM_HEADS_PARAMS; + +#define NV0073_CTRL_CMD_SPECIFIC_GET_ALL_HEAD_MASK (0x730287U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_ALL_HEAD_MASK_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SPECIFIC_GET_ALL_HEAD_MASK_PARAMS { + NvU32 subDeviceInstance; + NvU32 headMask; +} NV0073_CTRL_SPECIFIC_GET_ALL_HEAD_MASK_PARAMS; + +#define NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED (0x730120U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayMask; + NvU32 displayMaskDDC; +} NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS; + +#define NV0073_CTRL_MAX_CONNECTORS 4U + +#define NV0073_CTRL_CMD_SPECIFIC_GET_CONNECTOR_DATA (0x730250U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 flags; + NvU32 DDCPartners; + NvU32 count; + struct { + NvU32 index; + NvU32 type; + NvU32 location; + } data[NV0073_CTRL_MAX_CONNECTORS]; + NvU32 platform; +} NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS; + +#define NV0073_CTRL_CMD_SPECIFIC_OR_GET_INFO (0x73028bU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 index; + NvU32 type; + NvU32 protocol; + NvU32 ditherType; + NvU32 ditherAlgo; + NvU32 location; + NvU32 rootPortId; + NvU32 dcbIndex; + NV_DECLARE_ALIGNED(NvU64 vbiosAddress, 8); + NvBool bIsLitByVbios; + NvBool bIsDispDynamic; +} NV0073_CTRL_SPECIFIC_OR_GET_INFO_PARAMS; + +#define NV0073_CTRL_SPECIFIC_OR_TYPE_NONE (0x00000000U) +#define NV0073_CTRL_SPECIFIC_OR_TYPE_DAC (0x00000001U) +#define NV0073_CTRL_SPECIFIC_OR_TYPE_SOR (0x00000002U) +#define NV0073_CTRL_SPECIFIC_OR_TYPE_PIOR (0x00000003U) +#define NV0073_CTRL_SPECIFIC_OR_TYPE_DSI (0x00000005U) + +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_DAC_RGB_CRT (0x00000000U) +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_LVDS_CUSTOM (0x00000000U) +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_A (0x00000001U) +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_SINGLE_TMDS_B (0x00000002U) +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DUAL_TMDS (0x00000005U) +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DP_A (0x00000008U) +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DP_B (0x00000009U) +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_SOR_DSI (0x00000010U) +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_DSI (0x00000011U) +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_PIOR_EXT_TMDS_ENC (0x00000000U) +#define NV0073_CTRL_SPECIFIC_OR_PROTOCOL_UNKNOWN (0xFFFFFFFFU) + +#define NV0073_CTRL_CMD_DP_GET_CAPS (0x731369U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS_MESSAGE_ID" */ + +typedef struct NV0073_CTRL_CMD_DSC_CAP_PARAMS { + NvBool bDscSupported; + NvU32 encoderColorFormatMask; + NvU32 lineBufferSizeKB; + NvU32 rateBufferSizeKB; + NvU32 bitsPerPixelPrecision; + NvU32 maxNumHztSlices; + NvU32 lineBufferBitDepth; +} NV0073_CTRL_CMD_DSC_CAP_PARAMS; + +typedef struct NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS { + NvU32 subDeviceInstance; + NvU32 sorIndex; + NvU32 maxLinkRate; + NvU32 dpVersionsSupported; + NvU32 UHBRSupported; + NvBool bIsMultistreamSupported; + NvBool bIsSCEnabled; + NvBool bHasIncreasedWatermarkLimits; + NvBool bIsPC2Disabled; + NvBool isSingleHeadMSTSupported; + NvBool bFECSupported; + NvBool bIsTrainPhyRepeater; + NvBool bOverrideLinkBw; + NV0073_CTRL_CMD_DSC_CAP_PARAMS DSC; +} NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS; + +#define NV0073_CTRL_CMD_DP_GET_CAPS (0x731369U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS_MESSAGE_ID" */ +#define NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS_MESSAGE_ID (0x69U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_2 0:0 +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_2_NO (0x00000000U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_2_YES (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_4 1:1 +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_4_NO (0x00000000U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_4_YES (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE 2:0 +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_NONE (0x00000000U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62 (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70 (0x00000002U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40 (0x00000003U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10 (0x00000004U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_RGB (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_444 (0x00000002U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_NATIVE_422 (0x00000004U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_NATIVE_420 (0x00000008U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_16 (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_8 (0x00000002U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_4 (0x00000003U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_2 (0x00000004U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1 (0x00000005U) + +#define NV2080_NOTIFIERS_HOTPLUG (1) + +typedef struct { + NvU32 plugDisplayMask; + NvU32 unplugDisplayMask; +} Nv2080HotplugNotification; + +#define NV2080_NOTIFIERS_DP_IRQ (7) + +typedef struct Nv2080DpIrqNotificationRec { + NvU32 displayId; +} Nv2080DpIrqNotification; + +#define NV0073_CTRL_CMD_SYSTEM_GET_CONNECT_STATE (0x730122U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS { + NvU32 subDeviceInstance; + NvU32 flags; + NvU32 displayMask; + NvU32 retryTimeMs; +} NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS; + +#define NV0073_CTRL_CMD_DFP_GET_INFO (0x731140U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DFP_INTERFACE_ID << 8) | NV0073_CTRL_DFP_GET_INFO_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_DFP_GET_INFO_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 flags; + NvU32 flags2; +} NV0073_CTRL_DFP_GET_INFO_PARAMS; + +#define NV0073_CTRL_DFP_FLAGS_SIGNAL 2:0 +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_TMDS (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_LVDS (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_SDI (0x00000002U) +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_DISPLAYPORT (0x00000003U) +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_DSI (0x00000004U) +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_WRBK (0x00000005U) +#define NV0073_CTRL_DFP_FLAGS_LANE 5:3 +#define NV0073_CTRL_DFP_FLAGS_LANE_NONE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_LANE_SINGLE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_LANE_DUAL (0x00000002U) +#define NV0073_CTRL_DFP_FLAGS_LANE_QUAD (0x00000003U) +#define NV0073_CTRL_DFP_FLAGS_LANE_OCT (0x00000004U) +#define NV0073_CTRL_DFP_FLAGS_LIMIT 6:6 +#define NV0073_CTRL_DFP_FLAGS_LIMIT_DISABLE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_LIMIT_60HZ_RR (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_SLI_SCALER 7:7 +#define NV0073_CTRL_DFP_FLAGS_SLI_SCALER_NORMAL (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_SLI_SCALER_DISABLE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_HDMI_CAPABLE 8:8 +#define NV0073_CTRL_DFP_FLAGS_HDMI_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_HDMI_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_RANGE_LIMITED_CAPABLE 9:9 +#define NV0073_CTRL_DFP_FLAGS_RANGE_LIMITED_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_RANGE_LIMITED_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_RANGE_AUTO_CAPABLE 10:10 +#define NV0073_CTRL_DFP_FLAGS_RANGE_AUTO_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_RANGE_AUTO_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR422_CAPABLE 11:11 +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR422_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR422_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR444_CAPABLE 12:12 +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR444_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR444_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_HDMI_ALLOWED 14:14 +#define NV0073_CTRL_DFP_FLAGS_HDMI_ALLOWED_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_HDMI_ALLOWED_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_EMBEDDED_DISPLAYPORT 15:15 +#define NV0073_CTRL_DFP_FLAGS_EMBEDDED_DISPLAYPORT_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_EMBEDDED_DISPLAYPORT_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_CONSTRAINT 16:16 +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_CONSTRAINT_NONE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_CONSTRAINT_PREFER_RBR (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW 19:17 +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_1_62GBPS (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_2_70GBPS (0x00000002U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_5_40GBPS (0x00000003U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_8_10GBPS (0x00000004U) +#define NV0073_CTRL_DFP_FLAGS_LINK 21:20 +#define NV0073_CTRL_DFP_FLAGS_LINK_NONE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_LINK_SINGLE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_LINK_DUAL (0x00000002U) +#define NV0073_CTRL_DFP_FLAGS_DP_FORCE_RM_EDID 22:22 +#define NV0073_CTRL_DFP_FLAGS_DP_FORCE_RM_EDID_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_DP_FORCE_RM_EDID_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID 24:23 +#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_NONE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_A (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_B (0x00000002U) +#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_GANGED (0x00000003U) +#define NV0073_CTRL_DFP_FLAGS_DP_POST_CURSOR2_DISABLED 25:25 +#define NV0073_CTRL_DFP_FLAGS_DP_POST_CURSOR2_DISABLED_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_DP_POST_CURSOR2_DISABLED_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DP_PHY_REPEATER_COUNT 29:26 +#define NV0073_CTRL_DFP_FLAGS_DYNAMIC_MUX_CAPABLE 30:30 +#define NV0073_CTRL_DFP_FLAGS_DYNAMIC_MUX_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_DYNAMIC_MUX_CAPABLE_TRUE (0x00000001U) + +#define NV0073_CTRL_CMD_SYSTEM_GET_ACTIVE (0x730126U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS { + NvU32 subDeviceInstance; + NvU32 head; + NvU32 flags; + NvU32 displayId; +} NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS; + +typedef NvU32 NV0073_CTRL_DFP_ASSIGN_SOR_LINKCONFIG; + +typedef struct NV0073_CTRL_DFP_ASSIGN_SOR_INFO { + NvU32 displayMask; + NvU32 sorType; +} NV0073_CTRL_DFP_ASSIGN_SOR_INFO; + +#define NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS 4U + +#define NV0073_CTRL_CMD_DFP_ASSIGN_SOR (0x731152U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DFP_INTERFACE_ID << 8) | NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU8 sorExcludeMask; + NvU32 slaveDisplayId; + NV0073_CTRL_DFP_ASSIGN_SOR_LINKCONFIG forceSublinkConfig; + NvBool bIs2Head1Or; + NvU32 sorAssignList[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS]; + NV0073_CTRL_DFP_ASSIGN_SOR_INFO sorAssignListWithTag[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS]; + NvU8 reservedSorMask; + NvU32 flags; +} NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS; + +#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_AUDIO 0:0 +#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_AUDIO_OPTIMAL (0x00000001U) +#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_AUDIO_DEFAULT (0x00000000U) +#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_ACTIVE_SOR_NOT_AUDIO_CAPABLE 1:1 +#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_ACTIVE_SOR_NOT_AUDIO_CAPABLE_NO (0x00000000U) +#define NV0073_CTRL_DFP_ASSIGN_SOR_FLAGS_ACTIVE_SOR_NOT_AUDIO_CAPABLE_YES (0x00000001U) + +#define NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS (0x730292U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS (0x730291U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS_PARAMS_MESSAGE_ID" */ + +typedef struct NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 brightness; + NvBool bUncalibrated; +} NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS; + +#define NV0073_CTRL_CMD_DFP_SET_ELD_AUDIO_CAPS (0x731144U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DFP_INTERFACE_ID << 8) | NV0073_CTRL_DFP_SET_ELD_AUDIO_CAP_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_ELD_BUFFER 96U + +typedef struct NV0073_CTRL_DFP_SET_ELD_AUDIO_CAP_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 numELDSize; + NvU8 bufferELD[NV0073_CTRL_DFP_ELD_AUDIO_CAPS_ELD_BUFFER]; + NvU32 maxFreqSupported; + NvU32 ctrl; + NvU32 deviceEntry; +} NV0073_CTRL_DFP_SET_ELD_AUDIO_CAP_PARAMS; + +#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_PD 0:0 +#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_PD_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_PD_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_ELDV 1:1 +#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_ELDV_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_ELD_AUDIO_CAPS_CTRL_ELDV_TRUE (0x00000001U) + +#define NV0073_CTRL_SPECIFIC_GET_EDID_MAX_EDID_BYTES 2048U + +#define NV0073_CTRL_CMD_SPECIFIC_GET_EDID_V2 (0x730245U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_EDID_V2_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SPECIFIC_GET_EDID_V2_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 bufferSize; + NvU32 flags; + NvU8 edidBuffer[NV0073_CTRL_SPECIFIC_GET_EDID_MAX_EDID_BYTES]; +} NV0073_CTRL_SPECIFIC_GET_EDID_V2_PARAMS; + +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_ENABLE (0x730273U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_SET_HDMI_ENABLE_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SPECIFIC_SET_HDMI_ENABLE_PARAMS { + NvU8 subDeviceInstance; + NvU32 displayId; + NvU8 enable; +} NV0073_CTRL_SPECIFIC_SET_HDMI_ENABLE_PARAMS; + +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS (0x730293U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_SET_HDMI_SINK_CAPS_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SPECIFIC_SET_HDMI_SINK_CAPS_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 caps; +} NV0073_CTRL_SPECIFIC_SET_HDMI_SINK_CAPS_PARAMS; + +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS (0x730293U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_SET_HDMI_SINK_CAPS_PARAMS_MESSAGE_ID" */ +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_GT_340MHZ_CLOCK_SUPPORTED 0:0 +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_GT_340MHZ_CLOCK_SUPPORTED_FALSE (0x00000000U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_GT_340MHZ_CLOCK_SUPPORTED_TRUE (0x00000001U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_LTE_340MHZ_SCRAMBLING_SUPPORTED 1:1 +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_LTE_340MHZ_SCRAMBLING_SUPPORTED_FALSE (0x00000000U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_LTE_340MHZ_SCRAMBLING_SUPPORTED_TRUE (0x00000001U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_SCDC_SUPPORTED 2:2 +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_SCDC_SUPPORTED_FALSE (0x00000000U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_SCDC_SUPPORTED_TRUE (0x00000001U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED 5:3 +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_NONE (0x00000000U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_3LANES_3G (0x00000001U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_3LANES_6G (0x00000002U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_4LANES_6G (0x00000003U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_4LANES_8G (0x00000004U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_4LANES_10G (0x00000005U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_MAX_FRL_RATE_SUPPORTED_4LANES_12G (0x00000006U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_12_SUPPORTED 6:6 +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_12_SUPPORTED_FALSE (0x00000000U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_12_SUPPORTED_TRUE (0x00000001U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED 9:7 +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_NONE (0x00000000U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_3LANES_3G (0x00000001U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_3LANES_6G (0x00000002U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_4LANES_6G (0x00000003U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_4LANES_8G (0x00000004U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_4LANES_10G (0x00000005U) +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_SINK_CAPS_DSC_MAX_FRL_RATE_SUPPORTED_4LANES_12G (0x00000006U) + +#define NV0073_CTRL_SET_OD_MAX_PACKET_SIZE 36U + +#define NV0073_CTRL_CMD_SPECIFIC_SET_OD_PACKET (0x730288U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 transmitControl; + NvU32 packetSize; + NvU32 targetHead; + NvBool bUsePsrHeadforSdp; + NvU8 aPacket[NV0073_CTRL_SET_OD_MAX_PACKET_SIZE]; +} NV0073_CTRL_SPECIFIC_SET_OD_PACKET_PARAMS; + +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ENABLE 0:0 +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ENABLE_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ENABLE_YES (0x0000001U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_OTHER_FRAME 1:1 +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_OTHER_FRAME_DISABLE (0x0000000U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_OTHER_FRAME_ENABLE (0x0000001U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SINGLE_FRAME 2:2 +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SINGLE_FRAME_DISABLE (0x0000000U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SINGLE_FRAME_ENABLE (0x0000001U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ON_HBLANK 3:3 +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ON_HBLANK_DISABLE (0x0000000U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_ON_HBLANK_ENABLE (0x0000001U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_IMMEDIATE 4:4 +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_IMMEDIATE_DISABLE (0x0000000U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_IMMEDIATE_ENABLE (0x0000001U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_VIDEO_FMT 5:5 +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_VIDEO_FMT_SW_CONTROLLED (0x0000000U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_VIDEO_FMT_HW_CONTROLLED (0x0000001U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_STEREO_POLARITY 6:6 +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_STEREO_POLARITY_FALSE (0x0000000U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_STEREO_POLARITY_TRUE (0x0000001U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_SELF_REFRESH_SETTING 7:7 +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_SELF_REFRESH_SETTING_FALSE (0x0000000U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_SET_SELF_REFRESH_SETTING_TRUE (0x0000001U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_GEN_INFOFRAME_MODE 9:8 +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_GEN_INFOFRAME_MODE_INFOFRAME0 (0x0000000U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_GEN_INFOFRAME_MODE_INFOFRAME1 (0x0000001U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_RESERVED_LEGACY_MODE 31:31 +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_RESERVED_LEGACY_MODE_NO (0x0000000U) +#define NV0073_CTRL_SPECIFIC_SET_OD_PACKET_TRANSMIT_CONTROL_RESERVED_LEGACY_MODE_YES (0x0000001U) + +#define NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM (0x730275U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM_PARAMS_MESSAGE_ID" */ + +typedef struct NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM_PARAMS { + NvU8 subDeviceInstance; + NvU32 displayId; + NvU8 mute; +} NV0073_CTRL_CMD_SPECIFIC_SET_HDMI_AUDIO_MUTESTREAM_PARAMS; + +#define NV0073_CTRL_DP_AUXCH_MAX_DATA_SIZE 16U + +#define NV0073_CTRL_CMD_DP_AUXCH_CTRL (0x731341U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_DP_AUXCH_CTRL_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_DP_AUXCH_CTRL_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvBool bAddrOnly; + NvU32 cmd; + NvU32 addr; + NvU8 data[NV0073_CTRL_DP_AUXCH_MAX_DATA_SIZE]; + NvU32 size; + NvU32 replyType; + NvU32 retryTimeMs; +} NV0073_CTRL_DP_AUXCH_CTRL_PARAMS; + +#define NV0073_CTRL_DP_AUXCH_CMD_TYPE 3:3 +#define NV0073_CTRL_DP_AUXCH_CMD_TYPE_I2C (0x00000000U) +#define NV0073_CTRL_DP_AUXCH_CMD_TYPE_AUX (0x00000001U) +#define NV0073_CTRL_DP_AUXCH_CMD_I2C_MOT 2:2 +#define NV0073_CTRL_DP_AUXCH_CMD_I2C_MOT_FALSE (0x00000000U) +#define NV0073_CTRL_DP_AUXCH_CMD_I2C_MOT_TRUE (0x00000001U) +#define NV0073_CTRL_DP_AUXCH_CMD_REQ_TYPE 1:0 +#define NV0073_CTRL_DP_AUXCH_CMD_REQ_TYPE_WRITE (0x00000000U) +#define NV0073_CTRL_DP_AUXCH_CMD_REQ_TYPE_READ (0x00000001U) +#define NV0073_CTRL_DP_AUXCH_CMD_REQ_TYPE_WRITE_STATUS (0x00000002U) + +#define NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES (0x731377U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES 8U + +typedef struct NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS { + // In + NvU32 subDeviceInstance; + NvU32 displayId; + NvU16 linkRateTbl[NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES]; + + // Out + NvU8 linkBwTbl[NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES]; + NvU8 linkBwCount; +} NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS; + +#define NV0073_CTRL_CMD_DP_CTRL (0x731343U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_DP_CTRL_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_DP_CTRL_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 cmd; + NvU32 data; + NvU32 err; + NvU32 retryTimeMs; + NvU32 eightLaneDpcdBaseAddr; +} NV0073_CTRL_DP_CTRL_PARAMS; + +#define NV0073_CTRL_DP_CMD_SET_LANE_COUNT 0:0 +#define NV0073_CTRL_DP_CMD_SET_LANE_COUNT_FALSE (0x00000000U) +#define NV0073_CTRL_DP_CMD_SET_LANE_COUNT_TRUE (0x00000001U) +#define NV0073_CTRL_DP_CMD_SET_LINK_BW 1:1 +#define NV0073_CTRL_DP_CMD_SET_LINK_BW_FALSE (0x00000000U) +#define NV0073_CTRL_DP_CMD_SET_LINK_BW_TRUE (0x00000001U) +#define NV0073_CTRL_DP_CMD_DISABLE_DOWNSPREAD 2:2 +#define NV0073_CTRL_DP_CMD_DISABLE_DOWNSPREAD_FALSE (0x00000000U) +#define NV0073_CTRL_DP_CMD_DISABLE_DOWNSPREAD_TRUE (0x00000001U) +#define NV0073_CTRL_DP_CMD_UNUSED 3:3 +#define NV0073_CTRL_DP_CMD_SET_FORMAT_MODE 4:4 +#define NV0073_CTRL_DP_CMD_SET_FORMAT_MODE_SINGLE_STREAM (0x00000000U) +#define NV0073_CTRL_DP_CMD_SET_FORMAT_MODE_MULTI_STREAM (0x00000001U) +#define NV0073_CTRL_DP_CMD_FAST_LINK_TRAINING 5:5 +#define NV0073_CTRL_DP_CMD_FAST_LINK_TRAINING_NO (0x00000000U) +#define NV0073_CTRL_DP_CMD_FAST_LINK_TRAINING_YES (0x00000001U) +#define NV0073_CTRL_DP_CMD_NO_LINK_TRAINING 6:6 +#define NV0073_CTRL_DP_CMD_NO_LINK_TRAINING_NO (0x00000000U) +#define NV0073_CTRL_DP_CMD_NO_LINK_TRAINING_YES (0x00000001U) +#define NV0073_CTRL_DP_CMD_SET_ENHANCED_FRAMING 7:7 +#define NV0073_CTRL_DP_CMD_SET_ENHANCED_FRAMING_FALSE (0x00000000U) +#define NV0073_CTRL_DP_CMD_SET_ENHANCED_FRAMING_TRUE (0x00000001U) +#define NV0073_CTRL_DP_CMD_USE_DOWNSPREAD_SETTING 8:8 +#define NV0073_CTRL_DP_CMD_USE_DOWNSPREAD_SETTING_DEFAULT (0x00000000U) +#define NV0073_CTRL_DP_CMD_USE_DOWNSPREAD_SETTING_FORCE (0x00000001U) +#define NV0073_CTRL_DP_CMD_SKIP_HW_PROGRAMMING 9:9 +#define NV0073_CTRL_DP_CMD_SKIP_HW_PROGRAMMING_NO (0x00000000U) +#define NV0073_CTRL_DP_CMD_SKIP_HW_PROGRAMMING_YES (0x00000001U) +#define NV0073_CTRL_DP_CMD_POST_LT_ADJ_REQ_GRANTED 10:10 +#define NV0073_CTRL_DP_CMD_POST_LT_ADJ_REQ_GRANTED_NO (0x00000000U) +#define NV0073_CTRL_DP_CMD_POST_LT_ADJ_REQ_GRANTED_YES (0x00000001U) +#define NV0073_CTRL_DP_CMD_FAKE_LINK_TRAINING 12:11 +#define NV0073_CTRL_DP_CMD_FAKE_LINK_TRAINING_NO (0x00000000U) +#define NV0073_CTRL_DP_CMD_FAKE_LINK_TRAINING_DONOT_TOGGLE_TRANSMISSION (0x00000001U) +#define NV0073_CTRL_DP_CMD_FAKE_LINK_TRAINING_TOGGLE_TRANSMISSION_ON (0x00000002U) +#define NV0073_CTRL_DP_CMD_TRAIN_PHY_REPEATER 13:13 +#define NV0073_CTRL_DP_CMD_TRAIN_PHY_REPEATER_NO (0x00000000U) +#define NV0073_CTRL_DP_CMD_TRAIN_PHY_REPEATER_YES (0x00000001U) +#define NV0073_CTRL_DP_CMD_FALLBACK_CONFIG 14:14 +#define NV0073_CTRL_DP_CMD_FALLBACK_CONFIG_FALSE (0x00000000U) +#define NV0073_CTRL_DP_CMD_FALLBACK_CONFIG_TRUE (0x00000001U) +#define NV0073_CTRL_DP_CMD_ENABLE_FEC 15:15 +#define NV0073_CTRL_DP_CMD_ENABLE_FEC_FALSE (0x00000000U) +#define NV0073_CTRL_DP_CMD_ENABLE_FEC_TRUE (0x00000001U) +#define NV0073_CTRL_DP_CMD_BANDWIDTH_TEST 29:29 +#define NV0073_CTRL_DP_CMD_BANDWIDTH_TEST_NO (0x00000000U) +#define NV0073_CTRL_DP_CMD_BANDWIDTH_TEST_YES (0x00000001U) +#define NV0073_CTRL_DP_CMD_LINK_CONFIG_CHECK_DISABLE 30:30 +#define NV0073_CTRL_DP_CMD_LINK_CONFIG_CHECK_DISABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DP_CMD_LINK_CONFIG_CHECK_DISABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DP_CMD_DISABLE_LINK_CONFIG 31:31 +#define NV0073_CTRL_DP_CMD_DISABLE_LINK_CONFIG_FALSE (0x00000000U) +#define NV0073_CTRL_DP_CMD_DISABLE_LINK_CONFIG_TRUE (0x00000001U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE 3:0 +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_MONITOR_ENABLE_BEGIN (0x00000000U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_MONITOR_ENABLE_CHALLENGE (0x00000001U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_MONITOR_ENABLE_CHECK (0x00000002U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_DRIVER_ENABLE_BEGIN (0x00000003U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_DRIVER_ENABLE_CHALLENGE (0x00000004U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_DRIVER_ENABLE_CHECK (0x00000005U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_RESET_MONITOR (0x00000006U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_INIT_PUBLIC_INFO (0x00000007U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_GET_PUBLIC_INFO (0x00000008U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_CMD_STAGE_STATUS_CHECK (0x00000009U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_OK (0x00000000U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_PENDING (0x80000001U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_READ_ERROR (0x80000002U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_WRITE_ERROR (0x80000003U) +#define NV0073_CTRL_DP_CMD_ENABLE_VRR_STATUS_DEVICE_ERROR (0x80000004U) + +#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT 4:0 +#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT_0 (0x00000000U) +#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT_1 (0x00000001U) +#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT_2 (0x00000002U) +#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT_4 (0x00000004U) +#define NV0073_CTRL_DP_DATA_SET_LANE_COUNT_8 (0x00000008U) +#define NV0073_CTRL_DP_DATA_SET_LINK_BW 15:8 +#define NV0073_CTRL_DP_DATA_SET_LINK_BW_1_62GBPS (0x00000006U) +#define NV0073_CTRL_DP_DATA_SET_LINK_BW_2_16GBPS (0x00000008U) +#define NV0073_CTRL_DP_DATA_SET_LINK_BW_2_43GBPS (0x00000009U) +#define NV0073_CTRL_DP_DATA_SET_LINK_BW_2_70GBPS (0x0000000AU) +#define NV0073_CTRL_DP_DATA_SET_LINK_BW_3_24GBPS (0x0000000CU) +#define NV0073_CTRL_DP_DATA_SET_LINK_BW_4_32GBPS (0x00000010U) +#define NV0073_CTRL_DP_DATA_SET_LINK_BW_5_40GBPS (0x00000014U) +#define NV0073_CTRL_DP_DATA_SET_LINK_BW_8_10GBPS (0x0000001EU) +#define NV0073_CTRL_DP_DATA_SET_ENHANCED_FRAMING 18:18 +#define NV0073_CTRL_DP_DATA_SET_ENHANCED_FRAMING_NO (0x00000000U) +#define NV0073_CTRL_DP_DATA_SET_ENHANCED_FRAMING_YES (0x00000001U) +#define NV0073_CTRL_DP_DATA_TARGET 22:19 +#define NV0073_CTRL_DP_DATA_TARGET_SINK (0x00000000U) +#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_0 (0x00000001U) +#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_1 (0x00000002U) +#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_2 (0x00000003U) +#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_3 (0x00000004U) +#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_4 (0x00000005U) +#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_5 (0x00000006U) +#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_6 (0x00000007U) +#define NV0073_CTRL_DP_DATA_TARGET_PHY_REPEATER_7 (0x00000008U) + +#define NV0073_CTRL_CMD_DP_SET_LANE_DATA (0x731346U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_DP_SET_LANE_DATA_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_MAX_LANES 8U + +typedef struct NV0073_CTRL_DP_LANE_DATA_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 numLanes; + NvU32 data[NV0073_CTRL_MAX_LANES]; +} NV0073_CTRL_DP_LANE_DATA_PARAMS; + +#define NV0073_CTRL_DP_LANE_DATA_PREEMPHASIS 1:0 +#define NV0073_CTRL_DP_LANE_DATA_PREEMPHASIS_NONE (0x00000000U) +#define NV0073_CTRL_DP_LANE_DATA_PREEMPHASIS_LEVEL1 (0x00000001U) +#define NV0073_CTRL_DP_LANE_DATA_PREEMPHASIS_LEVEL2 (0x00000002U) +#define NV0073_CTRL_DP_LANE_DATA_PREEMPHASIS_LEVEL3 (0x00000003U) +#define NV0073_CTRL_DP_LANE_DATA_DRIVECURRENT 3:2 +#define NV0073_CTRL_DP_LANE_DATA_DRIVECURRENT_LEVEL0 (0x00000000U) +#define NV0073_CTRL_DP_LANE_DATA_DRIVECURRENT_LEVEL1 (0x00000001U) +#define NV0073_CTRL_DP_LANE_DATA_DRIVECURRENT_LEVEL2 (0x00000002U) +#define NV0073_CTRL_DP_LANE_DATA_DRIVECURRENT_LEVEL3 (0x00000003U) + +#define NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID (0x73135bU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID_PARAMS_MESSAGE_ID" */ + +typedef struct NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 preferredDisplayId; + + NvBool force; + NvBool useBFM; + + NvU32 displayIdAssigned; + NvU32 allDisplayMask; +} NV0073_CTRL_CMD_DP_TOPOLOGY_ALLOCATE_DISPLAYID_PARAMS; + +#define NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID (0x73135cU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID_PARAMS_MESSAGE_ID" */ + +typedef struct NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; +} NV0073_CTRL_CMD_DP_TOPOLOGY_FREE_DISPLAYID_PARAMS; + +#define NV0073_CTRL_CMD_DP_CONFIG_STREAM (0x731362U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS_MESSAGE_ID" */ + +typedef struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS { + NvU32 subDeviceInstance; + NvU32 head; + NvU32 sorIndex; + NvU32 dpLink; + + NvBool bEnableOverride; + NvBool bMST; + NvU32 singleHeadMultistreamMode; + NvU32 hBlankSym; + NvU32 vBlankSym; + NvU32 colorFormat; + NvBool bEnableTwoHeadOneOr; + + struct { + NvU32 slotStart; + NvU32 slotEnd; + NvU32 PBN; + NvU32 Timeslice; + NvBool sendACT; // deprecated -Use NV0073_CTRL_CMD_DP_SEND_ACT + NvU32 singleHeadMSTPipeline; + NvBool bEnableAudioOverRightPanel; + } MST; + + struct { + NvBool bEnhancedFraming; + NvU32 tuSize; + NvU32 waterMark; + NvU32 actualPclkHz; // deprecated -Use MvidWarParams + NvU32 linkClkFreqHz; // deprecated -Use MvidWarParams + NvBool bEnableAudioOverRightPanel; + struct { + NvU32 activeCnt; + NvU32 activeFrac; + NvU32 activePolarity; + NvBool mvidWarEnabled; + struct { + NvU32 actualPclkHz; + NvU32 linkClkFreqHz; + } MvidWarParams; + } Legacy; + } SST; +} NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS; + +#define NV0073_CTRL_CMD_DFP_SET_AUDIO_ENABLE (0x731150U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DFP_INTERFACE_ID << 8) | NV0073_CTRL_DFP_SET_AUDIO_ENABLE_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_DFP_SET_AUDIO_ENABLE_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvBool enable; +} NV0073_CTRL_DFP_SET_AUDIO_ENABLE_PARAMS; + +#define NV0073_CTRL_CMD_DP_SET_AUDIO_MUTESTREAM (0x731359U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_DP_SET_AUDIO_MUTESTREAM_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_DP_SET_AUDIO_MUTESTREAM_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 mute; +} NV0073_CTRL_DP_SET_AUDIO_MUTESTREAM_PARAMS; + +#define NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER (0x20800a58) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS { + NvU32 addressSpace; + NV_DECLARE_ALIGNED(NvU64 physicalAddr, 8); + NV_DECLARE_ALIGNED(NvU64 limit, 8); + NvU32 cacheSnoop; + NvU32 hclass; + NvU32 channelInstance; + NvBool valid; +} NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS; + +#define ADDR_SYSMEM (1) // System memory (PCI) + +#define ADDR_FBMEM 2 // Frame buffer memory space + +typedef struct +{ + NvV32 channelInstance; // One of the n channel instances of a given channel type. + // All PIO channels have two instances (one per head). + NvHandle hObjectNotify; // ctx dma handle for an area (of type NvNotification defined in sdk/nvidia/inc/nvtypes.h) where RM can write errors. + NvP64 pControl NV_ALIGN_BYTES(8); // pControl gives virt addr of control region for PIO channel +} NV50VAIO_CHANNELPIO_ALLOCATION_PARAMETERS; + +typedef struct +{ + NvV32 channelInstance; // One of the n channel instances of a given channel type. + // Note that core channel has only one instance + // while all others have two (one per head). + NvHandle hObjectBuffer; // ctx dma handle for DMA push buffer + NvHandle hObjectNotify; // ctx dma handle for an area (of type NvNotification defined in sdk/nvidia/inc/nvtypes.h) where RM can write errors/notifications + NvU32 offset; // Initial offset for put/get, usually zero. + NvP64 pControl NV_ALIGN_BYTES(8); // pControl gives virt addr of UDISP GET/PUT regs + + NvU32 flags; +#define NV50VAIO_CHANNELDMA_ALLOCATION_FLAGS_CONNECT_PB_AT_GRAB 1:1 +#define NV50VAIO_CHANNELDMA_ALLOCATION_FLAGS_CONNECT_PB_AT_GRAB_YES 0x00000000 +#define NV50VAIO_CHANNELDMA_ALLOCATION_FLAGS_CONNECT_PB_AT_GRAB_NO 0x00000001 + +} NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/engine.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/engine.h new file mode 100644 index 000000000000..b26dfc8f8087 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/engine.h @@ -0,0 +1,260 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_ENGINE_H__ +#define __NVRM_ENGINE_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +#define MC_ENGINE_IDX_NULL 0 // This must be 0 +#define MC_ENGINE_IDX_TMR 1 +#define MC_ENGINE_IDX_DISP 2 +#define MC_ENGINE_IDX_FB 3 +#define MC_ENGINE_IDX_FIFO 4 +#define MC_ENGINE_IDX_VIDEO 5 +#define MC_ENGINE_IDX_MD 6 +#define MC_ENGINE_IDX_BUS 7 +#define MC_ENGINE_IDX_PMGR 8 +#define MC_ENGINE_IDX_VP2 9 +#define MC_ENGINE_IDX_CIPHER 10 +#define MC_ENGINE_IDX_BIF 11 +#define MC_ENGINE_IDX_PPP 12 +#define MC_ENGINE_IDX_PRIVRING 13 +#define MC_ENGINE_IDX_PMU 14 +#define MC_ENGINE_IDX_CE0 15 +#define MC_ENGINE_IDX_CE1 16 +#define MC_ENGINE_IDX_CE2 17 +#define MC_ENGINE_IDX_CE3 18 +#define MC_ENGINE_IDX_CE4 19 +#define MC_ENGINE_IDX_CE5 20 +#define MC_ENGINE_IDX_CE6 21 +#define MC_ENGINE_IDX_CE7 22 +#define MC_ENGINE_IDX_CE8 23 +#define MC_ENGINE_IDX_CE9 24 +#define MC_ENGINE_IDX_CE_MAX MC_ENGINE_IDX_CE9 +#define MC_ENGINE_IDX_VIC 35 +#define MC_ENGINE_IDX_ISOHUB 36 +#define MC_ENGINE_IDX_VGPU 37 +#define MC_ENGINE_IDX_MSENC 38 +#define MC_ENGINE_IDX_MSENC1 39 +#define MC_ENGINE_IDX_MSENC2 40 +#define MC_ENGINE_IDX_C2C 41 +#define MC_ENGINE_IDX_LTC 42 +#define MC_ENGINE_IDX_FBHUB 43 +#define MC_ENGINE_IDX_HDACODEC 44 +#define MC_ENGINE_IDX_GMMU 45 +#define MC_ENGINE_IDX_SEC2 46 +#define MC_ENGINE_IDX_FSP 47 +#define MC_ENGINE_IDX_NVLINK 48 +#define MC_ENGINE_IDX_GSP 49 +#define MC_ENGINE_IDX_NVJPG 50 +#define MC_ENGINE_IDX_NVJPEG MC_ENGINE_IDX_NVJPG +#define MC_ENGINE_IDX_NVJPEG0 MC_ENGINE_IDX_NVJPEG +#define MC_ENGINE_IDX_NVJPEG1 51 +#define MC_ENGINE_IDX_NVJPEG2 52 +#define MC_ENGINE_IDX_NVJPEG3 53 +#define MC_ENGINE_IDX_NVJPEG4 54 +#define MC_ENGINE_IDX_NVJPEG5 55 +#define MC_ENGINE_IDX_NVJPEG6 56 +#define MC_ENGINE_IDX_NVJPEG7 57 +#define MC_ENGINE_IDX_REPLAYABLE_FAULT 58 +#define MC_ENGINE_IDX_ACCESS_CNTR 59 +#define MC_ENGINE_IDX_NON_REPLAYABLE_FAULT 60 +#define MC_ENGINE_IDX_REPLAYABLE_FAULT_ERROR 61 +#define MC_ENGINE_IDX_NON_REPLAYABLE_FAULT_ERROR 62 +#define MC_ENGINE_IDX_INFO_FAULT 63 +#define MC_ENGINE_IDX_BSP 64 +#define MC_ENGINE_IDX_NVDEC MC_ENGINE_IDX_BSP +#define MC_ENGINE_IDX_NVDEC0 MC_ENGINE_IDX_NVDEC +#define MC_ENGINE_IDX_NVDEC1 65 +#define MC_ENGINE_IDX_NVDEC2 66 +#define MC_ENGINE_IDX_NVDEC3 67 +#define MC_ENGINE_IDX_NVDEC4 68 +#define MC_ENGINE_IDX_NVDEC5 69 +#define MC_ENGINE_IDX_NVDEC6 70 +#define MC_ENGINE_IDX_NVDEC7 71 +#define MC_ENGINE_IDX_CPU_DOORBELL 72 +#define MC_ENGINE_IDX_PRIV_DOORBELL 73 +#define MC_ENGINE_IDX_MMU_ECC_ERROR 74 +#define MC_ENGINE_IDX_BLG 75 +#define MC_ENGINE_IDX_PERFMON 76 +#define MC_ENGINE_IDX_BUF_RESET 77 +#define MC_ENGINE_IDX_XBAR 78 +#define MC_ENGINE_IDX_ZPW 79 +#define MC_ENGINE_IDX_OFA0 80 +#define MC_ENGINE_IDX_TEGRA 81 +#define MC_ENGINE_IDX_GR 82 +#define MC_ENGINE_IDX_GR0 MC_ENGINE_IDX_GR +#define MC_ENGINE_IDX_GR1 83 +#define MC_ENGINE_IDX_GR2 84 +#define MC_ENGINE_IDX_GR3 85 +#define MC_ENGINE_IDX_GR4 86 +#define MC_ENGINE_IDX_GR5 87 +#define MC_ENGINE_IDX_GR6 88 +#define MC_ENGINE_IDX_GR7 89 +#define MC_ENGINE_IDX_ESCHED 90 +#define MC_ENGINE_IDX_ESCHED__SIZE 64 +#define MC_ENGINE_IDX_GR_FECS_LOG 154 +#define MC_ENGINE_IDX_GR0_FECS_LOG MC_ENGINE_IDX_GR_FECS_LOG +#define MC_ENGINE_IDX_GR1_FECS_LOG 155 +#define MC_ENGINE_IDX_GR2_FECS_LOG 156 +#define MC_ENGINE_IDX_GR3_FECS_LOG 157 +#define MC_ENGINE_IDX_GR4_FECS_LOG 158 +#define MC_ENGINE_IDX_GR5_FECS_LOG 159 +#define MC_ENGINE_IDX_GR6_FECS_LOG 160 +#define MC_ENGINE_IDX_GR7_FECS_LOG 161 +#define MC_ENGINE_IDX_TMR_SWRL 162 +#define MC_ENGINE_IDX_DISP_GSP 163 +#define MC_ENGINE_IDX_REPLAYABLE_FAULT_CPU 164 +#define MC_ENGINE_IDX_NON_REPLAYABLE_FAULT_CPU 165 +#define MC_ENGINE_IDX_PXUC 166 +#define MC_ENGINE_IDX_MAX 167 // This must be kept as the max bit if +#define MC_ENGINE_IDX_INVALID 0xFFFFFFFF +#define MC_ENGINE_IDX_GRn(x) (MC_ENGINE_IDX_GR0 + (x)) +#define MC_ENGINE_IDX_GRn_FECS_LOG(x) (MC_ENGINE_IDX_GR0_FECS_LOG + (x)) +#define MC_ENGINE_IDX_CE(x) (MC_ENGINE_IDX_CE0 + (x)) +#define MC_ENGINE_IDX_MSENCn(x) (MC_ENGINE_IDX_MSENC + (x)) +#define MC_ENGINE_IDX_NVDECn(x) (MC_ENGINE_IDX_NVDEC + (x)) +#define MC_ENGINE_IDX_NVJPEGn(x) (MC_ENGINE_IDX_NVJPEG + (x)) +#define MC_ENGINE_IDX_ESCHEDn(x) (MC_ENGINE_IDX_ESCHED + (x)) + +typedef enum +{ + RM_ENGINE_TYPE_NULL = (0x00000000), + RM_ENGINE_TYPE_GR0 = (0x00000001), + RM_ENGINE_TYPE_GR1 = (0x00000002), + RM_ENGINE_TYPE_GR2 = (0x00000003), + RM_ENGINE_TYPE_GR3 = (0x00000004), + RM_ENGINE_TYPE_GR4 = (0x00000005), + RM_ENGINE_TYPE_GR5 = (0x00000006), + RM_ENGINE_TYPE_GR6 = (0x00000007), + RM_ENGINE_TYPE_GR7 = (0x00000008), + RM_ENGINE_TYPE_COPY0 = (0x00000009), + RM_ENGINE_TYPE_COPY1 = (0x0000000a), + RM_ENGINE_TYPE_COPY2 = (0x0000000b), + RM_ENGINE_TYPE_COPY3 = (0x0000000c), + RM_ENGINE_TYPE_COPY4 = (0x0000000d), + RM_ENGINE_TYPE_COPY5 = (0x0000000e), + RM_ENGINE_TYPE_COPY6 = (0x0000000f), + RM_ENGINE_TYPE_COPY7 = (0x00000010), + RM_ENGINE_TYPE_COPY8 = (0x00000011), + RM_ENGINE_TYPE_COPY9 = (0x00000012), + RM_ENGINE_TYPE_NVDEC0 = (0x0000001d), + RM_ENGINE_TYPE_NVDEC1 = (0x0000001e), + RM_ENGINE_TYPE_NVDEC2 = (0x0000001f), + RM_ENGINE_TYPE_NVDEC3 = (0x00000020), + RM_ENGINE_TYPE_NVDEC4 = (0x00000021), + RM_ENGINE_TYPE_NVDEC5 = (0x00000022), + RM_ENGINE_TYPE_NVDEC6 = (0x00000023), + RM_ENGINE_TYPE_NVDEC7 = (0x00000024), + RM_ENGINE_TYPE_NVENC0 = (0x00000025), + RM_ENGINE_TYPE_NVENC1 = (0x00000026), + RM_ENGINE_TYPE_NVENC2 = (0x00000027), + RM_ENGINE_TYPE_VP = (0x00000028), + RM_ENGINE_TYPE_ME = (0x00000029), + RM_ENGINE_TYPE_PPP = (0x0000002a), + RM_ENGINE_TYPE_MPEG = (0x0000002b), + RM_ENGINE_TYPE_SW = (0x0000002c), + RM_ENGINE_TYPE_TSEC = (0x0000002d), + RM_ENGINE_TYPE_VIC = (0x0000002e), + RM_ENGINE_TYPE_MP = (0x0000002f), + RM_ENGINE_TYPE_SEC2 = (0x00000030), + RM_ENGINE_TYPE_HOST = (0x00000031), + RM_ENGINE_TYPE_DPU = (0x00000032), + RM_ENGINE_TYPE_PMU = (0x00000033), + RM_ENGINE_TYPE_FBFLCN = (0x00000034), + RM_ENGINE_TYPE_NVJPEG0 = (0x00000035), + RM_ENGINE_TYPE_NVJPEG1 = (0x00000036), + RM_ENGINE_TYPE_NVJPEG2 = (0x00000037), + RM_ENGINE_TYPE_NVJPEG3 = (0x00000038), + RM_ENGINE_TYPE_NVJPEG4 = (0x00000039), + RM_ENGINE_TYPE_NVJPEG5 = (0x0000003a), + RM_ENGINE_TYPE_NVJPEG6 = (0x0000003b), + RM_ENGINE_TYPE_NVJPEG7 = (0x0000003c), + RM_ENGINE_TYPE_OFA = (0x0000003d), + RM_ENGINE_TYPE_LAST = (0x0000003e), +} RM_ENGINE_TYPE; + +#define NV2080_ENGINE_TYPE_NULL (0x00000000) +#define NV2080_ENGINE_TYPE_GRAPHICS (0x00000001) +#define NV2080_ENGINE_TYPE_GR0 NV2080_ENGINE_TYPE_GRAPHICS +#define NV2080_ENGINE_TYPE_GR1 (0x00000002) +#define NV2080_ENGINE_TYPE_GR2 (0x00000003) +#define NV2080_ENGINE_TYPE_GR3 (0x00000004) +#define NV2080_ENGINE_TYPE_GR4 (0x00000005) +#define NV2080_ENGINE_TYPE_GR5 (0x00000006) +#define NV2080_ENGINE_TYPE_GR6 (0x00000007) +#define NV2080_ENGINE_TYPE_GR7 (0x00000008) +#define NV2080_ENGINE_TYPE_COPY0 (0x00000009) +#define NV2080_ENGINE_TYPE_COPY1 (0x0000000a) +#define NV2080_ENGINE_TYPE_COPY2 (0x0000000b) +#define NV2080_ENGINE_TYPE_COPY3 (0x0000000c) +#define NV2080_ENGINE_TYPE_COPY4 (0x0000000d) +#define NV2080_ENGINE_TYPE_COPY5 (0x0000000e) +#define NV2080_ENGINE_TYPE_COPY6 (0x0000000f) +#define NV2080_ENGINE_TYPE_COPY7 (0x00000010) +#define NV2080_ENGINE_TYPE_COPY8 (0x00000011) +#define NV2080_ENGINE_TYPE_COPY9 (0x00000012) +#define NV2080_ENGINE_TYPE_BSP (0x00000013) +#define NV2080_ENGINE_TYPE_NVDEC0 NV2080_ENGINE_TYPE_BSP +#define NV2080_ENGINE_TYPE_NVDEC1 (0x00000014) +#define NV2080_ENGINE_TYPE_NVDEC2 (0x00000015) +#define NV2080_ENGINE_TYPE_NVDEC3 (0x00000016) +#define NV2080_ENGINE_TYPE_NVDEC4 (0x00000017) +#define NV2080_ENGINE_TYPE_NVDEC5 (0x00000018) +#define NV2080_ENGINE_TYPE_NVDEC6 (0x00000019) +#define NV2080_ENGINE_TYPE_NVDEC7 (0x0000001a) +#define NV2080_ENGINE_TYPE_MSENC (0x0000001b) +#define NV2080_ENGINE_TYPE_NVENC0 NV2080_ENGINE_TYPE_MSENC /* Mutually exclusive alias */ +#define NV2080_ENGINE_TYPE_NVENC1 (0x0000001c) +#define NV2080_ENGINE_TYPE_NVENC2 (0x0000001d) +#define NV2080_ENGINE_TYPE_VP (0x0000001e) +#define NV2080_ENGINE_TYPE_ME (0x0000001f) +#define NV2080_ENGINE_TYPE_PPP (0x00000020) +#define NV2080_ENGINE_TYPE_MPEG (0x00000021) +#define NV2080_ENGINE_TYPE_SW (0x00000022) +#define NV2080_ENGINE_TYPE_CIPHER (0x00000023) +#define NV2080_ENGINE_TYPE_TSEC NV2080_ENGINE_TYPE_CIPHER +#define NV2080_ENGINE_TYPE_VIC (0x00000024) +#define NV2080_ENGINE_TYPE_MP (0x00000025) +#define NV2080_ENGINE_TYPE_SEC2 (0x00000026) +#define NV2080_ENGINE_TYPE_HOST (0x00000027) +#define NV2080_ENGINE_TYPE_DPU (0x00000028) +#define NV2080_ENGINE_TYPE_PMU (0x00000029) +#define NV2080_ENGINE_TYPE_FBFLCN (0x0000002a) +#define NV2080_ENGINE_TYPE_NVJPG (0x0000002b) +#define NV2080_ENGINE_TYPE_NVJPEG0 NV2080_ENGINE_TYPE_NVJPG +#define NV2080_ENGINE_TYPE_NVJPEG1 (0x0000002c) +#define NV2080_ENGINE_TYPE_NVJPEG2 (0x0000002d) +#define NV2080_ENGINE_TYPE_NVJPEG3 (0x0000002e) +#define NV2080_ENGINE_TYPE_NVJPEG4 (0x0000002f) +#define NV2080_ENGINE_TYPE_NVJPEG5 (0x00000030) +#define NV2080_ENGINE_TYPE_NVJPEG6 (0x00000031) +#define NV2080_ENGINE_TYPE_NVJPEG7 (0x00000032) +#define NV2080_ENGINE_TYPE_OFA (0x00000033) +#define NV2080_ENGINE_TYPE_LAST (0x0000003e) +#define NV2080_ENGINE_TYPE_ALLENGINES (0xffffffff) +#define NV2080_ENGINE_TYPE_COPY_SIZE 10 +#define NV2080_ENGINE_TYPE_NVENC_SIZE 3 +#define NV2080_ENGINE_TYPE_NVJPEG_SIZE 8 +#define NV2080_ENGINE_TYPE_NVDEC_SIZE 8 +#define NV2080_ENGINE_TYPE_GR_SIZE 8 +#define NV2080_ENGINE_TYPE_COPY(i) (NV2080_ENGINE_TYPE_COPY0+(i)) +#define NV2080_ENGINE_TYPE_IS_COPY(i) (((i) >= NV2080_ENGINE_TYPE_COPY0) && ((i) <= NV2080_ENGINE_TYPE_COPY9)) +#define NV2080_ENGINE_TYPE_COPY_IDX(i) ((i) - NV2080_ENGINE_TYPE_COPY0) +#define NV2080_ENGINE_TYPE_NVENC(i) (NV2080_ENGINE_TYPE_NVENC0+(i)) +#define NV2080_ENGINE_TYPE_IS_NVENC(i) (((i) >= NV2080_ENGINE_TYPE_NVENC0) && ((i) < NV2080_ENGINE_TYPE_NVENC(NV2080_ENGINE_TYPE_NVENC_SIZE))) +#define NV2080_ENGINE_TYPE_NVENC_IDX(i) ((i) - NV2080_ENGINE_TYPE_NVENC0) +#define NV2080_ENGINE_TYPE_NVDEC(i) (NV2080_ENGINE_TYPE_NVDEC0+(i)) +#define NV2080_ENGINE_TYPE_IS_NVDEC(i) (((i) >= NV2080_ENGINE_TYPE_NVDEC0) && ((i) < NV2080_ENGINE_TYPE_NVDEC(NV2080_ENGINE_TYPE_NVDEC_SIZE))) +#define NV2080_ENGINE_TYPE_NVDEC_IDX(i) ((i) - NV2080_ENGINE_TYPE_NVDEC0) +#define NV2080_ENGINE_TYPE_NVJPEG(i) (NV2080_ENGINE_TYPE_NVJPEG0+(i)) +#define NV2080_ENGINE_TYPE_IS_NVJPEG(i) (((i) >= NV2080_ENGINE_TYPE_NVJPEG0) && ((i) < NV2080_ENGINE_TYPE_NVJPEG(NV2080_ENGINE_TYPE_NVJPEG_SIZE))) +#define NV2080_ENGINE_TYPE_NVJPEG_IDX(i) ((i) - NV2080_ENGINE_TYPE_NVJPEG0) +#define NV2080_ENGINE_TYPE_GR(i) (NV2080_ENGINE_TYPE_GR0 + (i)) +#define NV2080_ENGINE_TYPE_IS_GR(i) (((i) >= NV2080_ENGINE_TYPE_GR0) && ((i) < NV2080_ENGINE_TYPE_GR(NV2080_ENGINE_TYPE_GR_SIZE))) +#define NV2080_ENGINE_TYPE_GR_IDX(i) ((i) - NV2080_ENGINE_TYPE_GR0) +#define NV2080_ENGINE_TYPE_IS_VALID(i) (((i) > (NV2080_ENGINE_TYPE_NULL)) && ((i) < (NV2080_ENGINE_TYPE_LAST))) +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/event.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/event.h new file mode 100644 index 000000000000..057f7220c225 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/event.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_EVENT_H__ +#define __NVRM_EVENT_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +#define NV01_EVENT_KERNEL_CALLBACK_EX (0x0000007e) + +typedef struct NV0005_ALLOC_PARAMETERS { + NvHandle hParentClient; + NvHandle hSrcResource; + + NvV32 hClass; + NvV32 notifyIndex; + NV_DECLARE_ALIGNED(NvP64 data, 8); +} NV0005_ALLOC_PARAMETERS; + +#define NV01_EVENT_CLIENT_RM (0x04000000) + +#define NV2080_CTRL_CMD_EVENT_SET_NOTIFICATION (0x20800301) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_EVENT_INTERFACE_ID << 8) | NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS { + NvU32 event; + NvU32 action; + NvBool bNotifyState; + NvU32 info32; + NvU16 info16; +} NV2080_CTRL_EVENT_SET_NOTIFICATION_PARAMS; + +#define NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT (0x00000002) + +typedef struct rpc_post_event_v17_00 +{ + NvHandle hClient; + NvHandle hEvent; + NvU32 notifyIndex; + NvU32 data; + NvU16 info16; + NvU32 status; + NvU32 eventDataSize; + NvBool bNotifyList; + NvU8 eventData[]; +} rpc_post_event_v17_00; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/fbsr.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/fbsr.h new file mode 100644 index 000000000000..28786ef013a2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/fbsr.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_FBSR_H__ +#define __NVRM_FBSR_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +#define NV01_MEMORY_LIST_FBMEM (0x00000082) + +#define NV01_MEMORY_LIST_SYSTEM (0x00000081) + +#define NVOS02_FLAGS_PHYSICALITY 7:4 +#define NVOS02_FLAGS_PHYSICALITY_CONTIGUOUS (0x00000000) +#define NVOS02_FLAGS_PHYSICALITY_NONCONTIGUOUS (0x00000001) +#define NVOS02_FLAGS_LOCATION 11:8 +#define NVOS02_FLAGS_LOCATION_PCI (0x00000000) +#define NVOS02_FLAGS_LOCATION_AGP (0x00000001) +#define NVOS02_FLAGS_LOCATION_VIDMEM (0x00000002) +#define NVOS02_FLAGS_COHERENCY 15:12 +#define NVOS02_FLAGS_COHERENCY_UNCACHED (0x00000000) +#define NVOS02_FLAGS_COHERENCY_CACHED (0x00000001) +#define NVOS02_FLAGS_COHERENCY_WRITE_COMBINE (0x00000002) +#define NVOS02_FLAGS_COHERENCY_WRITE_THROUGH (0x00000003) +#define NVOS02_FLAGS_COHERENCY_WRITE_PROTECT (0x00000004) +#define NVOS02_FLAGS_COHERENCY_WRITE_BACK (0x00000005) +#define NVOS02_FLAGS_ALLOC 17:16 +#define NVOS02_FLAGS_ALLOC_NONE (0x00000001) +#define NVOS02_FLAGS_GPU_CACHEABLE 18:18 +#define NVOS02_FLAGS_GPU_CACHEABLE_NO (0x00000000) +#define NVOS02_FLAGS_GPU_CACHEABLE_YES (0x00000001) +#define NVOS02_FLAGS_KERNEL_MAPPING 19:19 +#define NVOS02_FLAGS_KERNEL_MAPPING_NO_MAP (0x00000000) +#define NVOS02_FLAGS_KERNEL_MAPPING_MAP (0x00000001) +#define NVOS02_FLAGS_ALLOC_NISO_DISPLAY 20:20 +#define NVOS02_FLAGS_ALLOC_NISO_DISPLAY_NO (0x00000000) +#define NVOS02_FLAGS_ALLOC_NISO_DISPLAY_YES (0x00000001) +#define NVOS02_FLAGS_ALLOC_USER_READ_ONLY 21:21 +#define NVOS02_FLAGS_ALLOC_USER_READ_ONLY_NO (0x00000000) +#define NVOS02_FLAGS_ALLOC_USER_READ_ONLY_YES (0x00000001) +#define NVOS02_FLAGS_ALLOC_DEVICE_READ_ONLY 22:22 +#define NVOS02_FLAGS_ALLOC_DEVICE_READ_ONLY_NO (0x00000000) +#define NVOS02_FLAGS_ALLOC_DEVICE_READ_ONLY_YES (0x00000001) +#define NVOS02_FLAGS_PEER_MAP_OVERRIDE 23:23 +#define NVOS02_FLAGS_PEER_MAP_OVERRIDE_DEFAULT (0x00000000) +#define NVOS02_FLAGS_PEER_MAP_OVERRIDE_REQUIRED (0x00000001) +#define NVOS02_FLAGS_ALLOC_TYPE_SYNCPOINT 24:24 +#define NVOS02_FLAGS_ALLOC_TYPE_SYNCPOINT_APERTURE (0x00000001) +#define NVOS02_FLAGS_MEMORY_PROTECTION 26:25 +#define NVOS02_FLAGS_MEMORY_PROTECTION_DEFAULT (0x00000000) +#define NVOS02_FLAGS_MEMORY_PROTECTION_PROTECTED (0x00000001) +#define NVOS02_FLAGS_MEMORY_PROTECTION_UNPROTECTED (0x00000002) +#define NVOS02_FLAGS_MAPPING 31:30 +#define NVOS02_FLAGS_MAPPING_DEFAULT (0x00000000) +#define NVOS02_FLAGS_MAPPING_NO_MAP (0x00000001) +#define NVOS02_FLAGS_MAPPING_NEVER_MAP (0x00000002) + +struct pte_desc +{ + NvU32 idr:2; + NvU32 reserved1:14; + NvU32 length:16; + union { + NvU64 pte; // PTE when IDR==0; PDE when IDR > 0 + NvU64 pde; // PTE when IDR==0; PDE when IDR > 0 + } pte_pde[] NV_ALIGN_BYTES(8); // PTE when IDR==0; PDE when IDR > 0 +}; + +typedef struct rpc_alloc_memory_v13_01 +{ + NvHandle hClient; + NvHandle hDevice; + NvHandle hMemory; + NvU32 hClass; + NvU32 flags; + NvU32 pteAdjust; + NvU32 format; + NvU64 length NV_ALIGN_BYTES(8); + NvU32 pageCount; + struct pte_desc pteDesc; +} rpc_alloc_memory_v13_01; + +#define FBSR_TYPE_DMA 4 // Copy using DMA. Fastest. + +#define NV2080_CTRL_CMD_INTERNAL_FBSR_INIT (0x20800ac2) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS { + NvU32 fbsrType; + NvU32 numRegions; + NvHandle hClient; + NvHandle hSysMem; + NV_DECLARE_ALIGNED(NvU64 gspFbAllocsSysOffset, 8); + NvBool bEnteringGcoffState; +} NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS; + +#define NV2080_CTRL_CMD_INTERNAL_FBSR_SEND_REGION_INFO (0x20800ac3) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_FBSR_SEND_REGION_INFO_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_FBSR_SEND_REGION_INFO_PARAMS { + NvU32 fbsrType; + NvHandle hClient; + NvHandle hVidMem; + NV_DECLARE_ALIGNED(NvU64 vidOffset, 8); + NV_DECLARE_ALIGNED(NvU64 sysOffset, 8); + NV_DECLARE_ALIGNED(NvU64 size, 8); +} NV2080_CTRL_INTERNAL_FBSR_SEND_REGION_INFO_PARAMS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/fifo.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/fifo.h new file mode 100644 index 000000000000..325fdd8b6090 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/fifo.h @@ -0,0 +1,350 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_FIFO_H__ +#define __NVRM_FIFO_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +#define NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_MAX_ENTRIES 32 + +#define NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_DATA_TYPES 16 + +#define NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_MAX_PBDMA 2 + +#define NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_MAX_NAME_LEN 16 + +typedef struct NV2080_CTRL_FIFO_DEVICE_ENTRY { + NvU32 engineData[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_DATA_TYPES]; + NvU32 pbdmaIds[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_MAX_PBDMA]; + NvU32 pbdmaFaultIds[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_MAX_PBDMA]; + NvU32 numPbdmas; + char engineName[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_ENGINE_MAX_NAME_LEN]; +} NV2080_CTRL_FIFO_DEVICE_ENTRY; + +#define NV2080_CTRL_CMD_FIFO_GET_DEVICE_INFO_TABLE (0x20801112) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_FIFO_INTERFACE_ID << 8) | NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS { + NvU32 baseIndex; + NvU32 numEntries; + NvBool bMore; + // C form: NV2080_CTRL_FIFO_DEVICE_ENTRY entries[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_MAX_ENTRIES]; + NV2080_CTRL_FIFO_DEVICE_ENTRY entries[NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_MAX_ENTRIES]; +} NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS; + +typedef enum +{ + /* ************************************************************************* + * Bug 3820969 + * THINK BEFORE CHANGING ENUM ORDER HERE. + * VGPU-guest uses this same ordering. Because this enum is not versioned, + * changing the order here WILL BREAK old-guest-on-newer-host compatibility. + * ************************************************************************/ + + // *ENG_XYZ, e.g.: ENG_GR, ENG_CE etc., + ENGINE_INFO_TYPE_ENG_DESC = 0, + + // HW engine ID + ENGINE_INFO_TYPE_FIFO_TAG, + + // RM_ENGINE_TYPE_* + ENGINE_INFO_TYPE_RM_ENGINE_TYPE, + + // + // runlist id (meaning varies by GPU) + // Valid only for Esched-driven engines + // + ENGINE_INFO_TYPE_RUNLIST, + + // NV_PFIFO_INTR_MMU_FAULT_ENG_ID_* + ENGINE_INFO_TYPE_MMU_FAULT_ID, + + // ROBUST_CHANNEL_* + ENGINE_INFO_TYPE_RC_MASK, + + // Reset Bit Position. On Ampere, only valid if not _INVALID + ENGINE_INFO_TYPE_RESET, + + // Interrupt Bit Position + ENGINE_INFO_TYPE_INTR, + + // log2(MC_ENGINE_*) + ENGINE_INFO_TYPE_MC, + + // The DEV_TYPE_ENUM for this engine + ENGINE_INFO_TYPE_DEV_TYPE_ENUM, + + // The particular instance of this engine type + ENGINE_INFO_TYPE_INSTANCE_ID, + + // + // The base address for this engine's NV_RUNLIST. Valid only on Ampere+ + // Valid only for Esched-driven engines + // + ENGINE_INFO_TYPE_RUNLIST_PRI_BASE, + + // + // If this entry is a host-driven engine. + // Update _isEngineInfoTypeValidForOnlyHostDriven when adding any new entry. + // + ENGINE_INFO_TYPE_IS_HOST_DRIVEN_ENGINE, + + // + // The index into the per-engine NV_RUNLIST registers. Valid only on Ampere+ + // Valid only for Esched-driven engines + // + ENGINE_INFO_TYPE_RUNLIST_ENGINE_ID, + + // + // The base address for this engine's NV_CHRAM registers. Valid only on + // Ampere+ + // + // Valid only for Esched-driven engines + // + ENGINE_INFO_TYPE_CHRAM_PRI_BASE, + + // This entry added to copy data at RMCTRL_EXPORT() call for Kernel RM + ENGINE_INFO_TYPE_KERNEL_RM_MAX, + // Used for iterating the engine info table by the index passed. + ENGINE_INFO_TYPE_INVALID = ENGINE_INFO_TYPE_KERNEL_RM_MAX, + + // Size of FIFO_ENGINE_LIST.engineData + ENGINE_INFO_TYPE_ENGINE_DATA_ARRAY_SIZE = ENGINE_INFO_TYPE_INVALID, + + // Input-only parameter for kfifoEngineInfoXlate. + ENGINE_INFO_TYPE_PBDMA_ID + + /* ************************************************************************* + * Bug 3820969 + * THINK BEFORE CHANGING ENUM ORDER HERE. + * VGPU-guest uses this same ordering. Because this enum is not versioned, + * changing the order here WILL BREAK old-guest-on-newer-host compatibility. + * ************************************************************************/ +} ENGINE_INFO_TYPE; + +#define NV2080_CTRL_CMD_CE_GET_FAULT_METHOD_BUFFER_SIZE (0x20802a08) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_CE_INTERFACE_ID << 8) | NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS { + NvU32 size; +} NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS; + +#define NV2080_CTRL_CMD_INTERNAL_MAX_CONSTRUCTED_FALCONS 0x40 + +typedef struct NV2080_CTRL_INTERNAL_CONSTRUCTED_FALCON_INFO { + NvU32 engDesc; + NvU32 ctxAttr; + NvU32 ctxBufferSize; + NvU32 addrSpaceList; + NvU32 registerBase; +} NV2080_CTRL_INTERNAL_CONSTRUCTED_FALCON_INFO; + +#define NV2080_CTRL_CMD_INTERNAL_GET_CONSTRUCTED_FALCON_INFO (0x20800a42) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_GET_CONSTRUCTED_FALCON_INFO_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_GET_CONSTRUCTED_FALCON_INFO_PARAMS { + NvU32 numConstructedFalcons; + NV2080_CTRL_INTERNAL_CONSTRUCTED_FALCON_INFO constructedFalconsTable[NV2080_CTRL_CMD_INTERNAL_MAX_CONSTRUCTED_FALCONS]; +} NV2080_CTRL_INTERNAL_GET_CONSTRUCTED_FALCON_INFO_PARAMS; + +#define NV_MAX_SUBDEVICES 8 + +typedef struct NV_MEMORY_DESC_PARAMS { + NV_DECLARE_ALIGNED(NvU64 base, 8); + NV_DECLARE_ALIGNED(NvU64 size, 8); + NvU32 addressSpace; + NvU32 cacheAttrib; +} NV_MEMORY_DESC_PARAMS; + +#define CC_CHAN_ALLOC_IV_SIZE_DWORD 3U + +#define CC_CHAN_ALLOC_NONCE_SIZE_DWORD 8U + +typedef struct NV_CHANNEL_ALLOC_PARAMS { + + NvHandle hObjectError; // error context DMA + NvHandle hObjectBuffer; // no longer used + NV_DECLARE_ALIGNED(NvU64 gpFifoOffset, 8); // offset to beginning of GP FIFO + NvU32 gpFifoEntries; // number of GP FIFO entries + + NvU32 flags; + + + NvHandle hContextShare; // context share handle + NvHandle hVASpace; // VASpace for the channel + + // handle to UserD memory object for channel, ignored if hUserdMemory[0]=0 + NvHandle hUserdMemory[NV_MAX_SUBDEVICES]; + + // offset to beginning of UserD within hUserdMemory[x] + NV_DECLARE_ALIGNED(NvU64 userdOffset[NV_MAX_SUBDEVICES], 8); + + // engine type(NV2080_ENGINE_TYPE_*) with which this channel is associated + NvU32 engineType; + // Channel identifier that is unique for the duration of a RM session + NvU32 cid; + // One-hot encoded bitmask to match SET_SUBDEVICE_MASK methods + NvU32 subDeviceId; + NvHandle hObjectEccError; // ECC error context DMA + + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS instanceMem, 8); + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS userdMem, 8); + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS ramfcMem, 8); + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS mthdbufMem, 8); + + NvHandle hPhysChannelGroup; // reserved + NvU32 internalFlags; // reserved + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS errorNotifierMem, 8); // reserved + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS eccErrorNotifierMem, 8); // reserved + NvU32 ProcessID; // reserved + NvU32 SubProcessID; // reserved + + // IV used for CPU-side encryption / GPU-side decryption. + NvU32 encryptIv[CC_CHAN_ALLOC_IV_SIZE_DWORD]; // reserved + // IV used for CPU-side decryption / GPU-side encryption. + NvU32 decryptIv[CC_CHAN_ALLOC_IV_SIZE_DWORD]; // reserved + // Nonce used CPU-side signing / GPU-side signature verification. + NvU32 hmacNonce[CC_CHAN_ALLOC_NONCE_SIZE_DWORD]; // reserved +} NV_CHANNEL_ALLOC_PARAMS; + +typedef NV_CHANNEL_ALLOC_PARAMS NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS; + +#define NVOS04_FLAGS_CHANNEL_TYPE 1:0 +#define NVOS04_FLAGS_CHANNEL_TYPE_PHYSICAL 0x00000000 +#define NVOS04_FLAGS_CHANNEL_TYPE_VIRTUAL 0x00000001 // OBSOLETE +#define NVOS04_FLAGS_CHANNEL_TYPE_PHYSICAL_FOR_VIRTUAL 0x00000002 // OBSOLETE +#define NVOS04_FLAGS_VPR 2:2 +#define NVOS04_FLAGS_VPR_FALSE 0x00000000 +#define NVOS04_FLAGS_VPR_TRUE 0x00000001 +#define NVOS04_FLAGS_CC_SECURE 2:2 +#define NVOS04_FLAGS_CC_SECURE_FALSE 0x00000000 +#define NVOS04_FLAGS_CC_SECURE_TRUE 0x00000001 +#define NVOS04_FLAGS_CHANNEL_SKIP_MAP_REFCOUNTING 3:3 +#define NVOS04_FLAGS_CHANNEL_SKIP_MAP_REFCOUNTING_FALSE 0x00000000 +#define NVOS04_FLAGS_CHANNEL_SKIP_MAP_REFCOUNTING_TRUE 0x00000001 +#define NVOS04_FLAGS_GROUP_CHANNEL_RUNQUEUE 4:4 +#define NVOS04_FLAGS_GROUP_CHANNEL_RUNQUEUE_DEFAULT 0x00000000 +#define NVOS04_FLAGS_GROUP_CHANNEL_RUNQUEUE_ONE 0x00000001 +#define NVOS04_FLAGS_PRIVILEGED_CHANNEL 5:5 +#define NVOS04_FLAGS_PRIVILEGED_CHANNEL_FALSE 0x00000000 +#define NVOS04_FLAGS_PRIVILEGED_CHANNEL_TRUE 0x00000001 +#define NVOS04_FLAGS_DELAY_CHANNEL_SCHEDULING 6:6 +#define NVOS04_FLAGS_DELAY_CHANNEL_SCHEDULING_FALSE 0x00000000 +#define NVOS04_FLAGS_DELAY_CHANNEL_SCHEDULING_TRUE 0x00000001 +#define NVOS04_FLAGS_CHANNEL_DENY_PHYSICAL_MODE_CE 7:7 +#define NVOS04_FLAGS_CHANNEL_DENY_PHYSICAL_MODE_CE_FALSE 0x00000000 +#define NVOS04_FLAGS_CHANNEL_DENY_PHYSICAL_MODE_CE_TRUE 0x00000001 +#define NVOS04_FLAGS_CHANNEL_USERD_INDEX_VALUE 10:8 +#define NVOS04_FLAGS_CHANNEL_USERD_INDEX_FIXED 11:11 +#define NVOS04_FLAGS_CHANNEL_USERD_INDEX_FIXED_FALSE 0x00000000 +#define NVOS04_FLAGS_CHANNEL_USERD_INDEX_FIXED_TRUE 0x00000001 +#define NVOS04_FLAGS_CHANNEL_USERD_INDEX_PAGE_VALUE 20:12 +#define NVOS04_FLAGS_CHANNEL_USERD_INDEX_PAGE_FIXED 21:21 +#define NVOS04_FLAGS_CHANNEL_USERD_INDEX_PAGE_FIXED_FALSE 0x00000000 +#define NVOS04_FLAGS_CHANNEL_USERD_INDEX_PAGE_FIXED_TRUE 0x00000001 +#define NVOS04_FLAGS_CHANNEL_DENY_AUTH_LEVEL_PRIV 22:22 +#define NVOS04_FLAGS_CHANNEL_DENY_AUTH_LEVEL_PRIV_FALSE 0x00000000 +#define NVOS04_FLAGS_CHANNEL_DENY_AUTH_LEVEL_PRIV_TRUE 0x00000001 +#define NVOS04_FLAGS_CHANNEL_SKIP_SCRUBBER 23:23 +#define NVOS04_FLAGS_CHANNEL_SKIP_SCRUBBER_FALSE 0x00000000 +#define NVOS04_FLAGS_CHANNEL_SKIP_SCRUBBER_TRUE 0x00000001 +#define NVOS04_FLAGS_CHANNEL_CLIENT_MAP_FIFO 24:24 +#define NVOS04_FLAGS_CHANNEL_CLIENT_MAP_FIFO_FALSE 0x00000000 +#define NVOS04_FLAGS_CHANNEL_CLIENT_MAP_FIFO_TRUE 0x00000001 +#define NVOS04_FLAGS_SET_EVICT_LAST_CE_PREFETCH_CHANNEL 25:25 +#define NVOS04_FLAGS_SET_EVICT_LAST_CE_PREFETCH_CHANNEL_FALSE 0x00000000 +#define NVOS04_FLAGS_SET_EVICT_LAST_CE_PREFETCH_CHANNEL_TRUE 0x00000001 +#define NVOS04_FLAGS_CHANNEL_VGPU_PLUGIN_CONTEXT 26:26 +#define NVOS04_FLAGS_CHANNEL_VGPU_PLUGIN_CONTEXT_FALSE 0x00000000 +#define NVOS04_FLAGS_CHANNEL_VGPU_PLUGIN_CONTEXT_TRUE 0x00000001 +#define NVOS04_FLAGS_CHANNEL_PBDMA_ACQUIRE_TIMEOUT 27:27 +#define NVOS04_FLAGS_CHANNEL_PBDMA_ACQUIRE_TIMEOUT_FALSE 0x00000000 +#define NVOS04_FLAGS_CHANNEL_PBDMA_ACQUIRE_TIMEOUT_TRUE 0x00000001 +#define NVOS04_FLAGS_GROUP_CHANNEL_THREAD 29:28 +#define NVOS04_FLAGS_GROUP_CHANNEL_THREAD_DEFAULT 0x00000000 +#define NVOS04_FLAGS_GROUP_CHANNEL_THREAD_ONE 0x00000001 +#define NVOS04_FLAGS_GROUP_CHANNEL_THREAD_TWO 0x00000002 +#define NVOS04_FLAGS_MAP_CHANNEL 30:30 +#define NVOS04_FLAGS_MAP_CHANNEL_FALSE 0x00000000 +#define NVOS04_FLAGS_MAP_CHANNEL_TRUE 0x00000001 +#define NVOS04_FLAGS_SKIP_CTXBUFFER_ALLOC 31:31 +#define NVOS04_FLAGS_SKIP_CTXBUFFER_ALLOC_FALSE 0x00000000 +#define NVOS04_FLAGS_SKIP_CTXBUFFER_ALLOC_TRUE 0x00000001 + +typedef enum { + /*! + * Initial state as passed in NV_CHANNEL_ALLOC_PARAMS by + * kernel CPU-RM clients. + */ + ERROR_NOTIFIER_TYPE_UNKNOWN = 0, + /*! @brief Error notifier is explicitly not set. + * + * The corresponding hErrorContext or hEccErrorContext must be + * NV01_NULL_OBJECT. + */ + ERROR_NOTIFIER_TYPE_NONE, + /*! @brief Error notifier is a ContextDma */ + ERROR_NOTIFIER_TYPE_CTXDMA, + /*! @brief Error notifier is a NvNotification array in sysmem/vidmem */ + ERROR_NOTIFIER_TYPE_MEMORY +} ErrorNotifierType; + +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE 1:0 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE_USER 0x0 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE_ADMIN 0x1 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE_KERNEL 0x2 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE 3:2 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_UNKNOWN ERROR_NOTIFIER_TYPE_UNKNOWN +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_NONE ERROR_NOTIFIER_TYPE_NONE +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_CTXDMA ERROR_NOTIFIER_TYPE_CTXDMA +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_MEMORY ERROR_NOTIFIER_TYPE_MEMORY +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE 5:4 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_UNKNOWN ERROR_NOTIFIER_TYPE_UNKNOWN +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_NONE ERROR_NOTIFIER_TYPE_NONE +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_CTXDMA ERROR_NOTIFIER_TYPE_CTXDMA +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_MEMORY ERROR_NOTIFIER_TYPE_MEMORY + +#define NVA06F_CTRL_CMD_BIND (0xa06f0104) /* finn: Evaluated from "(FINN_KEPLER_CHANNEL_GPFIFO_A_GPFIFO_INTERFACE_ID << 8) | NVA06F_CTRL_BIND_PARAMS_MESSAGE_ID" */ +typedef struct NVA06F_CTRL_BIND_PARAMS { + NvU32 engineType; +} NVA06F_CTRL_BIND_PARAMS; + +#define NVA06F_CTRL_CMD_GPFIFO_SCHEDULE (0xa06f0103) /* finn: Evaluated from "(FINN_KEPLER_CHANNEL_GPFIFO_A_GPFIFO_INTERFACE_ID << 8) | NVA06F_CTRL_GPFIFO_SCHEDULE_PARAMS_MESSAGE_ID" */ +typedef struct NVA06F_CTRL_GPFIFO_SCHEDULE_PARAMS { + NvBool bEnable; + NvBool bSkipSubmit; +} NVA06F_CTRL_GPFIFO_SCHEDULE_PARAMS; + +#define NV2080_CTRL_GPU_PROMOTE_CONTEXT_MAX_ENTRIES 16U + +typedef struct NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ENTRY { + NV_DECLARE_ALIGNED(NvU64 gpuPhysAddr, 8); + NV_DECLARE_ALIGNED(NvU64 gpuVirtAddr, 8); + NV_DECLARE_ALIGNED(NvU64 size, 8); + NvU32 physAttr; + NvU16 bufferId; + NvU8 bInitialize; + NvU8 bNonmapped; +} NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ENTRY; + +#define NV2080_CTRL_CMD_GPU_PROMOTE_CTX (0x2080012bU) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_GPU_INTERFACE_ID << 8) | NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS { + NvU32 engineType; + NvHandle hClient; + NvU32 ChID; + NvHandle hChanClient; + NvHandle hObject; + NvHandle hVirtMemory; + NV_DECLARE_ALIGNED(NvU64 virtAddress, 8); + NV_DECLARE_ALIGNED(NvU64 size, 8); + NvU32 entryCount; + // C form: NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ENTRY promoteEntry[NV2080_CTRL_GPU_PROMOTE_CONTEXT_MAX_ENTRIES]; + NV_DECLARE_ALIGNED(NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ENTRY promoteEntry[NV2080_CTRL_GPU_PROMOTE_CONTEXT_MAX_ENTRIES], 8); +} NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS; + +typedef struct rpc_rc_triggered_v17_02 +{ + NvU32 nv2080EngineType; + NvU32 chid; + NvU32 exceptType; + NvU32 scope; + NvU16 partitionAttributionId; +} rpc_rc_triggered_v17_02; +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080fifo.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/gr.h index 6acb3f73242d..82c5ec727bb4 100644 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl0080/ctrl0080fifo.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/gr.h @@ -1,30 +1,31 @@ -#ifndef __src_common_sdk_nvidia_inc_ctrl_ctrl0080_ctrl0080fifo_h__ -#define __src_common_sdk_nvidia_inc_ctrl_ctrl0080_ctrl0080fifo_h__ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_GR_H__ +#define __NVRM_GR_H__ +#include <nvrm/nvtypes.h> /* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ -/* - * SPDX-FileCopyrightText: Copyright (c) 2006-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ +#define NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO (0x20800a32) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO_PARAMS_MESSAGE_ID" */ + +#define NV2080_CTRL_INTERNAL_GR_MAX_ENGINES 8 + +#define NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT 0x19 + +typedef struct NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO { + NvU32 size; + NvU32 alignment; +} NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO; + +typedef struct NV2080_CTRL_INTERNAL_STATIC_GR_CONTEXT_BUFFERS_INFO { + NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO engine[NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT]; +} NV2080_CTRL_INTERNAL_STATIC_GR_CONTEXT_BUFFERS_INFO; + +typedef struct NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS { + NV2080_CTRL_INTERNAL_STATIC_GR_CONTEXT_BUFFERS_INFO engineContextBuffersInfo[NV2080_CTRL_INTERNAL_GR_MAX_ENGINES]; +} NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS; #define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID 4:0 #define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS (0x00000000) @@ -54,4 +55,19 @@ #define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_PRIV_ACCESS_MAP (0x00000018) #define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT (0x00000019) +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_MAIN 0U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PM 1U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PATCH 2U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_BUFFER_BUNDLE_CB 3U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PAGEPOOL 4U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_ATTRIBUTE_CB 5U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_RTV_CB_GLOBAL 6U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_GFXP_POOL 7U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_GFXP_CTRL_BLK 8U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_FECS_EVENT 9U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_PRIV_ACCESS_MAP 10U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_UNRESTRICTED_PRIV_ACCESS_MAP 11U +#define NV2080_CTRL_GPU_PROMOTE_CTX_BUFFER_ID_GLOBAL_PRIV_ACCESS_MAP 12U + +#include "fifo.h" #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/gsp.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/gsp.h new file mode 100644 index 000000000000..b6683a5bf870 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/gsp.h @@ -0,0 +1,825 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_GSP_H__ +#define __NVRM_GSP_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +#define NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MAX_ENTRIES 16U + +#define NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MEM_TYPES 17U + +typedef NvBool NV2080_CTRL_CMD_FB_GET_FB_REGION_SURFACE_MEM_TYPE_FLAG[NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MEM_TYPES]; + +typedef struct NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO { + NV_DECLARE_ALIGNED(NvU64 base, 8); + NV_DECLARE_ALIGNED(NvU64 limit, 8); + NV_DECLARE_ALIGNED(NvU64 reserved, 8); + NvU32 performance; + NvBool supportCompressed; + NvBool supportISO; + NvBool bProtected; + NV2080_CTRL_CMD_FB_GET_FB_REGION_SURFACE_MEM_TYPE_FLAG blackList; +} NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO; + +typedef struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS { + NvU32 numFBRegions; + NV_DECLARE_ALIGNED(NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO fbRegion[NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MAX_ENTRIES], 8); +} NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS; + +#define NV0080_CTRL_GR_CAPS_TBL_SIZE 23 + +#define NV2080_GPU_MAX_GID_LENGTH (0x000000100ULL) + +typedef struct NV2080_CTRL_GPU_GET_GID_INFO_PARAMS { + NvU32 index; + NvU32 flags; + NvU32 length; + NvU8 data[NV2080_GPU_MAX_GID_LENGTH]; +} NV2080_CTRL_GPU_GET_GID_INFO_PARAMS; + +typedef struct NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS { + NvU32 gpcMask; +} NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS; + +typedef struct NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS { + NvU32 gpcId; + NvU32 tpcMask; +} NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS; + +typedef struct NV2080_CTRL_GPU_GET_FERMI_ZCULL_INFO_PARAMS { + NvU32 gpcId; + NvU32 zcullMask; +} NV2080_CTRL_GPU_GET_FERMI_ZCULL_INFO_PARAMS; + +typedef struct NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS { + NvU32 BoardID; + char chipSKU[4]; + char chipSKUMod[2]; + char project[5]; + char projectSKU[5]; + char CDP[6]; + char projectSKUMod[2]; + NvU32 businessCycle; +} NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS; + +typedef enum +{ + COMPUTE_BRANDING_TYPE_NONE, + COMPUTE_BRANDING_TYPE_TESLA, +} COMPUTE_BRANDING_TYPE; + +#define MAX_GPC_COUNT 32 + +typedef struct NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS { + NvU32 totalVFs; + NvU32 firstVfOffset; + NvU32 vfFeatureMask; + NV_DECLARE_ALIGNED(NvU64 FirstVFBar0Address, 8); + NV_DECLARE_ALIGNED(NvU64 FirstVFBar1Address, 8); + NV_DECLARE_ALIGNED(NvU64 FirstVFBar2Address, 8); + NV_DECLARE_ALIGNED(NvU64 bar0Size, 8); + NV_DECLARE_ALIGNED(NvU64 bar1Size, 8); + NV_DECLARE_ALIGNED(NvU64 bar2Size, 8); + NvBool b64bitBar0; + NvBool b64bitBar1; + NvBool b64bitBar2; + NvBool bSriovEnabled; + NvBool bSriovHeavyEnabled; + NvBool bEmulateVFBar0TlbInvalidationRegister; + NvBool bClientRmAllocatedCtxBuffer; +} NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS; + +#include "engine.h" + +#define NVGPU_ENGINE_CAPS_MASK_BITS 32 + +#define NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX ((RM_ENGINE_TYPE_LAST-1)/NVGPU_ENGINE_CAPS_MASK_BITS + 1) + +typedef struct GspSMInfo_t +{ + NvU32 version; + NvU32 regBankCount; + NvU32 regBankRegCount; + NvU32 maxWarpsPerSM; + NvU32 maxThreadsPerWarp; + NvU32 geomGsObufEntries; + NvU32 geomXbufEntries; + NvU32 maxSPPerSM; + NvU32 rtCoreCount; +} GspSMInfo; + +typedef enum NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS { + NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_MAIN = 0, + NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_SPILL = 1, + NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_PAGEPOOL = 2, + NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_BETACB = 3, + NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_RTV = 4, + NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_CONTEXT_POOL = 5, + NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_CONTEXT_POOL_CONTROL = 6, + NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_CONTEXT_POOL_CONTROL_CPU = 7, + NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_END = 8, +} NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS; + +#define NV2080_GPU_MAX_NAME_STRING_LENGTH (0x0000040U) + +typedef struct VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS +{ + NvU32 numHeads; + NvU32 maxNumHeads; +} VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS; + +typedef struct VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS +{ + NvU32 headIndex; + NvU32 maxHResolution; + NvU32 maxVResolution; +} VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS; + +typedef struct GspStaticConfigInfo_t +{ + NvU8 grCapsBits[NV0080_CTRL_GR_CAPS_TBL_SIZE]; + NV2080_CTRL_GPU_GET_GID_INFO_PARAMS gidInfo; + NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS gpcInfo; + NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS tpcInfo[MAX_GPC_COUNT]; + NV2080_CTRL_GPU_GET_FERMI_ZCULL_INFO_PARAMS zcullInfo[MAX_GPC_COUNT]; + NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS SKUInfo; + NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS fbRegionInfoParams; + COMPUTE_BRANDING_TYPE computeBranding; + + NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS sriovCaps; + NvU32 sriovMaxGfid; + + NvU32 engineCaps[NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX]; + + GspSMInfo SM_info; + + NvBool poisonFuseEnabled; + + NvU64 fb_length; + NvU32 fbio_mask; + NvU32 fb_bus_width; + NvU32 fb_ram_type; + NvU32 fbp_mask; + NvU32 l2_cache_size; + + NvU32 gfxpBufferSize[NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_CONTEXT_POOL]; + NvU32 gfxpBufferAlignment[NV2080_CTRL_CMD_GR_CTXSW_PREEMPTION_BIND_BUFFERS_CONTEXT_POOL]; + + NvU8 gpuNameString[NV2080_GPU_MAX_NAME_STRING_LENGTH]; + NvU8 gpuShortNameString[NV2080_GPU_MAX_NAME_STRING_LENGTH]; + NvU16 gpuNameString_Unicode[NV2080_GPU_MAX_NAME_STRING_LENGTH]; + NvBool bGpuInternalSku; + NvBool bIsQuadroGeneric; + NvBool bIsQuadroAd; + NvBool bIsNvidiaNvs; + NvBool bIsVgx; + NvBool bGeforceSmb; + NvBool bIsTitan; + NvBool bIsTesla; + NvBool bIsMobile; + NvBool bIsGc6Rtd3Allowed; + NvBool bIsGcOffRtd3Allowed; + NvBool bIsGcoffLegacyAllowed; + + NvU64 bar1PdeBase; + NvU64 bar2PdeBase; + + NvBool bVbiosValid; + NvU32 vbiosSubVendor; + NvU32 vbiosSubDevice; + + NvBool bPageRetirementSupported; + + NvBool bSplitVasBetweenServerClientRm; + + NvBool bClRootportNeedsNosnoopWAR; + + VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS displaylessMaxHeads; + VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS displaylessMaxResolution; + NvU64 displaylessMaxPixels; + + // Client handle for internal RMAPI control. + NvHandle hInternalClient; + + // Device handle for internal RMAPI control. + NvHandle hInternalDevice; + + // Subdevice handle for internal RMAPI control. + NvHandle hInternalSubdevice; + + NvBool bSelfHostedMode; + NvBool bAtsSupported; + + NvBool bIsGpuUefi; +} GspStaticConfigInfo; + +typedef struct rpc_unloading_guest_driver_v1F_07 +{ + NvBool bInPMTransition; + NvBool bGc6Entering; + NvU32 newLevel; +} rpc_unloading_guest_driver_v1F_07; + +typedef struct PACKED_REGISTRY_ENTRY +{ + NvU32 nameOffset; + NvU8 type; + NvU32 data; + NvU32 length; +} PACKED_REGISTRY_ENTRY; + +typedef struct PACKED_REGISTRY_TABLE +{ + NvU32 size; + NvU32 numEntries; + PACKED_REGISTRY_ENTRY entries[] __counted_by(numEntries); +} PACKED_REGISTRY_TABLE; + +typedef struct +{ + NvU16 deviceID; // deviceID + NvU16 vendorID; // vendorID + NvU16 subdeviceID; // subsystem deviceID + NvU16 subvendorID; // subsystem vendorID + NvU8 revisionID; // revision ID +} BUSINFO; + +#define NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS (16U) + +typedef struct DOD_METHOD_DATA +{ + NV_STATUS status; + NvU32 acpiIdListLen; + NvU32 acpiIdList[NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS]; +} DOD_METHOD_DATA; + +typedef struct JT_METHOD_DATA +{ + NV_STATUS status; + NvU32 jtCaps; + NvU16 jtRevId; + NvBool bSBIOSCaps; +} JT_METHOD_DATA; + +typedef struct MUX_METHOD_DATA_ELEMENT +{ + NvU32 acpiId; + NvU32 mode; + NV_STATUS status; +} MUX_METHOD_DATA_ELEMENT; + +#define NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS (16U) + +typedef struct MUX_METHOD_DATA +{ + NvU32 tableLen; + MUX_METHOD_DATA_ELEMENT acpiIdMuxModeTable[NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS]; + MUX_METHOD_DATA_ELEMENT acpiIdMuxPartTable[NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS]; +} MUX_METHOD_DATA; + +typedef struct CAPS_METHOD_DATA +{ + NV_STATUS status; + NvU32 optimusCaps; +} CAPS_METHOD_DATA; + +typedef struct ACPI_METHOD_DATA +{ + NvBool bValid; + DOD_METHOD_DATA dodMethodData; + JT_METHOD_DATA jtMethodData; + MUX_METHOD_DATA muxMethodData; + CAPS_METHOD_DATA capsMethodData; +} ACPI_METHOD_DATA; + +typedef struct GSP_VF_INFO +{ + NvU32 totalVFs; + NvU32 firstVFOffset; + NvU64 FirstVFBar0Address; + NvU64 FirstVFBar1Address; + NvU64 FirstVFBar2Address; + NvBool b64bitBar0; + NvBool b64bitBar1; + NvBool b64bitBar2; +} GSP_VF_INFO; + +typedef struct GspSystemInfo +{ + NvU64 gpuPhysAddr; + NvU64 gpuPhysFbAddr; + NvU64 gpuPhysInstAddr; + NvU64 nvDomainBusDeviceFunc; + NvU64 simAccessBufPhysAddr; + NvU64 pcieAtomicsOpMask; + NvU64 consoleMemSize; + NvU64 maxUserVa; + NvU32 pciConfigMirrorBase; + NvU32 pciConfigMirrorSize; + NvU8 oorArch; + NvU64 clPdbProperties; + NvU32 Chipset; + NvBool bGpuBehindBridge; + NvBool bMnocAvailable; + NvBool bUpstreamL0sUnsupported; + NvBool bUpstreamL1Unsupported; + NvBool bUpstreamL1PorSupported; + NvBool bUpstreamL1PorMobileOnly; + NvU8 upstreamAddressValid; + BUSINFO FHBBusInfo; + BUSINFO chipsetIDInfo; + ACPI_METHOD_DATA acpiMethodData; + NvU32 hypervisorType; + NvBool bIsPassthru; + NvU64 sysTimerOffsetNs; + GSP_VF_INFO gspVFInfo; +} GspSystemInfo; + +typedef struct rpc_os_error_log_v17_00 +{ + NvU32 exceptType; + NvU32 runlistId; + NvU32 chid; + char errString[0x100]; +} rpc_os_error_log_v17_00; + +typedef struct rpc_run_cpu_sequencer_v17_00 +{ + NvU32 bufferSizeDWord; + NvU32 cmdIndex; + NvU32 regSaveArea[8]; + NvU32 commandBuffer[]; +} rpc_run_cpu_sequencer_v17_00; + +typedef enum GSP_SEQ_BUF_OPCODE +{ + GSP_SEQ_BUF_OPCODE_REG_WRITE = 0, + GSP_SEQ_BUF_OPCODE_REG_MODIFY, + GSP_SEQ_BUF_OPCODE_REG_POLL, + GSP_SEQ_BUF_OPCODE_DELAY_US, + GSP_SEQ_BUF_OPCODE_REG_STORE, + GSP_SEQ_BUF_OPCODE_CORE_RESET, + GSP_SEQ_BUF_OPCODE_CORE_START, + GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT, + GSP_SEQ_BUF_OPCODE_CORE_RESUME, +} GSP_SEQ_BUF_OPCODE; + +typedef struct +{ + NvU32 addr; + NvU32 val; +} GSP_SEQ_BUF_PAYLOAD_REG_WRITE; + +typedef struct +{ + NvU32 addr; + NvU32 mask; + NvU32 val; +} GSP_SEQ_BUF_PAYLOAD_REG_MODIFY; + +typedef struct +{ + NvU32 addr; + NvU32 mask; + NvU32 val; + NvU32 timeout; + NvU32 error; +} GSP_SEQ_BUF_PAYLOAD_REG_POLL; + +typedef struct +{ + NvU32 val; +} GSP_SEQ_BUF_PAYLOAD_DELAY_US; + +typedef struct +{ + NvU32 addr; + NvU32 index; +} GSP_SEQ_BUF_PAYLOAD_REG_STORE; + +typedef struct GSP_SEQUENCER_BUFFER_CMD +{ + GSP_SEQ_BUF_OPCODE opCode; + union + { + GSP_SEQ_BUF_PAYLOAD_REG_WRITE regWrite; + GSP_SEQ_BUF_PAYLOAD_REG_MODIFY regModify; + GSP_SEQ_BUF_PAYLOAD_REG_POLL regPoll; + GSP_SEQ_BUF_PAYLOAD_DELAY_US delayUs; + GSP_SEQ_BUF_PAYLOAD_REG_STORE regStore; + } payload; +} GSP_SEQUENCER_BUFFER_CMD; + +typedef struct +{ + // Magic + // BL to use for verification (i.e. Booter locked it in WPR2) + NvU64 magic; // = 0xdc3aae21371a60b3; + + // Revision number of Booter-BL-Sequencer handoff interface + // Bumped up when we change this interface so it is not backward compatible. + // Bumped up when we revoke GSP-RM ucode + NvU64 revision; // = 1; + + // ---- Members regarding data in SYSMEM ---------------------------- + // Consumed by Booter for DMA + + NvU64 sysmemAddrOfRadix3Elf; + NvU64 sizeOfRadix3Elf; + + NvU64 sysmemAddrOfBootloader; + NvU64 sizeOfBootloader; + + // Offsets inside bootloader image needed by Booter + NvU64 bootloaderCodeOffset; + NvU64 bootloaderDataOffset; + NvU64 bootloaderManifestOffset; + + union + { + // Used only at initial boot + struct + { + NvU64 sysmemAddrOfSignature; + NvU64 sizeOfSignature; + }; + + // + // Used at suspend/resume to read GspFwHeapFreeList + // Offset relative to GspFwWprMeta FBMEM PA (gspFwWprStart) + // + struct + { + NvU32 gspFwHeapFreeListWprOffset; + NvU32 unused0; + NvU64 unused1; + }; + }; + + // ---- Members describing FB layout -------------------------------- + NvU64 gspFwRsvdStart; + + NvU64 nonWprHeapOffset; + NvU64 nonWprHeapSize; + + NvU64 gspFwWprStart; + + // GSP-RM to use to setup heap. + NvU64 gspFwHeapOffset; + NvU64 gspFwHeapSize; + + // BL to use to find ELF for jump + NvU64 gspFwOffset; + // Size is sizeOfRadix3Elf above. + + NvU64 bootBinOffset; + // Size is sizeOfBootloader above. + + NvU64 frtsOffset; + NvU64 frtsSize; + + NvU64 gspFwWprEnd; + + // GSP-RM to use for fbRegionInfo? + NvU64 fbSize; + + // ---- Other members ----------------------------------------------- + + // GSP-RM to use for fbRegionInfo? + NvU64 vgaWorkspaceOffset; + NvU64 vgaWorkspaceSize; + + // Boot count. Used to determine whether to load the firmware image. + NvU64 bootCount; + + // This union is organized the way it is to start at an 8-byte boundary and achieve natural + // packing of the internal struct fields. + union + { + struct + { + // TODO: the partitionRpc* fields below do not really belong in this + // structure. The values are patched in by the partition bootstrapper + // when GSP-RM is booted in a partition, and this structure was a + // convenient place for the bootstrapper to access them. These should + // be moved to a different comm. mechanism between the bootstrapper + // and the GSP-RM tasks. + + // Shared partition RPC memory (physical address) + NvU64 partitionRpcAddr; + + // Offsets relative to partitionRpcAddr + NvU16 partitionRpcRequestOffset; + NvU16 partitionRpcReplyOffset; + + // Code section and dataSection offset and size. + NvU32 elfCodeOffset; + NvU32 elfDataOffset; + NvU32 elfCodeSize; + NvU32 elfDataSize; + + // Used during GSP-RM resume to check for revocation + NvU32 lsUcodeVersion; + }; + + struct + { + // Pad for the partitionRpc* fields, plus 4 bytes + NvU32 partitionRpcPadding[4]; + + // CrashCat (contiguous) buffer size/location - occupies same bytes as the + // elf(Code|Data)(Offset|Size) fields above. + // TODO: move to GSP_FMC_INIT_PARAMS + NvU64 sysmemAddrOfCrashReportQueue; + NvU32 sizeOfCrashReportQueue; + + // Pad for the lsUcodeVersion field + NvU32 lsUcodeVersionPadding[1]; + }; + }; + + // Number of VF partitions allocating sub-heaps from the WPR heap + // Used during boot to ensure the heap is adequately sized + NvU8 gspFwHeapVfPartitionCount; + + // Pad structure to exactly 256 bytes. Can replace padding with additional + // fields without incrementing revision. Padding initialized to 0. + NvU8 padding[7]; + + // BL to use for verification (i.e. Booter says OK to boot) + NvU64 verified; // 0x0 -> unverified, 0xa0a0a0a0a0a0a0a0 -> verified +} GspFwWprMeta; + +#define GSP_FW_WPR_META_MAGIC 0xdc3aae21371a60b3ULL + +#define GSP_FW_WPR_META_REVISION 1 + +typedef struct +{ + NvU32 version; // queue version + NvU32 size; // bytes, page aligned + NvU32 msgSize; // entry size, bytes, must be power-of-2, 16 is minimum + NvU32 msgCount; // number of entries in queue + NvU32 writePtr; // message id of next slot + NvU32 flags; // if set it means "i want to swap RX" + NvU32 rxHdrOff; // Offset of msgqRxHeader from start of backing store. + NvU32 entryOff; // Offset of entries from start of backing store. +} msgqTxHeader; + +typedef struct +{ + NvU32 readPtr; // message id of last message read +} msgqRxHeader; + +typedef struct { + RmPhysAddr sharedMemPhysAddr; + NvU32 pageTableEntryCount; + NvLength cmdQueueOffset; + NvLength statQueueOffset; + NvLength locklessCmdQueueOffset; + NvLength locklessStatQueueOffset; +} MESSAGE_QUEUE_INIT_ARGUMENTS; + +typedef struct { + NvU32 oldLevel; + NvU32 flags; + NvBool bInPMTransition; +} GSP_SR_INIT_ARGUMENTS; + +typedef struct +{ + MESSAGE_QUEUE_INIT_ARGUMENTS messageQueueInitArguments; + GSP_SR_INIT_ARGUMENTS srInitArguments; + NvU32 gpuInstance; + + struct + { + NvU64 pa; + NvU64 size; + } profilerArgs; +} GSP_ARGUMENTS_CACHED; + +#define NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_0 (0x00000000U) + +#define NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3 (0x00000003U) + +typedef NvU64 LibosAddress; + +typedef struct +{ + LibosAddress id8; // Id tag. + LibosAddress pa; // Physical address. + LibosAddress size; // Size of memory area. + NvU8 kind; // See LibosMemoryRegionKind above. + NvU8 loc; // See LibosMemoryRegionLoc above. +} LibosMemoryRegionInitArgument; + +typedef enum { + LIBOS_MEMORY_REGION_NONE, + LIBOS_MEMORY_REGION_CONTIGUOUS, + LIBOS_MEMORY_REGION_RADIX3 +} LibosMemoryRegionKind; + +typedef enum { + LIBOS_MEMORY_REGION_LOC_NONE, + LIBOS_MEMORY_REGION_LOC_SYSMEM, + LIBOS_MEMORY_REGION_LOC_FB +} LibosMemoryRegionLoc; + +typedef struct +{ + // + // Magic + // Use for verification by Booter + // + NvU64 magic; // = GSP_FW_SR_META_MAGIC; + + // + // Revision number + // Bumped up when we change this interface so it is not backward compatible. + // Bumped up when we revoke GSP-RM ucode + // + NvU64 revision; // = GSP_FW_SR_META_MAGIC_REVISION; + + // + // ---- Members regarding data in SYSMEM ---------------------------- + // Consumed by Booter for DMA + // + NvU64 sysmemAddrOfSuspendResumeData; + NvU64 sizeOfSuspendResumeData; + + // ---- Members for crypto ops across S/R --------------------------- + + // + // HMAC over the entire GspFwSRMeta structure (including padding) + // with the hmac field itself zeroed. + // + NvU8 hmac[32]; + + // Hash over GspFwWprMeta structure + NvU8 wprMetaHash[32]; + + // Hash over GspFwHeapFreeList structure. All zeros signifies no free list. + NvU8 heapFreeListHash[32]; + + // Hash over data in WPR2 (skipping over free heap chunks; see Booter for details) + NvU8 dataHash[32]; + + // + // Pad structure to exactly 256 bytes (1 DMA chunk). + // Padding initialized to zero. + // + NvU32 padding[24]; + +} GspFwSRMeta; + +#define GSP_FW_SR_META_MAGIC 0x8a3bb9e6c6c39d93ULL + +#define GSP_FW_SR_META_REVISION 2 + +#define GSP_SEQUENCER_PAYLOAD_SIZE_DWORDS(opcode) \ + ((opcode == GSP_SEQ_BUF_OPCODE_REG_WRITE) ? (sizeof(GSP_SEQ_BUF_PAYLOAD_REG_WRITE) / sizeof(NvU32)) : \ + (opcode == GSP_SEQ_BUF_OPCODE_REG_MODIFY) ? (sizeof(GSP_SEQ_BUF_PAYLOAD_REG_MODIFY) / sizeof(NvU32)) : \ + (opcode == GSP_SEQ_BUF_OPCODE_REG_POLL) ? (sizeof(GSP_SEQ_BUF_PAYLOAD_REG_POLL) / sizeof(NvU32)) : \ + (opcode == GSP_SEQ_BUF_OPCODE_DELAY_US) ? (sizeof(GSP_SEQ_BUF_PAYLOAD_DELAY_US) / sizeof(NvU32)) : \ + (opcode == GSP_SEQ_BUF_OPCODE_REG_STORE) ? (sizeof(GSP_SEQ_BUF_PAYLOAD_REG_STORE) / sizeof(NvU32)) : \ + /* GSP_SEQ_BUF_OPCODE_CORE_RESET */ \ + /* GSP_SEQ_BUF_OPCODE_CORE_START */ \ + /* GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT */ \ + /* GSP_SEQ_BUF_OPCODE_CORE_RESUME */ \ + 0) + +typedef struct { + // + // Version 1 + // Version 2 + // Version 3 = for Partition boot + // Version 4 = for eb riscv boot + // Version 5 = Support signing entire RISC-V image as "code" in code section for hopper and later. + // + NvU32 version; // structure version + NvU32 bootloaderOffset; + NvU32 bootloaderSize; + NvU32 bootloaderParamOffset; + NvU32 bootloaderParamSize; + NvU32 riscvElfOffset; + NvU32 riscvElfSize; + NvU32 appVersion; // Changelist number associated with the image + // + // Manifest contains information about Monitor and it is + // input to BR + // + NvU32 manifestOffset; + NvU32 manifestSize; + // + // Monitor Data offset within RISCV image and size + // + NvU32 monitorDataOffset; + NvU32 monitorDataSize; + // + // Monitor Code offset withtin RISCV image and size + // + NvU32 monitorCodeOffset; + NvU32 monitorCodeSize; + NvU32 bIsMonitorEnabled; + // + // Swbrom Code offset within RISCV image and size + // + NvU32 swbromCodeOffset; + NvU32 swbromCodeSize; + // + // Swbrom Data offset within RISCV image and size + // + NvU32 swbromDataOffset; + NvU32 swbromDataSize; + // + // Total size of FB carveout (image and reserved space). + // + NvU32 fbReservedSize; + // + // Indicates whether the entire RISC-V image is signed as "code" in code section. + // + NvU32 bSignedAsCode; +} RM_RISCV_UCODE_DESC; + +typedef struct NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_ENTRY { + NvU16 engineIdx; + NvU32 pmcIntrMask; + NvU32 vectorStall; + NvU32 vectorNonStall; +} NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_ENTRY; + +typedef struct NV2080_INTR_CATEGORY_SUBTREE_MAP { + NvU8 subtreeStart; + NvU8 subtreeEnd; +} NV2080_INTR_CATEGORY_SUBTREE_MAP; + +#define NV2080_CTRL_INTERNAL_INTR_MAX_TABLE_SIZE 128 + +typedef enum NV2080_INTR_CATEGORY { + NV2080_INTR_CATEGORY_DEFAULT = 0, + NV2080_INTR_CATEGORY_ESCHED_DRIVEN_ENGINE = 1, + NV2080_INTR_CATEGORY_ESCHED_DRIVEN_ENGINE_NOTIFICATION = 2, + NV2080_INTR_CATEGORY_RUNLIST = 3, + NV2080_INTR_CATEGORY_RUNLIST_NOTIFICATION = 4, + NV2080_INTR_CATEGORY_UVM_OWNED = 5, + NV2080_INTR_CATEGORY_UVM_SHARED = 6, + NV2080_INTR_CATEGORY_ENUM_COUNT = 7, +} NV2080_INTR_CATEGORY; + +#define NV2080_CTRL_CMD_INTERNAL_INTR_GET_KERNEL_TABLE (0x20800a5c) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_PARAMS { + NvU32 tableLen; + NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_ENTRY table[NV2080_CTRL_INTERNAL_INTR_MAX_TABLE_SIZE]; + NV2080_INTR_CATEGORY_SUBTREE_MAP subtreeMap[NV2080_INTR_CATEGORY_ENUM_COUNT]; +} NV2080_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE_PARAMS; + +#define GSP_FW_HEAP_PARAM_SIZE_PER_GB_FB (96 << 10) // All architectures + +#define GSP_FW_HEAP_PARAM_CLIENT_ALLOC_SIZE ((48 << 10) * 2048) // Support 2048 channels + +typedef union rpc_message_rpc_union_field_v03_00 +{ + NvU32 spare; + NvU32 cpuRmGfid; +} rpc_message_rpc_union_field_v03_00; + +typedef rpc_message_rpc_union_field_v03_00 rpc_message_rpc_union_field_v; + +typedef struct rpc_message_header_v03_00 +{ + NvU32 header_version; + NvU32 signature; + NvU32 length; + NvU32 function; + NvU32 rpc_result; + NvU32 rpc_result_private; + NvU32 sequence; + rpc_message_rpc_union_field_v u; + rpc_generic_union rpc_message_data[]; +} rpc_message_header_v03_00; + +typedef rpc_message_header_v03_00 rpc_message_header_v; + +typedef struct GSP_MSG_QUEUE_ELEMENT +{ + NvU8 authTagBuffer[16]; // Authentication tag buffer. + NvU8 aadBuffer[16]; // AAD buffer. + NvU32 checkSum; // Set to value needed to make checksum always zero. + NvU32 seqNum; // Sequence number maintained by the message queue. + NvU32 elemCount; // Number of message queue elements this message has. + NV_DECLARE_ALIGNED(rpc_message_header_v rpc, 8); +} GSP_MSG_QUEUE_ELEMENT; + +#define GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2 (0 << 20) // No FB heap usage +#define GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3 (20 << 20) + +#define GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X (8 << 20) // Turing thru Ada + +#define GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB (64u) +#define GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB (84u) +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/msgfn.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/msgfn.h new file mode 100644 index 000000000000..642c13aec325 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/msgfn.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_MSGFN_H__ +#define __NVRM_MSGFN_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +#ifndef E +# define E(RPC) NV_VGPU_MSG_EVENT_##RPC, +# define DEFINING_E_IN_RPC_GLOBAL_ENUMS_H +enum { +#endif + E(FIRST_EVENT = 0x1000) // 0x1000 + E(GSP_INIT_DONE) // 0x1001 + E(GSP_RUN_CPU_SEQUENCER) // 0x1002 + E(POST_EVENT) // 0x1003 + E(RC_TRIGGERED) // 0x1004 + E(MMU_FAULT_QUEUED) // 0x1005 + E(OS_ERROR_LOG) // 0x1006 + E(RG_LINE_INTR) // 0x1007 + E(GPUACCT_PERFMON_UTIL_SAMPLES) // 0x1008 + E(SIM_READ) // 0x1009 + E(SIM_WRITE) // 0x100a + E(SEMAPHORE_SCHEDULE_CALLBACK) // 0x100b + E(UCODE_LIBOS_PRINT) // 0x100c + E(VGPU_GSP_PLUGIN_TRIGGERED) // 0x100d + E(PERF_GPU_BOOST_SYNC_LIMITS_CALLBACK) // 0x100e + E(PERF_BRIDGELESS_INFO_UPDATE) // 0x100f + E(VGPU_CONFIG) // 0x1010 + E(DISPLAY_MODESET) // 0x1011 + E(EXTDEV_INTR_SERVICE) // 0x1012 + E(NVLINK_INBAND_RECEIVED_DATA_256) // 0x1013 + E(NVLINK_INBAND_RECEIVED_DATA_512) // 0x1014 + E(NVLINK_INBAND_RECEIVED_DATA_1024) // 0x1015 + E(NVLINK_INBAND_RECEIVED_DATA_2048) // 0x1016 + E(NVLINK_INBAND_RECEIVED_DATA_4096) // 0x1017 + E(TIMED_SEMAPHORE_RELEASE) // 0x1018 + E(NVLINK_IS_GPU_DEGRADED) // 0x1019 + E(PFM_REQ_HNDLR_STATE_SYNC_CALLBACK) // 0x101a + E(GSP_SEND_USER_SHARED_DATA) // 0x101b + E(NVLINK_FAULT_UP) // 0x101c + E(GSP_LOCKDOWN_NOTICE) // 0x101d + E(MIG_CI_CONFIG_UPDATE) // 0x101e + E(NUM_EVENTS) // END +#ifdef DEFINING_E_IN_RPC_GLOBAL_ENUMS_H +}; +# undef E +# undef DEFINING_E_IN_RPC_GLOBAL_ENUMS_H +#endif +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvdec.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvdec.h new file mode 100644 index 000000000000..3a04e702677f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvdec.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_NVDEC_H__ +#define __NVRM_NVDEC_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +typedef struct +{ + NvU32 size; + NvU32 prohibitMultipleInstances; + NvU32 engineInstance; // Select NVDEC0 or NVDEC1 or NVDEC2 +} NV_BSP_ALLOCATION_PARAMETERS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvenc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvenc.h new file mode 100644 index 000000000000..203c1d5304d9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvenc.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_NVENC_H__ +#define __NVRM_NVENC_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +typedef struct +{ + NvU32 size; + NvU32 prohibitMultipleInstances; // Prohibit multiple allocations of MSENC? + NvU32 engineInstance; // Select MSENC/NVENC0 or NVENC1 or NVENC2 +} NV_MSENC_ALLOCATION_PARAMETERS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvjpg.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvjpg.h new file mode 100644 index 000000000000..71fc53889ec7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/nvjpg.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_NVJPG_H__ +#define __NVRM_NVJPG_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +typedef struct +{ + NvU32 size; + NvU32 prohibitMultipleInstances; // Prohibit multiple allocations of NVJPG? + NvU32 engineInstance; +} NV_NVJPG_ALLOCATION_PARAMETERS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ofa.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ofa.h new file mode 100644 index 000000000000..49d81c7673d2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/ofa.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_OFA_H__ +#define __NVRM_OFA_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +typedef struct +{ + NvU32 size; + NvU32 prohibitMultipleInstances; // Prohibit multiple allocations of OFA? +} NV_OFA_ALLOCATION_PARAMETERS; +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/rpcfn.h index 73c57f235f6a..2a037acc6b1e 100644 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/rpcfn.h @@ -1,5 +1,10 @@ -#ifndef __src_nvidia_kernel_inc_vgpu_rpc_global_enums_h__ -#define __src_nvidia_kernel_inc_vgpu_rpc_global_enums_h__ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_RPCFN_H__ +#define __NVRM_RPCFN_H__ +#include <nvrm/nvtypes.h> /* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ @@ -209,54 +214,12 @@ enum { X(RM, CTRL_SET_HS_CREDITS) // 198 X(RM, CTRL_PM_AREA_PC_SAMPLER) // 199 X(RM, INVALIDATE_TLB) // 200 + X(RM, RESERVED_201) // 201 + X(RM, ECC_NOTIFIER_WRITE_ACK) // 202 X(RM, NUM_FUNCTIONS) //END #ifdef DEFINING_X_IN_RPC_GLOBAL_ENUMS_H }; # undef X # undef DEFINING_X_IN_RPC_GLOBAL_ENUMS_H #endif - -#ifndef E -# define E(RPC) NV_VGPU_MSG_EVENT_##RPC, -# define DEFINING_E_IN_RPC_GLOBAL_ENUMS_H -enum { -#endif - E(FIRST_EVENT = 0x1000) // 0x1000 - E(GSP_INIT_DONE) // 0x1001 - E(GSP_RUN_CPU_SEQUENCER) // 0x1002 - E(POST_EVENT) // 0x1003 - E(RC_TRIGGERED) // 0x1004 - E(MMU_FAULT_QUEUED) // 0x1005 - E(OS_ERROR_LOG) // 0x1006 - E(RG_LINE_INTR) // 0x1007 - E(GPUACCT_PERFMON_UTIL_SAMPLES) // 0x1008 - E(SIM_READ) // 0x1009 - E(SIM_WRITE) // 0x100a - E(SEMAPHORE_SCHEDULE_CALLBACK) // 0x100b - E(UCODE_LIBOS_PRINT) // 0x100c - E(VGPU_GSP_PLUGIN_TRIGGERED) // 0x100d - E(PERF_GPU_BOOST_SYNC_LIMITS_CALLBACK) // 0x100e - E(PERF_BRIDGELESS_INFO_UPDATE) // 0x100f - E(VGPU_CONFIG) // 0x1010 - E(DISPLAY_MODESET) // 0x1011 - E(EXTDEV_INTR_SERVICE) // 0x1012 - E(NVLINK_INBAND_RECEIVED_DATA_256) // 0x1013 - E(NVLINK_INBAND_RECEIVED_DATA_512) // 0x1014 - E(NVLINK_INBAND_RECEIVED_DATA_1024) // 0x1015 - E(NVLINK_INBAND_RECEIVED_DATA_2048) // 0x1016 - E(NVLINK_INBAND_RECEIVED_DATA_4096) // 0x1017 - E(TIMED_SEMAPHORE_RELEASE) // 0x1018 - E(NVLINK_IS_GPU_DEGRADED) // 0x1019 - E(PFM_REQ_HNDLR_STATE_SYNC_CALLBACK) // 0x101a - E(GSP_SEND_USER_SHARED_DATA) // 0x101b - E(NVLINK_FAULT_UP) // 0x101c - E(GSP_LOCKDOWN_NOTICE) // 0x101d - E(MIG_CI_CONFIG_UPDATE) // 0x101e - E(NUM_EVENTS) // END -#ifdef DEFINING_E_IN_RPC_GLOBAL_ENUMS_H -}; -# undef E -# undef DEFINING_E_IN_RPC_GLOBAL_ENUMS_H -#endif - #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h new file mode 100644 index 000000000000..f6ec04efd119 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/nvrm/vmm.h @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_VMM_H__ +#define __NVRM_VMM_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ + +#define FERMI_VASPACE_A (0x000090f1) + +typedef struct +{ + NvU32 index; + NvV32 flags; + NvU64 vaSize NV_ALIGN_BYTES(8); + NvU64 vaStartInternal NV_ALIGN_BYTES(8); + NvU64 vaLimitInternal NV_ALIGN_BYTES(8); + NvU32 bigPageSize; + NvU64 vaBase NV_ALIGN_BYTES(8); +} NV_VASPACE_ALLOCATION_PARAMETERS; + +#define NV_VASPACE_ALLOCATION_INDEX_GPU_NEW 0x00 //<! Create new VASpace, by default + +#define NV_VASPACE_ALLOCATION_FLAGS_IS_EXTERNALLY_OWNED BIT(3) + +#define SPLIT_VAS_SERVER_RM_MANAGED_VA_START 0x100000000ULL // 4GB +#define SPLIT_VAS_SERVER_RM_MANAGED_VA_SIZE 0x20000000ULL // 512MB + +#define GMMU_FMT_MAX_LEVELS 6U + +#define NV90F1_CTRL_CMD_VASPACE_COPY_SERVER_RESERVED_PDES (0x90f10106U) /* finn: Evaluated from "(FINN_FERMI_VASPACE_A_VASPACE_INTERFACE_ID << 8) | NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS_MESSAGE_ID" */ +typedef struct NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS { + /*! + * [in] GPU sub-device handle - this API only supports unicast. + * Pass 0 to use subDeviceId instead. + */ + NvHandle hSubDevice; + + /*! + * [in] GPU sub-device ID. Ignored if hSubDevice is non-zero. + */ + NvU32 subDeviceId; + + /*! + * [in] Page size (VA coverage) of the level to reserve. + * This need not be a leaf (page table) page size - it can be + * the coverage of an arbitrary level (including root page directory). + */ + NV_DECLARE_ALIGNED(NvU64 pageSize, 8); + + /*! + * [in] First GPU virtual address of the range to reserve. + * This must be aligned to pageSize. + */ + NV_DECLARE_ALIGNED(NvU64 virtAddrLo, 8); + + /*! + * [in] Last GPU virtual address of the range to reserve. + * This (+1) must be aligned to pageSize. + */ + NV_DECLARE_ALIGNED(NvU64 virtAddrHi, 8); + + /*! + * [in] Number of PDE levels to copy. + */ + NvU32 numLevelsToCopy; + + /*! + * [in] Per-level information. + */ + struct { + /*! + * Physical address of this page level instance. + */ + NV_DECLARE_ALIGNED(NvU64 physAddress, 8); + + /*! + * Size in bytes allocated for this level instance. + */ + NV_DECLARE_ALIGNED(NvU64 size, 8); + + /*! + * Aperture in which this page level instance resides. + */ + NvU32 aperture; + + /*! + * Page shift corresponding to the level + */ + NvU8 pageShift; + } levels[GMMU_FMT_MAX_LEVELS]; +} NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS; + +#define NV0080_CTRL_CMD_DMA_SET_PAGE_DIRECTORY (0x801813U) /* finn: Evaluated from "(FINN_NV01_DEVICE_0_DMA_INTERFACE_ +ID << 8) | NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS_MESSAGE_ID" */ + +typedef struct NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS { + NV_DECLARE_ALIGNED(NvU64 physAddress, 8); + NvU32 numEntries; + NvU32 flags; + NvHandle hVASpace; + NvU32 chId; + NvU32 subDeviceId; // ID+1, 0 for BC + NvU32 pasid; +} NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS; + +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE 1:0 +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE_VIDMEM (0x00000000U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE_SYSMEM_COH (0x00000001U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_APERTURE_SYSMEM_NONCOH (0x00000002U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_PRESERVE_PDES 2:2 +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_PRESERVE_PDES_FALSE (0x00000000U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_PRESERVE_PDES_TRUE (0x00000001U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_ALL_CHANNELS 3:3 +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_ALL_CHANNELS_FALSE (0x00000000U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_ALL_CHANNELS_TRUE (0x00000001U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_IGNORE_CHANNEL_BUSY 4:4 +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_IGNORE_CHANNEL_BUSY_FALSE (0x00000000U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_IGNORE_CHANNEL_BUSY_TRUE (0x00000001U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_EXTEND_VASPACE 5:5 +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_EXTEND_VASPACE_FALSE (0x00000000U) +#define NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_FLAGS_EXTEND_VASPACE_TRUE (0x00000001U) + +#define NV0080_CTRL_CMD_DMA_UNSET_PAGE_DIRECTORY (0x801814U) /* finn: Evaluated from "(FINN_NV01_DEVICE_0_DMA_INTERFACE_ID << 8) | NV0080_CTRL_DMA_UNSET_PAGE_DIRECTORY_PARAMS_MESSAGE_ID" */ + +typedef struct NV0080_CTRL_DMA_UNSET_PAGE_DIRECTORY_PARAMS { + NvHandle hVASpace; + NvU32 subDeviceId; // ID+1, 0 for BC +} NV0080_CTRL_DMA_UNSET_PAGE_DIRECTORY_PARAMS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ad102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ofa.c index d72b3aae9a2b..2156808cba4f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/ad102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ofa.c @@ -19,26 +19,26 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "priv.h" +#include <rm/engine.h> -#include <subdev/gsp.h> +#include "nvrm/ofa.h" -#include <nvif/class.h> +static int +r535_ofa_alloc(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *ofa) +{ + NV_OFA_ALLOCATION_PARAMETERS *args; -static const struct nvkm_engine_func -ad102_nvdec = { - .sclass = { - { -1, -1, NVC9B0_VIDEO_DECODER }, - {} - } -}; + args = nvkm_gsp_rm_alloc_get(chan, handle, class, sizeof(*args), ofa); + if (WARN_ON(IS_ERR(args))) + return PTR_ERR(args); -int -ad102_nvdec_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, - struct nvkm_nvdec **pnvdec) -{ - if (nvkm_gsp_rm(device->gsp)) - return r535_nvdec_new(&ad102_nvdec, device, type, inst, pnvdec); + args->size = sizeof(*args); - return -ENODEV; + return nvkm_gsp_rm_alloc_wr(ofa, args); } + +const struct nvkm_rm_api_engine +r535_ofa = { + .alloc = r535_ofa_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c new file mode 100644 index 000000000000..a4190676e1ad --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <rm/rm.h> + +#include "nvrm/gsp.h" + +static const struct nvkm_rm_wpr +r535_wpr_libos2 = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB, +}; + +static const struct nvkm_rm_wpr +r535_wpr_libos3 = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, +}; + +static const struct nvkm_rm_api +r535_api = { + .gsp = &r535_gsp, + .rpc = &r535_rpc, + .ctrl = &r535_ctrl, + .alloc = &r535_alloc, + .client = &r535_client, + .device = &r535_device, + .fbsr = &r535_fbsr, + .disp = &r535_disp, + .fifo = &r535_fifo, + .ce = &r535_ce, + .gr = &r535_gr, + .nvdec = &r535_nvdec, + .nvenc = &r535_nvenc, + .nvjpg = &r535_nvjpg, + .ofa = &r535_ofa, +}; + +const struct nvkm_rm_impl +r535_rm_tu102 = { + .wpr = &r535_wpr_libos2, + .api = &r535_api, +}; + +const struct nvkm_rm_impl +r535_rm_ga102 = { + .wpr = &r535_wpr_libos3, + .api = &r535_api, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c new file mode 100644 index 000000000000..5acb98d137bd --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c @@ -0,0 +1,691 @@ +/* + * Copyright 2023 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include <rm/rpc.h> + +#include "nvrm/rpcfn.h" + +#define GSP_MSG_MIN_SIZE GSP_PAGE_SIZE +#define GSP_MSG_MAX_SIZE (GSP_MSG_MIN_SIZE * 16) + +/** + * DOC: GSP message queue element + * + * https://github.com/NVIDIA/open-gpu-kernel-modules/blob/535/src/nvidia/inc/kernel/gpu/gsp/message_queue_priv.h + * + * The GSP command queue and status queue are message queues for the + * communication between software and GSP. The software submits the GSP + * RPC via the GSP command queue, GSP writes the status of the submitted + * RPC in the status queue. + * + * A GSP message queue element consists of three parts: + * + * - message element header (struct r535_gsp_msg), which mostly maintains + * the metadata for queuing the element. + * + * - RPC message header (struct nvfw_gsp_rpc), which maintains the info + * of the RPC. E.g., the RPC function number. + * + * - The payload, where the RPC message stays. E.g. the params of a + * specific RPC function. Some RPC functions also have their headers + * in the payload. E.g. rm_alloc, rm_control. + * + * The memory layout of a GSP message element can be illustrated below:: + * + * +------------------------+ + * | Message Element Header | + * | (r535_gsp_msg) | + * | | + * | (r535_gsp_msg.data) | + * | | | + * |----------V-------------| + * | GSP RPC Header | + * | (nvfw_gsp_rpc) | + * | | + * | (nvfw_gsp_rpc.data) | + * | | | + * |----------V-------------| + * | Payload | + * | | + * | header(optional) | + * | params | + * +------------------------+ + * + * The max size of a message queue element is 16 pages (including the + * headers). When a GSP message to be sent is larger than 16 pages, the + * message should be split into multiple elements and sent accordingly. + * + * In the bunch of the split elements, the first element has the expected + * function number, while the rest of the elements are sent with the + * function number NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD. + * + * GSP consumes the elements from the cmdq and always writes the result + * back to the msgq. The result is also formed as split elements. + * + * Terminology: + * + * - gsp_msg(msg): GSP message element (element header + GSP RPC header + + * payload) + * - gsp_rpc(rpc): GSP RPC (RPC header + payload) + * - gsp_rpc_buf: buffer for (GSP RPC header + payload) + * - gsp_rpc_len: size of (GSP RPC header + payload) + * - params_size: size of params in the payload + * - payload_size: size of (header if exists + params) in the payload + */ + +struct r535_gsp_msg { + u8 auth_tag_buffer[16]; + u8 aad_buffer[16]; + u32 checksum; + u32 sequence; + u32 elem_count; + u32 pad; + u8 data[]; +}; + +struct nvfw_gsp_rpc { + u32 header_version; + u32 signature; + u32 length; + u32 function; + u32 rpc_result; + u32 rpc_result_private; + u32 sequence; + union { + u32 spare; + u32 cpuRmGfid; + }; + u8 data[]; +}; + +#define GSP_MSG_HDR_SIZE offsetof(struct r535_gsp_msg, data) + +#define to_gsp_hdr(p, header) \ + container_of((void *)p, typeof(*header), data) + +#define to_payload_hdr(p, header) \ + container_of((void *)p, typeof(*header), params) + +int +r535_rpc_status_to_errno(uint32_t rpc_status) +{ + switch (rpc_status) { + case 0x55: /* NV_ERR_NOT_READY */ + case 0x66: /* NV_ERR_TIMEOUT_RETRY */ + return -EBUSY; + case 0x51: /* NV_ERR_NO_MEMORY */ + return -ENOMEM; + default: + return -EINVAL; + } +} + +static int +r535_gsp_msgq_wait(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *ptime) +{ + u32 size, rptr = *gsp->msgq.rptr; + int used; + + size = DIV_ROUND_UP(GSP_MSG_HDR_SIZE + gsp_rpc_len, + GSP_PAGE_SIZE); + if (WARN_ON(!size || size >= gsp->msgq.cnt)) + return -EINVAL; + + do { + u32 wptr = *gsp->msgq.wptr; + + used = wptr + gsp->msgq.cnt - rptr; + if (used >= gsp->msgq.cnt) + used -= gsp->msgq.cnt; + if (used >= size) + break; + + usleep_range(1, 2); + } while (--(*ptime)); + + if (WARN_ON(!*ptime)) + return -ETIMEDOUT; + + return used; +} + +static struct r535_gsp_msg * +r535_gsp_msgq_get_entry(struct nvkm_gsp *gsp) +{ + u32 rptr = *gsp->msgq.rptr; + + /* Skip the first page, which is the message queue info */ + return (void *)((u8 *)gsp->shm.msgq.ptr + GSP_PAGE_SIZE + + rptr * GSP_PAGE_SIZE); +} + +/** + * DOC: Receive a GSP message queue element + * + * Receiving a GSP message queue element from the message queue consists of + * the following steps: + * + * - Peek the element from the queue: r535_gsp_msgq_peek(). + * Peek the first page of the element to determine the total size of the + * message before allocating the proper memory. + * + * - Allocate memory for the message. + * Once the total size of the message is determined from the GSP message + * queue element, the caller of r535_gsp_msgq_recv() allocates the + * required memory. + * + * - Receive the message: r535_gsp_msgq_recv(). + * Copy the message into the allocated memory. Advance the read pointer. + * If the message is a large GSP message, r535_gsp_msgq_recv() calls + * r535_gsp_msgq_recv_one_elem() repeatedly to receive continuation parts + * until the complete message is received. + * r535_gsp_msgq_recv() assembles the payloads of cotinuation parts into + * the return of the large GSP message. + * + * - Free the allocated memory: r535_gsp_msg_done(). + * The user is responsible for freeing the memory allocated for the GSP + * message pages after they have been processed. + */ +static void * +r535_gsp_msgq_peek(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) +{ + struct r535_gsp_msg *mqe; + int ret; + + ret = r535_gsp_msgq_wait(gsp, gsp_rpc_len, retries); + if (ret < 0) + return ERR_PTR(ret); + + mqe = r535_gsp_msgq_get_entry(gsp); + + return mqe->data; +} + +struct r535_gsp_msg_info { + int *retries; + u32 gsp_rpc_len; + void *gsp_rpc_buf; + bool continuation; +}; + +static void +r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl); + +static void * +r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp, + struct r535_gsp_msg_info *info) +{ + u8 *buf = info->gsp_rpc_buf; + u32 rptr = *gsp->msgq.rptr; + struct r535_gsp_msg *mqe; + u32 size, expected, len; + int ret; + + expected = info->gsp_rpc_len; + + ret = r535_gsp_msgq_wait(gsp, expected, info->retries); + if (ret < 0) + return ERR_PTR(ret); + + mqe = r535_gsp_msgq_get_entry(gsp); + + if (info->continuation) { + struct nvfw_gsp_rpc *rpc = (struct nvfw_gsp_rpc *)mqe->data; + + if (rpc->function != NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD) { + nvkm_error(&gsp->subdev, + "Not a continuation of a large RPC\n"); + r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); + return ERR_PTR(-EIO); + } + } + + size = ALIGN(expected + GSP_MSG_HDR_SIZE, GSP_PAGE_SIZE); + + len = ((gsp->msgq.cnt - rptr) * GSP_PAGE_SIZE) - sizeof(*mqe); + len = min_t(u32, expected, len); + + if (info->continuation) + memcpy(buf, mqe->data + sizeof(struct nvfw_gsp_rpc), + len - sizeof(struct nvfw_gsp_rpc)); + else + memcpy(buf, mqe->data, len); + + expected -= len; + + if (expected) { + mqe = (void *)((u8 *)gsp->shm.msgq.ptr + 0x1000 + 0 * 0x1000); + memcpy(buf + len, mqe, expected); + } + + rptr = (rptr + DIV_ROUND_UP(size, GSP_PAGE_SIZE)) % gsp->msgq.cnt; + + mb(); + (*gsp->msgq.rptr) = rptr; + return buf; +} + +static void * +r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) +{ + struct r535_gsp_msg *mqe; + const u32 max_rpc_size = GSP_MSG_MAX_SIZE - sizeof(*mqe); + struct nvfw_gsp_rpc *rpc; + struct r535_gsp_msg_info info = {0}; + u32 expected = gsp_rpc_len; + void *buf; + + mqe = r535_gsp_msgq_get_entry(gsp); + rpc = (struct nvfw_gsp_rpc *)mqe->data; + + if (WARN_ON(rpc->length > max_rpc_size)) + return NULL; + + buf = kvmalloc(max_t(u32, rpc->length, expected), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + info.gsp_rpc_buf = buf; + info.retries = retries; + info.gsp_rpc_len = rpc->length; + + buf = r535_gsp_msgq_recv_one_elem(gsp, &info); + if (IS_ERR(buf)) { + kvfree(info.gsp_rpc_buf); + info.gsp_rpc_buf = NULL; + return buf; + } + + if (expected <= max_rpc_size) + return buf; + + info.gsp_rpc_buf += info.gsp_rpc_len; + expected -= info.gsp_rpc_len; + + while (expected) { + u32 size; + + rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), info.retries); + if (IS_ERR_OR_NULL(rpc)) { + kfree(buf); + return rpc; + } + + info.gsp_rpc_len = rpc->length; + info.continuation = true; + + rpc = r535_gsp_msgq_recv_one_elem(gsp, &info); + if (IS_ERR_OR_NULL(rpc)) { + kfree(buf); + return rpc; + } + + size = info.gsp_rpc_len - sizeof(*rpc); + expected -= size; + info.gsp_rpc_buf += size; + } + + rpc = buf; + rpc->length = gsp_rpc_len; + return buf; +} + +static int +r535_gsp_cmdq_push(struct nvkm_gsp *gsp, void *rpc) +{ + struct r535_gsp_msg *msg = to_gsp_hdr(rpc, msg); + struct r535_gsp_msg *cqe; + u32 gsp_rpc_len = msg->checksum; + u64 *ptr = (void *)msg; + u64 *end; + u64 csum = 0; + int free, time = 1000000; + u32 wptr, size, step, len; + u32 off = 0; + + len = ALIGN(GSP_MSG_HDR_SIZE + gsp_rpc_len, GSP_PAGE_SIZE); + + end = (u64 *)((char *)ptr + len); + msg->pad = 0; + msg->checksum = 0; + msg->sequence = gsp->cmdq.seq++; + msg->elem_count = DIV_ROUND_UP(len, 0x1000); + + while (ptr < end) + csum ^= *ptr++; + + msg->checksum = upper_32_bits(csum) ^ lower_32_bits(csum); + + wptr = *gsp->cmdq.wptr; + do { + do { + free = *gsp->cmdq.rptr + gsp->cmdq.cnt - wptr - 1; + if (free >= gsp->cmdq.cnt) + free -= gsp->cmdq.cnt; + if (free >= 1) + break; + + usleep_range(1, 2); + } while(--time); + + if (WARN_ON(!time)) { + kvfree(msg); + return -ETIMEDOUT; + } + + cqe = (void *)((u8 *)gsp->shm.cmdq.ptr + 0x1000 + wptr * 0x1000); + step = min_t(u32, free, (gsp->cmdq.cnt - wptr)); + size = min_t(u32, len, step * GSP_PAGE_SIZE); + + memcpy(cqe, (u8 *)msg + off, size); + + wptr += DIV_ROUND_UP(size, 0x1000); + if (wptr == gsp->cmdq.cnt) + wptr = 0; + + off += size; + len -= size; + } while (len); + + nvkm_trace(&gsp->subdev, "cmdq: wptr %d\n", wptr); + wmb(); + (*gsp->cmdq.wptr) = wptr; + mb(); + + nvkm_falcon_wr32(&gsp->falcon, 0xc00, 0x00000000); + + kvfree(msg); + return 0; +} + +static void * +r535_gsp_cmdq_get(struct nvkm_gsp *gsp, u32 gsp_rpc_len) +{ + struct r535_gsp_msg *msg; + u32 size = GSP_MSG_HDR_SIZE + gsp_rpc_len; + + size = ALIGN(size, GSP_MSG_MIN_SIZE); + msg = kvzalloc(size, GFP_KERNEL); + if (!msg) + return ERR_PTR(-ENOMEM); + + msg->checksum = gsp_rpc_len; + return msg->data; +} + +static void +r535_gsp_msg_done(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg) +{ + kvfree(msg); +} + +static void +r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl) +{ + if (gsp->subdev.debug >= lvl) { + nvkm_printk__(&gsp->subdev, lvl, info, + "msg fn:%d len:0x%x/0x%zx res:0x%x resp:0x%x\n", + msg->function, msg->length, msg->length - sizeof(*msg), + msg->rpc_result, msg->rpc_result_private); + print_hex_dump(KERN_INFO, "msg: ", DUMP_PREFIX_OFFSET, 16, 1, + msg->data, msg->length - sizeof(*msg), true); + } +} + +struct nvfw_gsp_rpc * +r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + struct nvfw_gsp_rpc *rpc; + int retries = 4000000, i; + +retry: + rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), &retries); + if (IS_ERR_OR_NULL(rpc)) + return rpc; + + rpc = r535_gsp_msgq_recv(gsp, gsp_rpc_len, &retries); + if (IS_ERR_OR_NULL(rpc)) + return rpc; + + if (rpc->rpc_result) { + r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); + r535_gsp_msg_done(gsp, rpc); + return ERR_PTR(-EINVAL); + } + + r535_gsp_msg_dump(gsp, rpc, NV_DBG_TRACE); + + if (fn && rpc->function == fn) { + if (gsp_rpc_len) { + if (rpc->length < gsp_rpc_len) { + nvkm_error(subdev, "rpc len %d < %d\n", + rpc->length, gsp_rpc_len); + r535_gsp_msg_dump(gsp, rpc, NV_DBG_ERROR); + r535_gsp_msg_done(gsp, rpc); + return ERR_PTR(-EIO); + } + + return rpc; + } + + r535_gsp_msg_done(gsp, rpc); + return NULL; + } + + for (i = 0; i < gsp->msgq.ntfy_nr; i++) { + struct nvkm_gsp_msgq_ntfy *ntfy = &gsp->msgq.ntfy[i]; + + if (ntfy->fn == rpc->function) { + if (ntfy->func) + ntfy->func(ntfy->priv, ntfy->fn, rpc->data, + rpc->length - sizeof(*rpc)); + break; + } + } + + if (i == gsp->msgq.ntfy_nr) + r535_gsp_msg_dump(gsp, rpc, NV_DBG_WARN); + + r535_gsp_msg_done(gsp, rpc); + if (fn) + goto retry; + + if (*gsp->msgq.rptr != *gsp->msgq.wptr) + goto retry; + + return NULL; +} + +int +r535_gsp_msg_ntfy_add(struct nvkm_gsp *gsp, u32 fn, nvkm_gsp_msg_ntfy_func func, void *priv) +{ + int ret = 0; + + mutex_lock(&gsp->msgq.mutex); + if (WARN_ON(gsp->msgq.ntfy_nr >= ARRAY_SIZE(gsp->msgq.ntfy))) { + ret = -ENOSPC; + } else { + gsp->msgq.ntfy[gsp->msgq.ntfy_nr].fn = fn; + gsp->msgq.ntfy[gsp->msgq.ntfy_nr].func = func; + gsp->msgq.ntfy[gsp->msgq.ntfy_nr].priv = priv; + gsp->msgq.ntfy_nr++; + } + mutex_unlock(&gsp->msgq.mutex); + return ret; +} + +int +r535_gsp_rpc_poll(struct nvkm_gsp *gsp, u32 fn) +{ + void *repv; + + mutex_lock(&gsp->cmdq.mutex); + repv = r535_gsp_msg_recv(gsp, fn, 0); + mutex_unlock(&gsp->cmdq.mutex); + if (IS_ERR(repv)) + return PTR_ERR(repv); + + return 0; +} + +static void * +r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn, + enum nvkm_gsp_rpc_reply_policy policy, + u32 gsp_rpc_len) +{ + struct nvfw_gsp_rpc *reply; + void *repv = NULL; + + switch (policy) { + case NVKM_GSP_RPC_REPLY_NOWAIT: + break; + case NVKM_GSP_RPC_REPLY_RECV: + reply = r535_gsp_msg_recv(gsp, fn, gsp_rpc_len); + if (!IS_ERR_OR_NULL(reply)) + repv = reply->data; + else + repv = reply; + break; + case NVKM_GSP_RPC_REPLY_POLL: + repv = r535_gsp_msg_recv(gsp, fn, 0); + break; + } + + return repv; +} + +static void * +r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload, + enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len) +{ + struct nvfw_gsp_rpc *rpc = to_gsp_hdr(payload, rpc); + u32 fn = rpc->function; + int ret; + + if (gsp->subdev.debug >= NV_DBG_TRACE) { + nvkm_trace(&gsp->subdev, "rpc fn:%d len:0x%x/0x%zx\n", rpc->function, + rpc->length, rpc->length - sizeof(*rpc)); + print_hex_dump(KERN_INFO, "rpc: ", DUMP_PREFIX_OFFSET, 16, 1, + rpc->data, rpc->length - sizeof(*rpc), true); + } + + ret = r535_gsp_cmdq_push(gsp, rpc); + if (ret) + return ERR_PTR(ret); + + return r535_gsp_rpc_handle_reply(gsp, fn, policy, gsp_rpc_len); +} + +static void +r535_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv) +{ + struct nvfw_gsp_rpc *rpc = container_of(repv, typeof(*rpc), data); + + r535_gsp_msg_done(gsp, rpc); +} + +static void * +r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size) +{ + struct nvfw_gsp_rpc *rpc; + + rpc = r535_gsp_cmdq_get(gsp, ALIGN(sizeof(*rpc) + payload_size, + sizeof(u64))); + if (IS_ERR(rpc)) + return ERR_CAST(rpc); + + rpc->header_version = 0x03000000; + rpc->signature = ('C' << 24) | ('P' << 16) | ('R' << 8) | 'V'; + rpc->function = fn; + rpc->rpc_result = 0xffffffff; + rpc->rpc_result_private = 0xffffffff; + rpc->length = sizeof(*rpc) + payload_size; + return rpc->data; +} + +static void * +r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload, + enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len) +{ + struct nvfw_gsp_rpc *rpc = to_gsp_hdr(payload, rpc); + struct r535_gsp_msg *msg = to_gsp_hdr(rpc, msg); + const u32 max_rpc_size = GSP_MSG_MAX_SIZE - sizeof(*msg); + const u32 max_payload_size = max_rpc_size - sizeof(*rpc); + u32 payload_size = rpc->length - sizeof(*rpc); + void *repv; + + mutex_lock(&gsp->cmdq.mutex); + if (payload_size > max_payload_size) { + const u32 fn = rpc->function; + u32 remain_payload_size = payload_size; + + /* Adjust length, and send initial RPC. */ + rpc->length = sizeof(*rpc) + max_payload_size; + msg->checksum = rpc->length; + + repv = r535_gsp_rpc_send(gsp, payload, NVKM_GSP_RPC_REPLY_NOWAIT, 0); + if (IS_ERR(repv)) + goto done; + + payload += max_payload_size; + remain_payload_size -= max_payload_size; + + /* Remaining chunks sent as CONTINUATION_RECORD RPCs. */ + while (remain_payload_size) { + u32 size = min(remain_payload_size, + max_payload_size); + void *next; + + next = r535_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_CONTINUATION_RECORD, size); + if (IS_ERR(next)) { + repv = next; + goto done; + } + + memcpy(next, payload, size); + + repv = r535_gsp_rpc_send(gsp, next, NVKM_GSP_RPC_REPLY_NOWAIT, 0); + if (IS_ERR(repv)) + goto done; + + payload += size; + remain_payload_size -= size; + } + + /* Wait for reply. */ + repv = r535_gsp_rpc_handle_reply(gsp, fn, policy, payload_size + + sizeof(*rpc)); + } else { + repv = r535_gsp_rpc_send(gsp, payload, policy, gsp_rpc_len); + } + +done: + mutex_unlock(&gsp->cmdq.mutex); + return repv; +} + +const struct nvkm_rm_api_rpc +r535_rpc = { + .get = r535_gsp_rpc_get, + .push = r535_gsp_rpc_push, + .done = r535_gsp_rpc_done, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c index d3e95453f25d..52f2e5f14517 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c @@ -19,15 +19,38 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#include "vmm.h" +#include <subdev/mmu/vmm.h> -#include <nvrm/nvtypes.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/class/cl90f1.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/ctrl/ctrl90f1.h> -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvos.h> +#include <nvhw/drf.h> +#include "nvrm/vmm.h" -static int -r535_mmu_promote_vmm(struct nvkm_vmm *vmm) +void +r535_mmu_vaspace_del(struct nvkm_vmm *vmm) +{ + if (vmm->rm.external) { + NV0080_CTRL_DMA_UNSET_PAGE_DIRECTORY_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_get(&vmm->rm.device.object, + NV0080_CTRL_CMD_DMA_UNSET_PAGE_DIRECTORY, + sizeof(*ctrl)); + if (!IS_ERR(ctrl)) { + ctrl->hVASpace = vmm->rm.object.handle; + + WARN_ON(nvkm_gsp_rm_ctrl_wr(&vmm->rm.device.object, ctrl)); + } + + vmm->rm.external = false; + } + + nvkm_gsp_rm_free(&vmm->rm.object); + nvkm_gsp_device_dtor(&vmm->rm.device); + nvkm_gsp_client_dtor(&vmm->rm.client); + + nvkm_vmm_put(vmm, &vmm->rm.rsvd); +} + +int +r535_mmu_vaspace_new(struct nvkm_vmm *vmm, u32 handle, bool external) { NV_VASPACE_ALLOCATION_PARAMETERS *args; int ret; @@ -37,58 +60,103 @@ r535_mmu_promote_vmm(struct nvkm_vmm *vmm) if (ret) return ret; - args = nvkm_gsp_rm_alloc_get(&vmm->rm.device.object, 0x90f10000, FERMI_VASPACE_A, + args = nvkm_gsp_rm_alloc_get(&vmm->rm.device.object, handle, FERMI_VASPACE_A, sizeof(*args), &vmm->rm.object); if (IS_ERR(args)) return PTR_ERR(args); args->index = NV_VASPACE_ALLOCATION_INDEX_GPU_NEW; + if (external) + args->flags = NV_VASPACE_ALLOCATION_FLAGS_IS_EXTERNALLY_OWNED; ret = nvkm_gsp_rm_alloc_wr(&vmm->rm.object, args); if (ret) return ret; - { + if (!external) { NV90F1_CTRL_VASPACE_COPY_SERVER_RESERVED_PDES_PARAMS *ctrl; + u8 page_shift = 29; /* 512MiB */ + const u64 page_size = BIT_ULL(page_shift); + const struct nvkm_vmm_page *page; + const struct nvkm_vmm_desc *desc; + struct nvkm_vmm_pt *pd = vmm->pd; + + for (page = vmm->func->page; page->shift; page++) { + if (page->shift == page_shift) + break; + } + + if (WARN_ON(!page->shift)) + return -EINVAL; mutex_lock(&vmm->mutex.vmm); - ret = nvkm_vmm_get_locked(vmm, true, false, false, 0x1d, 32, 0x20000000, + ret = nvkm_vmm_get_locked(vmm, true, false, false, page_shift, 32, page_size, &vmm->rm.rsvd); mutex_unlock(&vmm->mutex.vmm); if (ret) return ret; + /* Some parts of RM expect the server-reserved area to be in a specific location. */ + if (WARN_ON(vmm->rm.rsvd->addr != SPLIT_VAS_SERVER_RM_MANAGED_VA_START || + vmm->rm.rsvd->size != SPLIT_VAS_SERVER_RM_MANAGED_VA_SIZE)) + return -EINVAL; + ctrl = nvkm_gsp_rm_ctrl_get(&vmm->rm.object, NV90F1_CTRL_CMD_VASPACE_COPY_SERVER_RESERVED_PDES, sizeof(*ctrl)); if (IS_ERR(ctrl)) return PTR_ERR(ctrl); - ctrl->pageSize = 0x20000000; + ctrl->pageSize = page_size; ctrl->virtAddrLo = vmm->rm.rsvd->addr; ctrl->virtAddrHi = vmm->rm.rsvd->addr + vmm->rm.rsvd->size - 1; - ctrl->numLevelsToCopy = vmm->pd->pde[0]->pde[0] ? 3 : 2; - ctrl->levels[0].physAddress = vmm->pd->pt[0]->addr; - ctrl->levels[0].size = 0x20; - ctrl->levels[0].aperture = 1; - ctrl->levels[0].pageShift = 0x2f; - ctrl->levels[1].physAddress = vmm->pd->pde[0]->pt[0]->addr; - ctrl->levels[1].size = 0x1000; - ctrl->levels[1].aperture = 1; - ctrl->levels[1].pageShift = 0x26; - if (vmm->pd->pde[0]->pde[0]) { - ctrl->levels[2].physAddress = vmm->pd->pde[0]->pde[0]->pt[0]->addr; - ctrl->levels[2].size = 0x1000; - ctrl->levels[2].aperture = 1; - ctrl->levels[2].pageShift = 0x1d; + + for (desc = page->desc; desc->bits; desc++) { + ctrl->numLevelsToCopy++; + page_shift += desc->bits; + } + desc--; + + for (int i = 0; i < ctrl->numLevelsToCopy; i++, desc--) { + page_shift -= desc->bits; + + ctrl->levels[i].physAddress = pd->pt[0]->addr; + ctrl->levels[i].size = (1 << desc->bits) * desc->size; + ctrl->levels[i].aperture = 1; + ctrl->levels[i].pageShift = page_shift; + + pd = pd->pde[0]; } ret = nvkm_gsp_rm_ctrl_wr(&vmm->rm.object, ctrl); + } else { + NV0080_CTRL_DMA_SET_PAGE_DIRECTORY_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_get(&vmm->rm.device.object, + NV0080_CTRL_CMD_DMA_SET_PAGE_DIRECTORY, + sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->physAddress = vmm->pd->pt[0]->addr; + ctrl->numEntries = 1 << vmm->func->page[0].desc->bits; + ctrl->flags = NVDEF(NV0080_CTRL_DMA_SET_PAGE_DIRECTORY, FLAGS, APERTURE, VIDMEM); + ctrl->hVASpace = vmm->rm.object.handle; + + ret = nvkm_gsp_rm_ctrl_wr(&vmm->rm.device.object, ctrl); + if (ret == 0) + vmm->rm.external = true; } return ret; } +static int +r535_mmu_promote_vmm(struct nvkm_vmm *vmm) +{ + return r535_mmu_vaspace_new(vmm, NVKM_RM_VASPACE, true); +} + static void r535_mmu_dtor(struct nvkm_mmu *mmu) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/Kbuild new file mode 100644 index 000000000000..5db0e7009e1f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/Kbuild @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: MIT +nvkm-y += nvkm/subdev/gsp/rm/r570/rm.o +nvkm-y += nvkm/subdev/gsp/rm/r570/gsp.o +nvkm-y += nvkm/subdev/gsp/rm/r570/client.o +nvkm-y += nvkm/subdev/gsp/rm/r570/fbsr.o +nvkm-y += nvkm/subdev/gsp/rm/r570/disp.o +nvkm-y += nvkm/subdev/gsp/rm/r570/fifo.o +nvkm-y += nvkm/subdev/gsp/rm/r570/gr.o +nvkm-y += nvkm/subdev/gsp/rm/r570/ofa.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/client.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/client.c new file mode 100644 index 000000000000..87e6240662ed --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/client.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <rm/rm.h> + +#include "nvrm/client.h" + +static int +r570_gsp_client_ctor(struct nvkm_gsp_client *client, u32 handle) +{ + NV0000_ALLOC_PARAMETERS *args; + + args = nvkm_gsp_rm_alloc_get(&client->object, handle, NV01_ROOT, sizeof(*args), + &client->object); + if (IS_ERR(args)) + return PTR_ERR(args); + + args->hClient = client->object.handle; + args->processID = ~0; + + return nvkm_gsp_rm_alloc_wr(&client->object, args); +} + +const struct nvkm_rm_api_client +r570_client = { + .ctor = r570_gsp_client_ctor, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c new file mode 100644 index 000000000000..a96e31c2d80b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <rm/rm.h> + +#include <engine/disp.h> +#include <engine/disp/outp.h> + +#include "nvhw/drf.h" + +#include "nvrm/disp.h" + +static int +r570_dmac_alloc(struct nvkm_disp *disp, u32 oclass, int inst, u32 put_offset, + struct nvkm_gsp_object *dmac) +{ + NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS *args; + + args = nvkm_gsp_rm_alloc_get(&disp->rm.object, (oclass << 16) | inst, oclass, + sizeof(*args), dmac); + if (IS_ERR(args)) + return PTR_ERR(args); + + args->channelInstance = inst; + args->offset = put_offset; + args->subDeviceId = BIT(0); + + return nvkm_gsp_rm_alloc_wr(dmac, args); +} + +static int +r570_disp_chan_set_pushbuf(struct nvkm_disp *disp, s32 oclass, int inst, struct nvkm_memory *memory) +{ + struct nvkm_gsp *gsp = disp->rm.objcom.client->gsp; + NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER, + sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + if (memory) { + switch (nvkm_memory_target(memory)) { + case NVKM_MEM_TARGET_NCOH: + ctrl->addressSpace = ADDR_SYSMEM; + ctrl->cacheSnoop = 0; + ctrl->pbTargetAperture = PHYS_PCI; + break; + case NVKM_MEM_TARGET_HOST: + ctrl->addressSpace = ADDR_SYSMEM; + ctrl->cacheSnoop = 1; + ctrl->pbTargetAperture = PHYS_PCI_COHERENT; + break; + case NVKM_MEM_TARGET_VRAM: + ctrl->addressSpace = ADDR_FBMEM; + ctrl->pbTargetAperture = PHYS_NVM; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + ctrl->physicalAddr = nvkm_memory_addr(memory); + ctrl->limit = nvkm_memory_size(memory) - 1; + } + + ctrl->hclass = oclass; + ctrl->channelInstance = inst; + ctrl->valid = ((oclass & 0xff) != 0x7a) ? 1 : 0; + ctrl->subDeviceId = BIT(0); + + return nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl); +} + +static int +r570_dp_set_indexed_link_rates(struct nvkm_outp *outp) +{ + NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS *ctrl; + struct nvkm_disp *disp = outp->disp; + + if (WARN_ON(outp->dp.rates > ARRAY_SIZE(ctrl->linkRateTbl))) + return -EINVAL; + + ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, + NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->displayId = BIT(outp->index); + for (int i = 0; i < outp->dp.rates; i++) + ctrl->linkRateTbl[outp->dp.rate[i].dpcd] = outp->dp.rate[i].rate * 10 / 200; + + return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl); +} + +static int +r570_dp_get_caps(struct nvkm_disp *disp, int *plink_bw, bool *pmst, bool *pwm) +{ + NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS *ctrl; + int ret; + + ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, + NV0073_CTRL_CMD_DP_GET_CAPS, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->sorIndex = ~0; + + ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); + if (ret) { + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return ret; + } + + switch (NVVAL_GET(ctrl->maxLinkRate, NV0073_CTRL_CMD, DP_GET_CAPS, MAX_LINK_RATE)) { + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62: + *plink_bw = 0x06; + break; + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70: + *plink_bw = 0x0a; + break; + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40: + *plink_bw = 0x14; + break; + case NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10: + *plink_bw = 0x1e; + break; + default: + *plink_bw = 0x00; + break; + } + + *pmst = ctrl->bIsMultistreamSupported; + *pwm = ctrl->bHasIncreasedWatermarkLimits; + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return 0; +} + +static int +r570_bl_ctrl(struct nvkm_disp *disp, unsigned display_id, bool set, int *pval) +{ + u32 cmd = set ? NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS : + NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS; + NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS *ctrl; + int ret; + + ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, cmd, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->displayId = BIT(display_id); + ctrl->brightness = *pval; + ctrl->brightnessType = NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_PERCENT100; + + ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); + if (ret) + return ret; + + *pval = ctrl->brightness; + + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return 0; +} + +static int +r570_disp_get_active(struct nvkm_disp *disp, unsigned head, u32 *displayid) +{ + NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS *ctrl; + int ret; + + ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, + NV0073_CTRL_CMD_SYSTEM_GET_ACTIVE, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->subDeviceInstance = 0; + ctrl->head = head; + + ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); + if (ret) { + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return ret; + } + + *displayid = ctrl->displayId; + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return 0; +} +static int +r570_disp_get_connect_state(struct nvkm_disp *disp, unsigned display_id) +{ + NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS *ctrl; + int ret; + + ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, + NV0073_CTRL_CMD_SYSTEM_GET_CONNECT_STATE, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->subDeviceInstance = 0; + ctrl->displayMask = BIT(display_id); + + ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); + if (ret == 0 && (ctrl->displayMask & BIT(display_id))) + ret = 1; + + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return ret; +} + +static int +r570_disp_get_supported(struct nvkm_disp *disp, unsigned long *pmask) +{ + NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom, + NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + *pmask = ctrl->displayMask; + + nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); + return 0; +} + +static int +r570_disp_get_static_info(struct nvkm_disp *disp) +{ + NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS *ctrl; + struct nvkm_gsp *gsp = disp->engine.subdev.device->gsp; + + ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO, + sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + disp->wndw.mask = ctrl->windowPresentMask; + disp->wndw.nr = fls(disp->wndw.mask); + + nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); + return 0; +} + +const struct nvkm_rm_api_disp +r570_disp = { + .get_static_info = r570_disp_get_static_info, + .get_supported = r570_disp_get_supported, + .get_connect_state = r570_disp_get_connect_state, + .get_active = r570_disp_get_active, + .bl_ctrl = r570_bl_ctrl, + .dp = { + .get_caps = r570_dp_get_caps, + .set_indexed_link_rates = r570_dp_set_indexed_link_rates, + }, + .chan = { + .set_pushbuf = r570_disp_chan_set_pushbuf, + .dmac_alloc = r570_dmac_alloc, + }, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fbsr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fbsr.c new file mode 100644 index 000000000000..2945d5b4e570 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fbsr.c @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <subdev/instmem/priv.h> +#include <subdev/bar.h> +#include <subdev/gsp.h> +#include <subdev/mmu/vmm.h> + +#include "nvrm/fbsr.h" +#include "nvrm/fifo.h" + +static int +r570_fbsr_suspend_channels(struct nvkm_gsp *gsp, bool suspend) +{ + NV2080_CTRL_CMD_INTERNAL_FIFO_TOGGLE_ACTIVE_CHANNEL_SCHEDULING_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_INTERNAL_FIFO_TOGGLE_ACTIVE_CHANNEL_SCHEDULING, + sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->bDisableActiveChannels = suspend; + + return nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl); +} + +static void +r570_fbsr_resume(struct nvkm_gsp *gsp) +{ + struct nvkm_device *device = gsp->subdev.device; + struct nvkm_instmem *imem = device->imem; + struct nvkm_instobj *iobj; + struct nvkm_vmm *vmm; + + /* Restore BAR2 page tables via BAR0 window, and re-enable BAR2. */ + list_for_each_entry(iobj, &imem->boot, head) { + if (iobj->suspend) + nvkm_instobj_load(iobj); + } + + device->bar->bar2 = true; + + vmm = nvkm_bar_bar2_vmm(device); + vmm->func->flush(vmm, 0); + + /* Restore remaining BAR2 allocations (including BAR1 page tables) via BAR2. */ + list_for_each_entry(iobj, &imem->list, head) { + if (iobj->suspend) + nvkm_instobj_load(iobj); + } + + vmm = nvkm_bar_bar1_vmm(device); + vmm->func->flush(vmm, 0); + + /* Resume channel scheduling. */ + r570_fbsr_suspend_channels(device->gsp, false); + + /* Finish cleaning up. */ + r535_fbsr_resume(gsp); +} + +static int +r570_fbsr_init(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size) +{ + NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS *ctrl; + struct nvkm_gsp_object memlist; + int ret; + + ret = r535_fbsr_memlist(&gsp->internal.device, 0xcaf00003, NVKM_MEM_TARGET_HOST, + 0, size, sgt, &memlist); + if (ret) + return ret; + + ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_INTERNAL_FBSR_INIT, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->hClient = gsp->internal.client.object.handle; + ctrl->hSysMem = memlist.handle; + ctrl->sysmemAddrOfSuspendResumeData = gsp->sr.meta.addr; + ctrl->bEnteringGcoffState = 1; + + ret = nvkm_gsp_rm_ctrl_wr(&gsp->internal.device.subdevice, ctrl); + if (ret) + return ret; + + nvkm_gsp_rm_free(&memlist); + return 0; +} + +static int +r570_fbsr_suspend(struct nvkm_gsp *gsp) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + struct nvkm_device *device = subdev->device; + struct nvkm_instmem *imem = device->imem; + struct nvkm_instobj *iobj; + u64 size; + int ret; + + /* Stop channel scheduling. */ + r570_fbsr_suspend_channels(gsp, true); + + /* Save BAR2 allocations to system memory. */ + list_for_each_entry(iobj, &imem->list, head) { + if (iobj->preserve) { + ret = nvkm_instobj_save(iobj); + if (ret) + return ret; + } + } + + list_for_each_entry(iobj, &imem->boot, head) { + ret = nvkm_instobj_save(iobj); + if (ret) + return ret; + } + + /* Disable BAR2 access. */ + device->bar->bar2 = false; + + /* Allocate system memory to hold RM's VRAM allocations across suspend. */ + size = gsp->fb.heap.size; + size += gsp->fb.rsvd_size; + size += gsp->fb.bios.vga_workspace.size; + nvkm_debug(subdev, "fbsr: size: 0x%llx bytes\n", size); + + ret = nvkm_gsp_sg(device, size, &gsp->sr.fbsr); + if (ret) + return ret; + + /* Initialise FBSR on RM. */ + ret = r570_fbsr_init(gsp, &gsp->sr.fbsr, size); + if (ret) { + nvkm_gsp_sg_free(device, &gsp->sr.fbsr); + return ret; + } + + return 0; +} + +const struct nvkm_rm_api_fbsr +r570_fbsr = { + .suspend = r570_fbsr_suspend, + .resume = r570_fbsr_resume, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fifo.c new file mode 100644 index 000000000000..79132805cfcf --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fifo.c @@ -0,0 +1,217 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <rm/rm.h> + +#include <subdev/mmu.h> +#include <engine/fifo/priv.h> +#include <engine/fifo/chan.h> +#include <engine/fifo/runl.h> + +#include "nvhw/drf.h" + +#include "nvrm/fifo.h" +#include "nvrm/engine.h" + +#define CHID_PER_USERD 8 + +static int +r570_chan_alloc(struct nvkm_gsp_device *device, u32 handle, u32 nv2080_engine_type, u8 runq, + bool priv, int chid, u64 inst_addr, u64 userd_addr, u64 mthdbuf_addr, + struct nvkm_vmm *vmm, u64 gpfifo_offset, u32 gpfifo_length, + struct nvkm_gsp_object *chan) +{ + struct nvkm_gsp *gsp = device->object.client->gsp; + struct nvkm_fifo *fifo = gsp->subdev.device->fifo; + const int userd_p = chid / CHID_PER_USERD; + const int userd_i = chid % CHID_PER_USERD; + NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS *args; + + args = nvkm_gsp_rm_alloc_get(&device->object, handle, + fifo->func->chan.user.oclass, sizeof(*args), chan); + if (WARN_ON(IS_ERR(args))) + return PTR_ERR(args); + + args->gpFifoOffset = gpfifo_offset; + args->gpFifoEntries = gpfifo_length / 8; + + args->flags = NVDEF(NVOS04, FLAGS, CHANNEL_TYPE, PHYSICAL); + args->flags |= NVDEF(NVOS04, FLAGS, VPR, FALSE); + args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_SKIP_MAP_REFCOUNTING, FALSE); + args->flags |= NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, runq); + if (!priv) + args->flags |= NVDEF(NVOS04, FLAGS, PRIVILEGED_CHANNEL, FALSE); + else + args->flags |= NVDEF(NVOS04, FLAGS, PRIVILEGED_CHANNEL, TRUE); + args->flags |= NVDEF(NVOS04, FLAGS, DELAY_CHANNEL_SCHEDULING, FALSE); + args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_DENY_PHYSICAL_MODE_CE, FALSE); + + args->flags |= NVVAL(NVOS04, FLAGS, CHANNEL_USERD_INDEX_VALUE, userd_i); + args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_USERD_INDEX_FIXED, FALSE); + args->flags |= NVVAL(NVOS04, FLAGS, CHANNEL_USERD_INDEX_PAGE_VALUE, userd_p); + args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_USERD_INDEX_PAGE_FIXED, TRUE); + + args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_DENY_AUTH_LEVEL_PRIV, FALSE); + args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_SKIP_SCRUBBER, FALSE); + args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_CLIENT_MAP_FIFO, FALSE); + args->flags |= NVDEF(NVOS04, FLAGS, SET_EVICT_LAST_CE_PREFETCH_CHANNEL, FALSE); + args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_VGPU_PLUGIN_CONTEXT, FALSE); + args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_PBDMA_ACQUIRE_TIMEOUT, FALSE); + args->flags |= NVDEF(NVOS04, FLAGS, GROUP_CHANNEL_THREAD, DEFAULT); + args->flags |= NVDEF(NVOS04, FLAGS, MAP_CHANNEL, FALSE); + args->flags |= NVDEF(NVOS04, FLAGS, SKIP_CTXBUFFER_ALLOC, FALSE); + + args->hVASpace = vmm->rm.object.handle; + args->engineType = nv2080_engine_type; + + args->instanceMem.base = inst_addr; + args->instanceMem.size = fifo->func->chan.func->inst->size; + args->instanceMem.addressSpace = 2; + args->instanceMem.cacheAttrib = 1; + + args->userdMem.base = userd_addr; + args->userdMem.size = fifo->func->chan.func->userd->size; + args->userdMem.addressSpace = 2; + args->userdMem.cacheAttrib = 1; + + args->ramfcMem.base = inst_addr; + args->ramfcMem.size = 0x200; + args->ramfcMem.addressSpace = 2; + args->ramfcMem.cacheAttrib = 1; + + args->mthdbufMem.base = mthdbuf_addr; + args->mthdbufMem.size = fifo->rm.mthdbuf_size; + args->mthdbufMem.addressSpace = 1; + args->mthdbufMem.cacheAttrib = 0; + + if (!priv) + args->internalFlags = NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, PRIVILEGE, USER); + else + args->internalFlags = NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, PRIVILEGE, ADMIN); + args->internalFlags |= NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, ERROR_NOTIFIER_TYPE, NONE); + args->internalFlags |= NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, ECC_ERROR_NOTIFIER_TYPE, NONE); + + return nvkm_gsp_rm_alloc_wr(chan, args); +} + +static int +r570_fifo_rc_triggered(void *priv, u32 fn, void *repv, u32 repc) +{ + rpc_rc_triggered_v17_02 *msg = repv; + struct nvkm_gsp *gsp = priv; + + if (WARN_ON(repc < sizeof(*msg))) + return -EINVAL; + + nvkm_error(&gsp->subdev, "rc engn:%08x chid:%d gfid:%d level:%d type:%d scope:%d part:%d " + "fault_addr:%08x%08x fault_type:%08x\n", + msg->nv2080EngineType, msg->chid, msg->gfid, msg->exceptLevel, msg->exceptType, + msg->scope, msg->partitionAttributionId, + msg->mmuFaultAddrHi, msg->mmuFaultAddrLo, msg->mmuFaultType); + + r535_fifo_rc_chid(gsp->subdev.device->fifo, msg->chid); + return 0; +} + +static int +r570_fifo_ectx_size(struct nvkm_fifo *fifo) +{ + NV2080_CTRL_GPU_GET_CONSTRUCTED_FALCON_INFO_PARAMS *ctrl; + struct nvkm_gsp *gsp = fifo->engine.subdev.device->gsp; + struct nvkm_runl *runl; + struct nvkm_engn *engn; + + ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_GPU_GET_CONSTRUCTED_FALCON_INFO, + sizeof(*ctrl)); + if (WARN_ON(IS_ERR(ctrl))) + return PTR_ERR(ctrl); + + for (int i = 0; i < ctrl->numConstructedFalcons; i++) { + nvkm_runl_foreach(runl, fifo) { + nvkm_runl_foreach_engn(engn, runl) { + if (engn->rm.desc == ctrl->constructedFalconsTable[i].engDesc) { + engn->rm.size = + ctrl->constructedFalconsTable[i].ctxBufferSize; + break; + } + } + } + } + + nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); + return 0; +} + +static int +r570_fifo_xlat_rm_engine_type(u32 rm, enum nvkm_subdev_type *ptype, int *p2080) +{ +#define RM_ENGINE_TYPE(RM,NVKM,INST) \ + RM_ENGINE_TYPE_##RM: \ + *ptype = NVKM_ENGINE_##NVKM; \ + *p2080 = NV2080_ENGINE_TYPE_##RM; \ + return INST + + switch (rm) { + case RM_ENGINE_TYPE( GR0, GR, 0); + case RM_ENGINE_TYPE( COPY0, CE, 0); + case RM_ENGINE_TYPE( COPY1, CE, 1); + case RM_ENGINE_TYPE( COPY2, CE, 2); + case RM_ENGINE_TYPE( COPY3, CE, 3); + case RM_ENGINE_TYPE( COPY4, CE, 4); + case RM_ENGINE_TYPE( COPY5, CE, 5); + case RM_ENGINE_TYPE( COPY6, CE, 6); + case RM_ENGINE_TYPE( COPY7, CE, 7); + case RM_ENGINE_TYPE( COPY8, CE, 8); + case RM_ENGINE_TYPE( COPY9, CE, 9); + case RM_ENGINE_TYPE( COPY10, CE, 10); + case RM_ENGINE_TYPE( COPY11, CE, 11); + case RM_ENGINE_TYPE( COPY12, CE, 12); + case RM_ENGINE_TYPE( COPY13, CE, 13); + case RM_ENGINE_TYPE( COPY14, CE, 14); + case RM_ENGINE_TYPE( COPY15, CE, 15); + case RM_ENGINE_TYPE( COPY16, CE, 16); + case RM_ENGINE_TYPE( COPY17, CE, 17); + case RM_ENGINE_TYPE( COPY18, CE, 18); + case RM_ENGINE_TYPE( COPY19, CE, 19); + case RM_ENGINE_TYPE( NVDEC0, NVDEC, 0); + case RM_ENGINE_TYPE( NVDEC1, NVDEC, 1); + case RM_ENGINE_TYPE( NVDEC2, NVDEC, 2); + case RM_ENGINE_TYPE( NVDEC3, NVDEC, 3); + case RM_ENGINE_TYPE( NVDEC4, NVDEC, 4); + case RM_ENGINE_TYPE( NVDEC5, NVDEC, 5); + case RM_ENGINE_TYPE( NVDEC6, NVDEC, 6); + case RM_ENGINE_TYPE( NVDEC7, NVDEC, 7); + case RM_ENGINE_TYPE( NVENC0, NVENC, 0); + case RM_ENGINE_TYPE( NVENC1, NVENC, 1); + case RM_ENGINE_TYPE( NVENC2, NVENC, 2); + case RM_ENGINE_TYPE( NVENC3, NVENC, 3); + case RM_ENGINE_TYPE(NVJPEG0, NVJPG, 0); + case RM_ENGINE_TYPE(NVJPEG1, NVJPG, 1); + case RM_ENGINE_TYPE(NVJPEG2, NVJPG, 2); + case RM_ENGINE_TYPE(NVJPEG3, NVJPG, 3); + case RM_ENGINE_TYPE(NVJPEG4, NVJPG, 4); + case RM_ENGINE_TYPE(NVJPEG5, NVJPG, 5); + case RM_ENGINE_TYPE(NVJPEG6, NVJPG, 6); + case RM_ENGINE_TYPE(NVJPEG7, NVJPG, 7); + case RM_ENGINE_TYPE( SW, SW, 0); + case RM_ENGINE_TYPE( SEC2, SEC2, 0); + case RM_ENGINE_TYPE( OFA0, OFA, 0); + case RM_ENGINE_TYPE( OFA1, OFA, 1); + default: + return -EINVAL; + } +#undef RM_ENGINE_TYPE +} + +const struct nvkm_rm_api_fifo +r570_fifo = { + .xlat_rm_engine_type = r570_fifo_xlat_rm_engine_type, + .ectx_size = r570_fifo_ectx_size, + .rsvd_chids = 1, + .rc_triggered = r570_fifo_rc_triggered, + .chan = { + .alloc = r570_chan_alloc, + }, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c new file mode 100644 index 000000000000..b6cced9b8aa1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <rm/gr.h> + +#include <subdev/mmu.h> +#include <engine/fifo.h> +#include <engine/fifo/chid.h> +#include <engine/gr/priv.h> + +#include "nvrm/gr.h" +#include "nvrm/engine.h" + +int +r570_gr_tpc_mask(struct nvkm_gsp *gsp, int gpc, u32 *pmask) +{ + NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS *ctrl; + int ret; + + ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_GPU_GET_FERMI_TPC_INFO, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->gpcId = gpc; + + ret = nvkm_gsp_rm_ctrl_push(&gsp->internal.device.subdevice, &ctrl, sizeof(*ctrl)); + if (ret) + return ret; + + *pmask = ctrl->tpcMask; + + nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); + return 0; +} + +int +r570_gr_gpc_mask(struct nvkm_gsp *gsp, u32 *pmask) +{ + NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_GPU_GET_FERMI_GPC_INFO, sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + *pmask = ctrl->gpcMask; + + nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); + return 0; +} + +static int +r570_gr_scrubber_ctrl(struct r535_gr *gr, bool teardown) +{ + NV2080_CTRL_INTERNAL_GR_INIT_BUG4208224_WAR_PARAMS *ctrl; + + ctrl = nvkm_gsp_rm_ctrl_get(&gr->scrubber.vmm->rm.device.subdevice, + NV2080_CTRL_CMD_INTERNAL_KGR_INIT_BUG4208224_WAR, + sizeof(*ctrl)); + if (IS_ERR(ctrl)) + return PTR_ERR(ctrl); + + ctrl->bTeardown = teardown; + + return nvkm_gsp_rm_ctrl_wr(&gr->scrubber.vmm->rm.device.subdevice, ctrl); +} + +static void +r570_gr_scrubber_fini(struct r535_gr *gr) +{ + /* Teardown scrubber channel on RM. */ + if (gr->scrubber.enabled) { + WARN_ON(r570_gr_scrubber_ctrl(gr, true)); + gr->scrubber.enabled = false; + } + + /* Free scrubber channel. */ + nvkm_gsp_rm_free(&gr->scrubber.threed); + nvkm_gsp_rm_free(&gr->scrubber.chan); + + for (int i = 0; i < gr->ctxbuf_nr; i++) { + nvkm_vmm_put(gr->scrubber.vmm, &gr->scrubber.ctxbuf.vma[i]); + nvkm_memory_unref(&gr->scrubber.ctxbuf.mem[i]); + } + + nvkm_vmm_unref(&gr->scrubber.vmm); + nvkm_memory_unref(&gr->scrubber.inst); +} + +static int +r570_gr_scrubber_init(struct r535_gr *gr) +{ + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + struct nvkm_device *device = subdev->device; + struct nvkm_gsp *gsp = device->gsp; + struct nvkm_rm *rm = gsp->rm; + int ret; + + /* Scrubber channel only required on TU10x. */ + switch (device->chipset) { + case 0x162: + case 0x164: + case 0x166: + break; + default: + return 0; + } + + if (gr->scrubber.chid < 0) { + gr->scrubber.chid = nvkm_chid_get(device->fifo->chid, NULL); + if (gr->scrubber.chid < 0) + return gr->scrubber.chid; + } + + /* Allocate scrubber channel. */ + ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, + 0x2000 + device->fifo->rm.mthdbuf_size, 0, true, + &gr->scrubber.inst); + if (ret) + goto done; + + ret = nvkm_vmm_new(device, 0x1000, 0, NULL, 0, NULL, "grScrubberVmm", + &gr->scrubber.vmm); + if (ret) + goto done; + + ret = r535_mmu_vaspace_new(gr->scrubber.vmm, KGRAPHICS_SCRUBBER_HANDLE_VAS, false); + if (ret) + goto done; + + ret = rm->api->fifo->chan.alloc(&gr->scrubber.vmm->rm.device, KGRAPHICS_SCRUBBER_HANDLE_CHANNEL, + NV2080_ENGINE_TYPE_GR0, 0, false, gr->scrubber.chid, + nvkm_memory_addr(gr->scrubber.inst), + nvkm_memory_addr(gr->scrubber.inst) + 0x1000, + nvkm_memory_addr(gr->scrubber.inst) + 0x2000, + gr->scrubber.vmm, 0, 0x1000, &gr->scrubber.chan); + if (ret) + goto done; + + ret = r535_gr_promote_ctx(gr, false, gr->scrubber.vmm, gr->scrubber.ctxbuf.mem, + gr->scrubber.ctxbuf.vma, &gr->scrubber.chan); + if (ret) + goto done; + + ret = nvkm_gsp_rm_alloc(&gr->scrubber.chan, KGRAPHICS_SCRUBBER_HANDLE_3DOBJ, + rm->gpu->gr.class.threed, 0, &gr->scrubber.threed); + if (ret) + goto done; + + /* Initialise scrubber channel on RM. */ + ret = r570_gr_scrubber_ctrl(gr, false); + if (ret) + goto done; + + gr->scrubber.enabled = true; + +done: + if (ret) + r570_gr_scrubber_fini(gr); + + return ret; +} + +static int +r570_gr_get_ctxbufs_info(struct r535_gr *gr) +{ + NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS *info; + struct nvkm_subdev *subdev = &gr->base.engine.subdev; + struct nvkm_gsp *gsp = subdev->device->gsp; + + info = nvkm_gsp_rm_ctrl_rd(&gsp->internal.device.subdevice, + NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO, + sizeof(*info)); + if (WARN_ON(IS_ERR(info))) + return PTR_ERR(info); + + for (int i = 0; i < ARRAY_SIZE(info->engineContextBuffersInfo[0].engine); i++) + r535_gr_get_ctxbuf_info(gr, i, &info->engineContextBuffersInfo[0].engine[i]); + + nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, info); + return 0; +} + +const struct nvkm_rm_api_gr +r570_gr = { + .get_ctxbufs_info = r570_gr_get_ctxbufs_info, + .scrubber.init = r570_gr_scrubber_init, + .scrubber.fini = r570_gr_scrubber_fini, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c new file mode 100644 index 000000000000..9d2fa4e66d59 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <rm/rm.h> +#include <rm/rpc.h> + +#include <asm-generic/video.h> + +#include "nvrm/gsp.h" +#include "nvrm/rpcfn.h" +#include "nvrm/msgfn.h" + +#include <core/pci.h> +#include <subdev/pci/priv.h> + +static u32 +r570_gsp_sr_data_size(struct nvkm_gsp *gsp) +{ + GspFwWprMeta *meta = gsp->wpr_meta.data; + + return (meta->frtsOffset + meta->frtsSize) - + (meta->nonWprHeapOffset + meta->nonWprHeapSize); +} + +static void +r570_gsp_drop_post_nocat_record(struct nvkm_gsp *gsp) +{ + if (gsp->subdev.debug < NV_DBG_DEBUG) { + r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_POST_NOCAT_RECORD, NULL, NULL); + r535_gsp_msg_ntfy_add(gsp, NV_VGPU_MSG_EVENT_GSP_LOCKDOWN_NOTICE, NULL, NULL); + } +} + +static bool +r570_gsp_xlat_mc_engine_idx(u32 mc_engine_idx, enum nvkm_subdev_type *ptype, int *pinst) +{ + switch (mc_engine_idx) { + case MC_ENGINE_IDX_GSP: + *ptype = NVKM_SUBDEV_GSP; + *pinst = 0; + return true; + case MC_ENGINE_IDX_DISP: + *ptype = NVKM_ENGINE_DISP; + *pinst = 0; + return true; + case MC_ENGINE_IDX_CE0 ... MC_ENGINE_IDX_CE19: + *ptype = NVKM_ENGINE_CE; + *pinst = mc_engine_idx - MC_ENGINE_IDX_CE0; + return true; + case MC_ENGINE_IDX_GR0: + *ptype = NVKM_ENGINE_GR; + *pinst = 0; + return true; + case MC_ENGINE_IDX_NVDEC0 ... MC_ENGINE_IDX_NVDEC7: + *ptype = NVKM_ENGINE_NVDEC; + *pinst = mc_engine_idx - MC_ENGINE_IDX_NVDEC0; + return true; + case MC_ENGINE_IDX_NVENC ... MC_ENGINE_IDX_NVENC3: + *ptype = NVKM_ENGINE_NVENC; + *pinst = mc_engine_idx - MC_ENGINE_IDX_NVENC; + return true; + case MC_ENGINE_IDX_NVJPEG0 ... MC_ENGINE_IDX_NVJPEG7: + *ptype = NVKM_ENGINE_NVJPG; + *pinst = mc_engine_idx - MC_ENGINE_IDX_NVJPEG0; + return true; + case MC_ENGINE_IDX_OFA0 ... MC_ENGINE_IDX_OFA1: + *ptype = NVKM_ENGINE_OFA; + *pinst = mc_engine_idx - MC_ENGINE_IDX_OFA0; + return true; + default: + return false; + } +} + +static int +r570_gsp_get_static_info(struct nvkm_gsp *gsp) +{ + GspStaticConfigInfo *rpc; + u32 gpc_mask; + u32 tpc_mask; + int ret; + + rpc = nvkm_gsp_rpc_rd(gsp, NV_VGPU_MSG_FUNCTION_GET_GSP_STATIC_INFO, sizeof(*rpc)); + if (IS_ERR(rpc)) + return PTR_ERR(rpc); + + gsp->internal.client.object.client = &gsp->internal.client; + gsp->internal.client.object.parent = NULL; + gsp->internal.client.object.handle = rpc->hInternalClient; + gsp->internal.client.gsp = gsp; + INIT_LIST_HEAD(&gsp->internal.client.events); + + gsp->internal.device.object.client = &gsp->internal.client; + gsp->internal.device.object.parent = &gsp->internal.client.object; + gsp->internal.device.object.handle = rpc->hInternalDevice; + + gsp->internal.device.subdevice.client = &gsp->internal.client; + gsp->internal.device.subdevice.parent = &gsp->internal.device.object; + gsp->internal.device.subdevice.handle = rpc->hInternalSubdevice; + + gsp->bar.rm_bar1_pdb = rpc->bar1PdeBase; + gsp->bar.rm_bar2_pdb = rpc->bar2PdeBase; + + r535_gsp_get_static_info_fb(gsp, &rpc->fbRegionInfoParams); + + if (gsp->rm->wpr->offset_set_by_acr) { + GspFwWprMeta *meta = gsp->wpr_meta.data; + + meta->nonWprHeapOffset = rpc->fwWprLayoutOffset.nonWprHeapOffset; + meta->frtsOffset = rpc->fwWprLayoutOffset.frtsOffset; + } + + nvkm_gsp_rpc_done(gsp, rpc); + + ret = r570_gr_gpc_mask(gsp, &gpc_mask); + if (ret) + return ret; + + for (int gpc = 0; gpc < 32; gpc++) { + if (gpc_mask & BIT(gpc)) { + ret = r570_gr_tpc_mask(gsp, gpc, &tpc_mask); + if (ret) + return ret; + + gsp->gr.tpcs += hweight32(tpc_mask); + gsp->gr.gpcs++; + } + } + + return 0; +} + +static void +r570_gsp_acpi_info(struct nvkm_gsp *gsp, ACPI_METHOD_DATA *acpi) +{ +#if defined(CONFIG_ACPI) && defined(CONFIG_X86) + acpi_handle handle = ACPI_HANDLE(gsp->subdev.device->dev); + + if (!handle) + return; + + acpi->bValid = 1; + + r535_gsp_acpi_dod(handle, &acpi->dodMethodData); + r535_gsp_acpi_jt(handle, &acpi->jtMethodData); + r535_gsp_acpi_caps(handle, &acpi->capsMethodData); +#endif +} + +static int +r570_gsp_set_system_info(struct nvkm_gsp *gsp) +{ + struct nvkm_device *device = gsp->subdev.device; + struct pci_dev *pdev = container_of(device, struct nvkm_device_pci, device)->pdev; + GspSystemInfo *info; + + if (WARN_ON(device->type == NVKM_DEVICE_TEGRA)) + return -ENOSYS; + + info = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_SET_SYSTEM_INFO, sizeof(*info)); + if (IS_ERR(info)) + return PTR_ERR(info); + + info->gpuPhysAddr = device->func->resource_addr(device, NVKM_BAR0_PRI); + info->gpuPhysFbAddr = device->func->resource_addr(device, NVKM_BAR1_FB); + info->gpuPhysInstAddr = device->func->resource_addr(device, NVKM_BAR2_INST); + info->nvDomainBusDeviceFunc = pci_dev_id(pdev); + info->maxUserVa = TASK_SIZE; + info->pciConfigMirrorBase = device->pci->func->cfg.addr; + info->pciConfigMirrorSize = device->pci->func->cfg.size; + info->PCIDeviceID = (pdev->device << 16) | pdev->vendor; + info->PCISubDeviceID = (pdev->subsystem_device << 16) | pdev->subsystem_vendor; + info->PCIRevisionID = pdev->revision; + r570_gsp_acpi_info(gsp, &info->acpiMethodData); + info->bIsPrimary = video_is_primary_device(device->dev); + info->bPreserveVideoMemoryAllocations = false; + + return nvkm_gsp_rpc_wr(gsp, info, NVKM_GSP_RPC_REPLY_NOWAIT); +} + +static void +r570_gsp_set_rmargs(struct nvkm_gsp *gsp, bool resume) +{ + GSP_ARGUMENTS_CACHED *args; + + args = gsp->rmargs.data; + args->messageQueueInitArguments.sharedMemPhysAddr = gsp->shm.mem.addr; + args->messageQueueInitArguments.pageTableEntryCount = gsp->shm.ptes.nr; + args->messageQueueInitArguments.cmdQueueOffset = + (u8 *)gsp->shm.cmdq.ptr - (u8 *)gsp->shm.mem.data; + args->messageQueueInitArguments.statQueueOffset = + (u8 *)gsp->shm.msgq.ptr - (u8 *)gsp->shm.mem.data; + + if (!resume) { + args->srInitArguments.oldLevel = 0; + args->srInitArguments.flags = 0; + args->srInitArguments.bInPMTransition = 0; + } else { + args->srInitArguments.oldLevel = NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3; + args->srInitArguments.flags = 0; + args->srInitArguments.bInPMTransition = 1; + } + + args->bDmemStack = 1; +} + +const struct nvkm_rm_api_gsp +r570_gsp = { + .set_rmargs = r570_gsp_set_rmargs, + .set_system_info = r570_gsp_set_system_info, + .get_static_info = r570_gsp_get_static_info, + .xlat_mc_engine_idx = r570_gsp_xlat_mc_engine_idx, + .drop_post_nocat_record = r570_gsp_drop_post_nocat_record, + .sr_data_size = r570_gsp_sr_data_size, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/client.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/client.h new file mode 100644 index 000000000000..e8714e0abc37 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/client.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_CLIENT_H__ +#define __NVRM_CLIENT_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/570.144 */ + +#define NV01_ROOT (0x0U) /* finn: Evaluated from "NV0000_ALLOC_PARAMETERS_MESSAGE_ID" */ + +#define NV_PROC_NAME_MAX_LENGTH 100U + +typedef struct NV0000_ALLOC_PARAMETERS { + NvHandle hClient; /* CORERM-2934: hClient must remain the first member until all allocations use these params */ + NvU32 processID; + char processName[NV_PROC_NAME_MAX_LENGTH]; + NV_DECLARE_ALIGNED(NvP64 pOsPidInfo, 8); +} NV0000_ALLOC_PARAMETERS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h new file mode 100644 index 000000000000..06e972835d77 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h @@ -0,0 +1,355 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_DISP_H__ +#define __NVRM_DISP_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/570.144 */ + +#define NV2080_CTRL_CMD_INTERNAL_DISPLAY_GET_STATIC_INFO (0x20800a01) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS { + NvU32 feHwSysCap; + NvU32 windowPresentMask; + NvBool bFbRemapperEnabled; + NvU32 numHeads; + NvU32 i2cPort; + NvU32 internalDispActiveMask; + NvU32 embeddedDisplayPortMask; + NvBool bExternalMuxSupported; + NvBool bInternalMuxSupported; + NvU32 numDispChannels; +} NV2080_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO_PARAMS; + +#define NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED (0x730107U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayMask; + NvU32 displayMaskDDC; +} NV0073_CTRL_SYSTEM_GET_SUPPORTED_PARAMS; + +#define NV0073_CTRL_MAX_CONNECTORS 4U + +#define NV0073_CTRL_CMD_SPECIFIC_GET_CONNECTOR_DATA (0x730250U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 flags; + NvU32 DDCPartners; + NvU32 count; + struct { + NvU32 index; + NvU32 type; + NvU32 location; + } data[NV0073_CTRL_MAX_CONNECTORS]; + NvU32 platform; +} NV0073_CTRL_SPECIFIC_GET_CONNECTOR_DATA_PARAMS; + +#define NV0073_CTRL_CMD_DP_GET_CAPS (0x731369U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS_MESSAGE_ID" */ + +typedef struct NV0073_CTRL_CMD_DSC_CAP_PARAMS { + NvBool bDscSupported; + NvU32 encoderColorFormatMask; + NvU32 lineBufferSizeKB; + NvU32 rateBufferSizeKB; + NvU32 bitsPerPixelPrecision; + NvU32 maxNumHztSlices; + NvU32 lineBufferBitDepth; +} NV0073_CTRL_CMD_DSC_CAP_PARAMS; + +typedef struct NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS { + NvU32 subDeviceInstance; + NvU32 sorIndex; + NvU32 maxLinkRate; + NvU32 dpVersionsSupported; + NvU32 UHBRSupportedByGpu; + NvU32 minPClkForCompressed; + NvBool bIsMultistreamSupported; + NvBool bIsSCEnabled; + NvBool bHasIncreasedWatermarkLimits; + NvBool bIsPC2Disabled; + NvBool isSingleHeadMSTSupported; + NvBool bFECSupported; + NvBool bIsTrainPhyRepeater; + NvBool bOverrideLinkBw; + NvBool bUseRgFlushSequence; + NvBool bSupportDPDownSpread; + NV0073_CTRL_CMD_DSC_CAP_PARAMS DSC; +} NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS; + +#define NV0073_CTRL_CMD_DP_GET_CAPS (0x731369U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS_MESSAGE_ID" */ +#define NV0073_CTRL_CMD_DP_GET_CAPS_PARAMS_MESSAGE_ID (0x69U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_2 0:0 +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_2_NO (0x00000000U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_2_YES (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_4 1:1 +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_4_NO (0x00000000U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP1_4_YES (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP2_0 2:2 +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP2_0_NO (0x00000000U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DP_VERSIONS_SUPPORTED_DP2_0_YES (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE 2:0 +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_NONE (0x00000000U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_1_62 (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_2_70 (0x00000002U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_5_40 (0x00000003U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_MAX_LINK_RATE_8_10 (0x00000004U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_UHBR_SUPPORTED_UHBR10_0 0:0 +#define NV0073_CTRL_CMD_DP_GET_CAPS_UHBR_SUPPORTED_UHBR10_0_NO (0x00000000U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_UHBR_SUPPORTED_UHBR10_0_YES (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_UHBR_SUPPORTED_UHBR13_5 1:1 +#define NV0073_CTRL_CMD_DP_GET_CAPS_UHBR_SUPPORTED_UHBR13_5_NO (0x00000000U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_UHBR_SUPPORTED_UHBR13_5_YES (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_UHBR_SUPPORTED_UHBR20_0 2:2 +#define NV0073_CTRL_CMD_DP_GET_CAPS_UHBR_SUPPORTED_UHBR20_0_NO (0x00000000U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_UHBR_SUPPORTED_UHBR20_0_YES (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_RGB (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_444 (0x00000002U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_NATIVE_422 (0x00000004U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_ENCODER_COLOR_FORMAT_Y_CB_CR_NATIVE_420 (0x00000008U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_16 (0x00000001U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_8 (0x00000002U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_4 (0x00000003U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1_2 (0x00000004U) +#define NV0073_CTRL_CMD_DP_GET_CAPS_DSC_BITS_PER_PIXEL_PRECISION_1 (0x00000005U) + +#define NV0073_CTRL_CMD_SYSTEM_GET_CONNECT_STATE (0x730108U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS { + NvU32 subDeviceInstance; + NvU32 flags; + NvU32 displayMask; + NvU32 retryTimeMs; +} NV0073_CTRL_SYSTEM_GET_CONNECT_STATE_PARAMS; + +#define NV0073_CTRL_CMD_DFP_GET_INFO (0x731140U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DFP_INTERFACE_ID << 8) | NV0073_CTRL_DFP_GET_INFO_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_DFP_GET_INFO_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 flags; + NvU32 UHBRSupportedByDfp; +} NV0073_CTRL_DFP_GET_INFO_PARAMS; + +#define NV0073_CTRL_DFP_FLAGS_SIGNAL 2:0 +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_TMDS (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_LVDS (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_SDI (0x00000002U) +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_DISPLAYPORT (0x00000003U) +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_DSI (0x00000004U) +#define NV0073_CTRL_DFP_FLAGS_SIGNAL_WRBK (0x00000005U) +#define NV0073_CTRL_DFP_FLAGS_LANE 5:3 +#define NV0073_CTRL_DFP_FLAGS_LANE_NONE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_LANE_SINGLE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_LANE_DUAL (0x00000002U) +#define NV0073_CTRL_DFP_FLAGS_LANE_QUAD (0x00000003U) +#define NV0073_CTRL_DFP_FLAGS_LANE_OCT (0x00000004U) +#define NV0073_CTRL_DFP_FLAGS_LIMIT 6:6 +#define NV0073_CTRL_DFP_FLAGS_LIMIT_DISABLE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_LIMIT_60HZ_RR (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_SLI_SCALER 7:7 +#define NV0073_CTRL_DFP_FLAGS_SLI_SCALER_NORMAL (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_SLI_SCALER_DISABLE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_HDMI_CAPABLE 8:8 +#define NV0073_CTRL_DFP_FLAGS_HDMI_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_HDMI_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_RANGE_LIMITED_CAPABLE 9:9 +#define NV0073_CTRL_DFP_FLAGS_RANGE_LIMITED_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_RANGE_LIMITED_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_RANGE_AUTO_CAPABLE 10:10 +#define NV0073_CTRL_DFP_FLAGS_RANGE_AUTO_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_RANGE_AUTO_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR422_CAPABLE 11:11 +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR422_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR422_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR444_CAPABLE 12:12 +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR444_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_FORMAT_YCBCR444_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_TYPE_C_TO_DP_CONNECTOR 13:13 +#define NV0073_CTRL_DFP_FLAGS_TYPE_C_TO_DP_CONNECTOR_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_TYPE_C_TO_DP_CONNECTOR_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_HDMI_ALLOWED 14:14 +#define NV0073_CTRL_DFP_FLAGS_HDMI_ALLOWED_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_HDMI_ALLOWED_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_EMBEDDED_DISPLAYPORT 15:15 +#define NV0073_CTRL_DFP_FLAGS_EMBEDDED_DISPLAYPORT_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_EMBEDDED_DISPLAYPORT_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_CONSTRAINT 16:16 +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_CONSTRAINT_NONE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_CONSTRAINT_PREFER_RBR (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW 19:17 +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_1_62GBPS (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_2_70GBPS (0x00000002U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_5_40GBPS (0x00000003U) +#define NV0073_CTRL_DFP_FLAGS_DP_LINK_BW_8_10GBPS (0x00000004U) +#define NV0073_CTRL_DFP_FLAGS_LINK 21:20 +#define NV0073_CTRL_DFP_FLAGS_LINK_NONE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_LINK_SINGLE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_LINK_DUAL (0x00000002U) +#define NV0073_CTRL_DFP_FLAGS_DP_FORCE_RM_EDID 22:22 +#define NV0073_CTRL_DFP_FLAGS_DP_FORCE_RM_EDID_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_DP_FORCE_RM_EDID_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID 24:23 +#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_NONE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_A (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_B (0x00000002U) +#define NV0073_CTRL_DFP_FLAGS_DSI_DEVICE_ID_DSI_GANGED (0x00000003U) +#define NV0073_CTRL_DFP_FLAGS_DP_POST_CURSOR2_DISABLED 25:25 +#define NV0073_CTRL_DFP_FLAGS_DP_POST_CURSOR2_DISABLED_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_DP_POST_CURSOR2_DISABLED_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS_DP_PHY_REPEATER_COUNT 29:26 +#define NV0073_CTRL_DFP_FLAGS_DYNAMIC_MUX_CAPABLE 30:30 +#define NV0073_CTRL_DFP_FLAGS_DYNAMIC_MUX_CAPABLE_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS_DYNAMIC_MUX_CAPABLE_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS2_DP_UHBR_SUPPORTED_10_0GBPS 0:0 +#define NV0073_CTRL_DFP_FLAGS2_DP_UHBR_SUPPORTED_10_0GBPS_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS2_DP_UHBR_SUPPORTED_10_0GBPS_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS2_DP_UHBR_SUPPORTED_13_5GBPS 1:1 +#define NV0073_CTRL_DFP_FLAGS2_DP_UHBR_SUPPORTED_13_5GBPS_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS2_DP_UHBR_SUPPORTED_13_5GBPS_TRUE (0x00000001U) +#define NV0073_CTRL_DFP_FLAGS2_DP_UHBR_SUPPORTED_20_0GBPS 2:2 +#define NV0073_CTRL_DFP_FLAGS2_DP_UHBR_SUPPORTED_20_0GBPS_FALSE (0x00000000U) +#define NV0073_CTRL_DFP_FLAGS2_DP_UHBR_SUPPORTED_20_0GBPS_TRUE (0x00000001U) + +#define NV0073_CTRL_CMD_SYSTEM_GET_ACTIVE (0x73010cU) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SYSTEM_INTERFACE_ID << 8) | NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS { + NvU32 subDeviceInstance; + NvU32 head; + NvU32 flags; + NvU32 displayId; +} NV0073_CTRL_SYSTEM_GET_ACTIVE_PARAMS; + +#define NV0073_CTRL_CMD_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS (0x730292U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_SET_BACKLIGHT_BRIGHTNESS_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_CMD_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS (0x730291U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_SPECIFIC_INTERFACE_ID << 8) | NV0073_CTRL_SPECIFIC_GET_BACKLIGHT_BRIGHTNESS_PARAMS_MESSAGE_ID" */ + +typedef struct NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 brightness; + NvBool bUncalibrated; + NvU8 brightnessType; +} NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_PARAMS; + +#define NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES (0x731377U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS_MESSAGE_ID" */ + +#define NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES 8U + +typedef struct NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS { + // In + NvU32 subDeviceInstance; + NvU32 displayId; + NvU16 linkRateTbl[NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES]; + + // Out + NvU16 linkBwTbl[NV0073_CTRL_DP_MAX_INDEXED_LINK_RATES]; + NvU8 linkBwCount; +} NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS; + +#define NV0073_CTRL_CMD_DP_CTRL (0x731343U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_DP_CTRL_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_DP_CTRL_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 cmd; + NvU32 data; + NvU32 err; + NvU32 retryTimeMs; + NvU32 eightLaneDpcdBaseAddr; +} NV0073_CTRL_DP_CTRL_PARAMS; + +typedef struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS { + NvU32 subDeviceInstance; + NvU32 head; + NvU32 sorIndex; + NvU32 dpLink; + + NvBool bEnableOverride; + NvBool bMST; + NvU32 singleHeadMultistreamMode; + NvU32 hBlankSym; + NvU32 vBlankSym; + NvU32 colorFormat; + NvBool bEnableTwoHeadOneOr; + + struct { + NvU32 slotStart; + NvU32 slotEnd; + NvU32 PBN; + NvU32 Timeslice; + NvBool sendACT; // deprecated -Use NV0073_CTRL_CMD_DP_SEND_ACT + NvU32 singleHeadMSTPipeline; + NvBool bEnableAudioOverRightPanel; + } MST; + + struct { + NvBool bEnhancedFraming; + NvU32 tuSize; + NvU32 waterMark; + NvBool bEnableAudioOverRightPanel; + } SST; +} NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS; + +#define NV0073_CTRL_CMD_DP_SET_AUDIO_MUTESTREAM (0x731359U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_DP_SET_AUDIO_MUTESTREAM_PARAMS_MESSAGE_ID" */ +typedef struct NV0073_CTRL_DP_SET_AUDIO_MUTESTREAM_PARAMS { + NvU32 subDeviceInstance; + NvU32 displayId; + NvU32 mute; +} NV0073_CTRL_DP_SET_AUDIO_MUTESTREAM_PARAMS; + +#define NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER (0x20800a58) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS { + NvU32 addressSpace; + NV_DECLARE_ALIGNED(NvU64 physicalAddr, 8); + NV_DECLARE_ALIGNED(NvU64 limit, 8); + NvU32 cacheSnoop; + NvU32 hclass; + NvU32 channelInstance; + NvBool valid; + NvU32 pbTargetAperture; + NvU32 channelPBSize; + NvU32 subDeviceId; +} NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER_PARAMS; + +#define ADDR_SYSMEM (1) + +#define ADDR_FBMEM 2 // Frame buffer memory space + +typedef enum +{ + PB_SIZE_4KB = 0, + PB_SIZE_8KB, + PB_SIZE_16KB, + PB_SIZE_32KB, + PB_SIZE_64KB +} ChannelPBSize; + +typedef struct +{ + NvV32 channelInstance; // One of the n channel instances of a given channel type. + // Note that core channel has only one instance + // while all others have two (one per head). + NvHandle hObjectBuffer; // ctx dma handle for DMA push buffer + NvHandle hObjectNotify; // ctx dma handle for an area (of type NvNotification defined in sdk/nvidia/inc/nvtypes.h) where RM can write errors/notifications + NvU32 offset; // Initial offset for put/get, usually zero. + NvP64 pControl NV_ALIGN_BYTES(8); // pControl gives virt addr of UDISP GET/PUT regs + + NvU32 flags; + ChannelPBSize channelPBSize; // Size of Push Buffer requested by client (allowed values in enum) +#define NV50VAIO_CHANNELDMA_ALLOCATION_FLAGS_CONNECT_PB_AT_GRAB 1:1 +#define NV50VAIO_CHANNELDMA_ALLOCATION_FLAGS_CONNECT_PB_AT_GRAB_YES 0x00000000 +#define NV50VAIO_CHANNELDMA_ALLOCATION_FLAGS_CONNECT_PB_AT_GRAB_NO 0x00000001 + + NvU32 subDeviceId; // One-hot encoded subDeviceId (i.e. SDM) that will be used to address the channel in the pushbuffer stream (via SSDM method) +} NV50VAIO_CHANNELDMA_ALLOCATION_PARAMETERS; + +#define NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_PERCENT100 1 +#define NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_PERCENT1000 2 +#define NV0073_CTRL_SPECIFIC_BACKLIGHT_BRIGHTNESS_TYPE_NITS 3 + +typedef enum +{ + IOVA, + PHYS_NVM, + PHYS_PCI, + PHYS_PCI_COHERENT +} PBTARGETAPERTURE; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/engine.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/engine.h new file mode 100644 index 000000000000..7997050a4f29 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/engine.h @@ -0,0 +1,318 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_ENGINE_H__ +#define __NVRM_ENGINE_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/570.144 */ + +#define MC_ENGINE_IDX_NULL 0 // This must be 0 +#define MC_ENGINE_IDX_TMR 1 +#define MC_ENGINE_IDX_DISP 2 +#define MC_ENGINE_IDX_FB 3 +#define MC_ENGINE_IDX_FIFO 4 +#define MC_ENGINE_IDX_VIDEO 5 +#define MC_ENGINE_IDX_MD 6 +#define MC_ENGINE_IDX_BUS 7 +#define MC_ENGINE_IDX_PMGR 8 +#define MC_ENGINE_IDX_VP2 9 +#define MC_ENGINE_IDX_CIPHER 10 +#define MC_ENGINE_IDX_BIF 11 +#define MC_ENGINE_IDX_PPP 12 +#define MC_ENGINE_IDX_PRIVRING 13 +#define MC_ENGINE_IDX_PMU 14 +#define MC_ENGINE_IDX_CE0 15 +#define MC_ENGINE_IDX_CE1 16 +#define MC_ENGINE_IDX_CE2 17 +#define MC_ENGINE_IDX_CE3 18 +#define MC_ENGINE_IDX_CE4 19 +#define MC_ENGINE_IDX_CE5 20 +#define MC_ENGINE_IDX_CE6 21 +#define MC_ENGINE_IDX_CE7 22 +#define MC_ENGINE_IDX_CE8 23 +#define MC_ENGINE_IDX_CE9 24 +#define MC_ENGINE_IDX_CE10 25 +#define MC_ENGINE_IDX_CE11 26 +#define MC_ENGINE_IDX_CE12 27 +#define MC_ENGINE_IDX_CE13 28 +#define MC_ENGINE_IDX_CE14 29 +#define MC_ENGINE_IDX_CE15 30 +#define MC_ENGINE_IDX_CE16 31 +#define MC_ENGINE_IDX_CE17 32 +#define MC_ENGINE_IDX_CE18 33 +#define MC_ENGINE_IDX_CE19 34 +#define MC_ENGINE_IDX_CE_MAX MC_ENGINE_IDX_CE19 +#define MC_ENGINE_IDX_VIC 35 +#define MC_ENGINE_IDX_ISOHUB 36 +#define MC_ENGINE_IDX_VGPU 37 +#define MC_ENGINE_IDX_NVENC 38 +#define MC_ENGINE_IDX_NVENC1 39 +#define MC_ENGINE_IDX_NVENC2 40 +#define MC_ENGINE_IDX_NVENC3 41 +#define MC_ENGINE_IDX_C2C 42 +#define MC_ENGINE_IDX_LTC 43 +#define MC_ENGINE_IDX_FBHUB 44 +#define MC_ENGINE_IDX_HDACODEC 45 +#define MC_ENGINE_IDX_GMMU 46 +#define MC_ENGINE_IDX_SEC2 47 +#define MC_ENGINE_IDX_FSP 48 +#define MC_ENGINE_IDX_NVLINK 49 +#define MC_ENGINE_IDX_GSP 50 +#define MC_ENGINE_IDX_NVJPG 51 +#define MC_ENGINE_IDX_NVJPEG MC_ENGINE_IDX_NVJPG +#define MC_ENGINE_IDX_NVJPEG0 MC_ENGINE_IDX_NVJPEG +#define MC_ENGINE_IDX_NVJPEG1 52 +#define MC_ENGINE_IDX_NVJPEG2 53 +#define MC_ENGINE_IDX_NVJPEG3 54 +#define MC_ENGINE_IDX_NVJPEG4 55 +#define MC_ENGINE_IDX_NVJPEG5 56 +#define MC_ENGINE_IDX_NVJPEG6 57 +#define MC_ENGINE_IDX_NVJPEG7 58 +#define MC_ENGINE_IDX_REPLAYABLE_FAULT 59 +#define MC_ENGINE_IDX_ACCESS_CNTR 60 +#define MC_ENGINE_IDX_NON_REPLAYABLE_FAULT 61 +#define MC_ENGINE_IDX_REPLAYABLE_FAULT_ERROR 62 +#define MC_ENGINE_IDX_NON_REPLAYABLE_FAULT_ERROR 63 +#define MC_ENGINE_IDX_INFO_FAULT 64 +#define MC_ENGINE_IDX_BSP 65 +#define MC_ENGINE_IDX_NVDEC MC_ENGINE_IDX_BSP +#define MC_ENGINE_IDX_NVDEC0 MC_ENGINE_IDX_NVDEC +#define MC_ENGINE_IDX_NVDEC1 66 +#define MC_ENGINE_IDX_NVDEC2 67 +#define MC_ENGINE_IDX_NVDEC3 68 +#define MC_ENGINE_IDX_NVDEC4 69 +#define MC_ENGINE_IDX_NVDEC5 70 +#define MC_ENGINE_IDX_NVDEC6 71 +#define MC_ENGINE_IDX_NVDEC7 72 +#define MC_ENGINE_IDX_CPU_DOORBELL 73 +#define MC_ENGINE_IDX_PRIV_DOORBELL 74 +#define MC_ENGINE_IDX_MMU_ECC_ERROR 75 +#define MC_ENGINE_IDX_BLG 76 +#define MC_ENGINE_IDX_PERFMON 77 +#define MC_ENGINE_IDX_BUF_RESET 78 +#define MC_ENGINE_IDX_XBAR 79 +#define MC_ENGINE_IDX_ZPW 80 +#define MC_ENGINE_IDX_OFA0 81 +#define MC_ENGINE_IDX_OFA1 82 +#define MC_ENGINE_IDX_TEGRA 83 +#define MC_ENGINE_IDX_GR 84 +#define MC_ENGINE_IDX_GR0 MC_ENGINE_IDX_GR +#define MC_ENGINE_IDX_GR1 85 +#define MC_ENGINE_IDX_GR2 86 +#define MC_ENGINE_IDX_GR3 87 +#define MC_ENGINE_IDX_GR4 88 +#define MC_ENGINE_IDX_GR5 89 +#define MC_ENGINE_IDX_GR6 90 +#define MC_ENGINE_IDX_GR7 91 +#define MC_ENGINE_IDX_ESCHED 92 +#define MC_ENGINE_IDX_ESCHED__SIZE 64 +#define MC_ENGINE_IDX_GR_FECS_LOG 156 +#define MC_ENGINE_IDX_GR0_FECS_LOG MC_ENGINE_IDX_GR_FECS_LOG +#define MC_ENGINE_IDX_GR1_FECS_LOG 157 +#define MC_ENGINE_IDX_GR2_FECS_LOG 158 +#define MC_ENGINE_IDX_GR3_FECS_LOG 159 +#define MC_ENGINE_IDX_GR4_FECS_LOG 160 +#define MC_ENGINE_IDX_GR5_FECS_LOG 161 +#define MC_ENGINE_IDX_GR6_FECS_LOG 162 +#define MC_ENGINE_IDX_GR7_FECS_LOG 163 +#define MC_ENGINE_IDX_TMR_SWRL 164 +#define MC_ENGINE_IDX_DISP_GSP 165 +#define MC_ENGINE_IDX_REPLAYABLE_FAULT_CPU 166 +#define MC_ENGINE_IDX_NON_REPLAYABLE_FAULT_CPU 167 +#define MC_ENGINE_IDX_PXUC 168 +#define MC_ENGINE_IDX_SYSLTC 169 +#define MC_ENGINE_IDX_LRCC 170 +#define MC_ENGINE_IDX_GSPLITE 171 +#define MC_ENGINE_IDX_GSPLITE0 MC_ENGINE_IDX_GSPLITE +#define MC_ENGINE_IDX_GSPLITE1 172 +#define MC_ENGINE_IDX_GSPLITE2 173 +#define MC_ENGINE_IDX_GSPLITE3 174 +#define MC_ENGINE_IDX_GSPLITE_MAX MC_ENGINE_IDX_GSPLITE3 +#define MC_ENGINE_IDX_DPAUX 175 +#define MC_ENGINE_IDX_DISP_LOW 176 +#define MC_ENGINE_IDX_MAX 177 + +typedef enum +{ + RM_ENGINE_TYPE_NULL = (0x00000000), + RM_ENGINE_TYPE_GR0 = (0x00000001), + RM_ENGINE_TYPE_GR1 = (0x00000002), + RM_ENGINE_TYPE_GR2 = (0x00000003), + RM_ENGINE_TYPE_GR3 = (0x00000004), + RM_ENGINE_TYPE_GR4 = (0x00000005), + RM_ENGINE_TYPE_GR5 = (0x00000006), + RM_ENGINE_TYPE_GR6 = (0x00000007), + RM_ENGINE_TYPE_GR7 = (0x00000008), + RM_ENGINE_TYPE_COPY0 = (0x00000009), + RM_ENGINE_TYPE_COPY1 = (0x0000000a), + RM_ENGINE_TYPE_COPY2 = (0x0000000b), + RM_ENGINE_TYPE_COPY3 = (0x0000000c), + RM_ENGINE_TYPE_COPY4 = (0x0000000d), + RM_ENGINE_TYPE_COPY5 = (0x0000000e), + RM_ENGINE_TYPE_COPY6 = (0x0000000f), + RM_ENGINE_TYPE_COPY7 = (0x00000010), + RM_ENGINE_TYPE_COPY8 = (0x00000011), + RM_ENGINE_TYPE_COPY9 = (0x00000012), + RM_ENGINE_TYPE_COPY10 = (0x00000013), + RM_ENGINE_TYPE_COPY11 = (0x00000014), + RM_ENGINE_TYPE_COPY12 = (0x00000015), + RM_ENGINE_TYPE_COPY13 = (0x00000016), + RM_ENGINE_TYPE_COPY14 = (0x00000017), + RM_ENGINE_TYPE_COPY15 = (0x00000018), + RM_ENGINE_TYPE_COPY16 = (0x00000019), + RM_ENGINE_TYPE_COPY17 = (0x0000001a), + RM_ENGINE_TYPE_COPY18 = (0x0000001b), + RM_ENGINE_TYPE_COPY19 = (0x0000001c), + RM_ENGINE_TYPE_NVDEC0 = (0x0000001d), + RM_ENGINE_TYPE_NVDEC1 = (0x0000001e), + RM_ENGINE_TYPE_NVDEC2 = (0x0000001f), + RM_ENGINE_TYPE_NVDEC3 = (0x00000020), + RM_ENGINE_TYPE_NVDEC4 = (0x00000021), + RM_ENGINE_TYPE_NVDEC5 = (0x00000022), + RM_ENGINE_TYPE_NVDEC6 = (0x00000023), + RM_ENGINE_TYPE_NVDEC7 = (0x00000024), + RM_ENGINE_TYPE_NVENC0 = (0x00000025), + RM_ENGINE_TYPE_NVENC1 = (0x00000026), + RM_ENGINE_TYPE_NVENC2 = (0x00000027), + // Bug 4175886 - Use this new value for all chips once GB20X is released + RM_ENGINE_TYPE_NVENC3 = (0x00000028), + RM_ENGINE_TYPE_VP = (0x00000029), + RM_ENGINE_TYPE_ME = (0x0000002a), + RM_ENGINE_TYPE_PPP = (0x0000002b), + RM_ENGINE_TYPE_MPEG = (0x0000002c), + RM_ENGINE_TYPE_SW = (0x0000002d), + RM_ENGINE_TYPE_TSEC = (0x0000002e), + RM_ENGINE_TYPE_VIC = (0x0000002f), + RM_ENGINE_TYPE_MP = (0x00000030), + RM_ENGINE_TYPE_SEC2 = (0x00000031), + RM_ENGINE_TYPE_HOST = (0x00000032), + RM_ENGINE_TYPE_DPU = (0x00000033), + RM_ENGINE_TYPE_PMU = (0x00000034), + RM_ENGINE_TYPE_FBFLCN = (0x00000035), + RM_ENGINE_TYPE_NVJPEG0 = (0x00000036), + RM_ENGINE_TYPE_NVJPEG1 = (0x00000037), + RM_ENGINE_TYPE_NVJPEG2 = (0x00000038), + RM_ENGINE_TYPE_NVJPEG3 = (0x00000039), + RM_ENGINE_TYPE_NVJPEG4 = (0x0000003a), + RM_ENGINE_TYPE_NVJPEG5 = (0x0000003b), + RM_ENGINE_TYPE_NVJPEG6 = (0x0000003c), + RM_ENGINE_TYPE_NVJPEG7 = (0x0000003d), + RM_ENGINE_TYPE_OFA0 = (0x0000003e), + RM_ENGINE_TYPE_OFA1 = (0x0000003f), + RM_ENGINE_TYPE_RESERVED40 = (0x00000040), + RM_ENGINE_TYPE_RESERVED41 = (0x00000041), + RM_ENGINE_TYPE_RESERVED42 = (0x00000042), + RM_ENGINE_TYPE_RESERVED43 = (0x00000043), + RM_ENGINE_TYPE_RESERVED44 = (0x00000044), + RM_ENGINE_TYPE_RESERVED45 = (0x00000045), + RM_ENGINE_TYPE_RESERVED46 = (0x00000046), + RM_ENGINE_TYPE_RESERVED47 = (0x00000047), + RM_ENGINE_TYPE_RESERVED48 = (0x00000048), + RM_ENGINE_TYPE_RESERVED49 = (0x00000049), + RM_ENGINE_TYPE_RESERVED4a = (0x0000004a), + RM_ENGINE_TYPE_RESERVED4b = (0x0000004b), + RM_ENGINE_TYPE_RESERVED4c = (0x0000004c), + RM_ENGINE_TYPE_RESERVED4d = (0x0000004d), + RM_ENGINE_TYPE_RESERVED4e = (0x0000004e), + RM_ENGINE_TYPE_RESERVED4f = (0x0000004f), + RM_ENGINE_TYPE_RESERVED50 = (0x00000050), + RM_ENGINE_TYPE_RESERVED51 = (0x00000051), + RM_ENGINE_TYPE_RESERVED52 = (0x00000052), + RM_ENGINE_TYPE_RESERVED53 = (0x00000053), + RM_ENGINE_TYPE_LAST = (0x00000054), +} RM_ENGINE_TYPE; + +#define NV2080_ENGINE_TYPE_NULL (0x00000000) +#define NV2080_ENGINE_TYPE_GRAPHICS (0x00000001) +#define NV2080_ENGINE_TYPE_GR0 NV2080_ENGINE_TYPE_GRAPHICS +#define NV2080_ENGINE_TYPE_GR1 (0x00000002) +#define NV2080_ENGINE_TYPE_GR2 (0x00000003) +#define NV2080_ENGINE_TYPE_GR3 (0x00000004) +#define NV2080_ENGINE_TYPE_GR4 (0x00000005) +#define NV2080_ENGINE_TYPE_GR5 (0x00000006) +#define NV2080_ENGINE_TYPE_GR6 (0x00000007) +#define NV2080_ENGINE_TYPE_GR7 (0x00000008) +#define NV2080_ENGINE_TYPE_COPY0 (0x00000009) +#define NV2080_ENGINE_TYPE_COPY1 (0x0000000a) +#define NV2080_ENGINE_TYPE_COPY2 (0x0000000b) +#define NV2080_ENGINE_TYPE_COPY3 (0x0000000c) +#define NV2080_ENGINE_TYPE_COPY4 (0x0000000d) +#define NV2080_ENGINE_TYPE_COPY5 (0x0000000e) +#define NV2080_ENGINE_TYPE_COPY6 (0x0000000f) +#define NV2080_ENGINE_TYPE_COPY7 (0x00000010) +#define NV2080_ENGINE_TYPE_COPY8 (0x00000011) +#define NV2080_ENGINE_TYPE_COPY9 (0x00000012) +#define NV2080_ENGINE_TYPE_BSP (0x00000013) +#define NV2080_ENGINE_TYPE_NVDEC0 NV2080_ENGINE_TYPE_BSP +#define NV2080_ENGINE_TYPE_NVDEC1 (0x00000014) +#define NV2080_ENGINE_TYPE_NVDEC2 (0x00000015) +#define NV2080_ENGINE_TYPE_NVDEC3 (0x00000016) +#define NV2080_ENGINE_TYPE_NVDEC4 (0x00000017) +#define NV2080_ENGINE_TYPE_NVDEC5 (0x00000018) +#define NV2080_ENGINE_TYPE_NVDEC6 (0x00000019) +#define NV2080_ENGINE_TYPE_NVDEC7 (0x0000001a) +#define NV2080_ENGINE_TYPE_MSENC (0x0000001b) +#define NV2080_ENGINE_TYPE_NVENC0 NV2080_ENGINE_TYPE_MSENC /* Mutually exclusive alias */ +#define NV2080_ENGINE_TYPE_NVENC1 (0x0000001c) +#define NV2080_ENGINE_TYPE_NVENC2 (0x0000001d) +#define NV2080_ENGINE_TYPE_VP (0x0000001e) +#define NV2080_ENGINE_TYPE_ME (0x0000001f) +#define NV2080_ENGINE_TYPE_PPP (0x00000020) +#define NV2080_ENGINE_TYPE_MPEG (0x00000021) +#define NV2080_ENGINE_TYPE_SW (0x00000022) +#define NV2080_ENGINE_TYPE_CIPHER (0x00000023) +#define NV2080_ENGINE_TYPE_TSEC NV2080_ENGINE_TYPE_CIPHER +#define NV2080_ENGINE_TYPE_VIC (0x00000024) +#define NV2080_ENGINE_TYPE_MP (0x00000025) +#define NV2080_ENGINE_TYPE_SEC2 (0x00000026) +#define NV2080_ENGINE_TYPE_HOST (0x00000027) +#define NV2080_ENGINE_TYPE_DPU (0x00000028) +#define NV2080_ENGINE_TYPE_PMU (0x00000029) +#define NV2080_ENGINE_TYPE_FBFLCN (0x0000002a) +#define NV2080_ENGINE_TYPE_NVJPG (0x0000002b) +#define NV2080_ENGINE_TYPE_NVJPEG0 NV2080_ENGINE_TYPE_NVJPG +#define NV2080_ENGINE_TYPE_NVJPEG1 (0x0000002c) +#define NV2080_ENGINE_TYPE_NVJPEG2 (0x0000002d) +#define NV2080_ENGINE_TYPE_NVJPEG3 (0x0000002e) +#define NV2080_ENGINE_TYPE_NVJPEG4 (0x0000002f) +#define NV2080_ENGINE_TYPE_NVJPEG5 (0x00000030) +#define NV2080_ENGINE_TYPE_NVJPEG6 (0x00000031) +#define NV2080_ENGINE_TYPE_NVJPEG7 (0x00000032) +#define NV2080_ENGINE_TYPE_OFA (0x00000033) +#define NV2080_ENGINE_TYPE_OFA0 NV2080_ENGINE_TYPE_OFA +#define NV2080_ENGINE_TYPE_COPY10 (0x00000034) +#define NV2080_ENGINE_TYPE_COPY11 (0x00000035) +#define NV2080_ENGINE_TYPE_COPY12 (0x00000036) +#define NV2080_ENGINE_TYPE_COPY13 (0x00000037) +#define NV2080_ENGINE_TYPE_COPY14 (0x00000038) +#define NV2080_ENGINE_TYPE_COPY15 (0x00000039) +#define NV2080_ENGINE_TYPE_COPY16 (0x0000003a) +#define NV2080_ENGINE_TYPE_COPY17 (0x0000003b) +#define NV2080_ENGINE_TYPE_COPY18 (0x0000003c) +#define NV2080_ENGINE_TYPE_COPY19 (0x0000003d) +#define NV2080_ENGINE_TYPE_OFA1 (0x0000003e) +#define NV2080_ENGINE_TYPE_NVENC3 (0x0000003f) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY0 (0x00000040) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY1 (0x00000041) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY2 (0x00000042) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY3 (0x00000043) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY4 (0x00000044) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY5 (0x00000045) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY6 (0x00000046) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY7 (0x00000047) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY8 (0x00000048) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY9 (0x00000049) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY10 (0x0000004a) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY11 (0x0000004b) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY12 (0x0000004c) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY13 (0x0000004d) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY14 (0x0000004e) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY15 (0x0000004f) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY16 (0x00000050) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY17 (0x00000051) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY18 (0x00000052) +#define NV2080_ENGINE_TYPE_COMP_DECOMP_COPY19 (0x00000053) +#define NV2080_ENGINE_TYPE_LAST (0x00000054) +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/fbsr.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/fbsr.h new file mode 100644 index 000000000000..8af432375f7a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/fbsr.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_FBSR_H__ +#define __NVRM_FBSR_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/570.144 */ + +#define NV2080_CTRL_CMD_INTERNAL_FBSR_INIT (0x20800ac2) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS { + NvHandle hClient; + NvHandle hSysMem; + NvBool bEnteringGcoffState; + NV_DECLARE_ALIGNED(NvU64 sysmemAddrOfSuspendResumeData, 8); +} NV2080_CTRL_INTERNAL_FBSR_INIT_PARAMS; + +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/alloc/alloc_channel.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/fifo.h index 7157c7757698..2b002ca64e0f 100644 --- a/drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/sdk/nvidia/inc/alloc/alloc_channel.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/fifo.h @@ -1,31 +1,14 @@ -#ifndef __src_common_sdk_nvidia_inc_alloc_alloc_channel_h__ -#define __src_common_sdk_nvidia_inc_alloc_alloc_channel_h__ -#include <nvrm/535.113.01/common/sdk/nvidia/inc/nvlimits.h> - -/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/535.113.01 */ - -/* - * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_FIFO_H__ +#define __NVRM_FIFO_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/570.144 */ + +#define NV_MAX_SUBDEVICES 8 typedef struct NV_MEMORY_DESC_PARAMS { NV_DECLARE_ALIGNED(NvU64 base, 8); @@ -34,137 +17,197 @@ typedef struct NV_MEMORY_DESC_PARAMS { NvU32 cacheAttrib; } NV_MEMORY_DESC_PARAMS; +#define CC_CHAN_ALLOC_IV_SIZE_DWORD 3U + +#define CC_CHAN_ALLOC_NONCE_SIZE_DWORD 8U + +typedef struct NV_CHANNEL_ALLOC_PARAMS { + + NvHandle hObjectError; // error context DMA + NvHandle hObjectBuffer; // no longer used + NV_DECLARE_ALIGNED(NvU64 gpFifoOffset, 8); // offset to beginning of GP FIFO + NvU32 gpFifoEntries; // number of GP FIFO entries + + NvU32 flags; + + + NvHandle hContextShare; // context share handle + NvHandle hVASpace; // VASpace for the channel + + // handle to UserD memory object for channel, ignored if hUserdMemory[0]=0 + NvHandle hUserdMemory[NV_MAX_SUBDEVICES]; + + // offset to beginning of UserD within hUserdMemory[x] + NV_DECLARE_ALIGNED(NvU64 userdOffset[NV_MAX_SUBDEVICES], 8); + + // engine type(NV2080_ENGINE_TYPE_*) with which this channel is associated + NvU32 engineType; + // Channel identifier that is unique for the duration of a RM session + NvU32 cid; + // One-hot encoded bitmask to match SET_SUBDEVICE_MASK methods + NvU32 subDeviceId; + NvHandle hObjectEccError; // ECC error context DMA + + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS instanceMem, 8); + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS userdMem, 8); + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS ramfcMem, 8); + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS mthdbufMem, 8); + + NvHandle hPhysChannelGroup; // reserved + NvU32 internalFlags; // reserved + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS errorNotifierMem, 8); // reserved + NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS eccErrorNotifierMem, 8); // reserved + NvU32 ProcessID; // reserved + NvU32 SubProcessID; // reserved + + // IV used for CPU-side encryption / GPU-side decryption. + NvU32 encryptIv[CC_CHAN_ALLOC_IV_SIZE_DWORD]; // reserved + // IV used for CPU-side decryption / GPU-side encryption. + NvU32 decryptIv[CC_CHAN_ALLOC_IV_SIZE_DWORD]; // reserved + // Nonce used CPU-side signing / GPU-side signature verification. + NvU32 hmacNonce[CC_CHAN_ALLOC_NONCE_SIZE_DWORD]; // reserved + NvU32 tpcConfigID; // TPC Configuration Id as supported by DTD-PG Feature +} NV_CHANNEL_ALLOC_PARAMS; + +typedef NV_CHANNEL_ALLOC_PARAMS NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS; + #define NVOS04_FLAGS_CHANNEL_TYPE 1:0 #define NVOS04_FLAGS_CHANNEL_TYPE_PHYSICAL 0x00000000 #define NVOS04_FLAGS_CHANNEL_TYPE_VIRTUAL 0x00000001 // OBSOLETE #define NVOS04_FLAGS_CHANNEL_TYPE_PHYSICAL_FOR_VIRTUAL 0x00000002 // OBSOLETE - #define NVOS04_FLAGS_VPR 2:2 #define NVOS04_FLAGS_VPR_FALSE 0x00000000 #define NVOS04_FLAGS_VPR_TRUE 0x00000001 - #define NVOS04_FLAGS_CC_SECURE 2:2 #define NVOS04_FLAGS_CC_SECURE_FALSE 0x00000000 #define NVOS04_FLAGS_CC_SECURE_TRUE 0x00000001 - #define NVOS04_FLAGS_CHANNEL_SKIP_MAP_REFCOUNTING 3:3 #define NVOS04_FLAGS_CHANNEL_SKIP_MAP_REFCOUNTING_FALSE 0x00000000 #define NVOS04_FLAGS_CHANNEL_SKIP_MAP_REFCOUNTING_TRUE 0x00000001 - #define NVOS04_FLAGS_GROUP_CHANNEL_RUNQUEUE 4:4 #define NVOS04_FLAGS_GROUP_CHANNEL_RUNQUEUE_DEFAULT 0x00000000 #define NVOS04_FLAGS_GROUP_CHANNEL_RUNQUEUE_ONE 0x00000001 - #define NVOS04_FLAGS_PRIVILEGED_CHANNEL 5:5 #define NVOS04_FLAGS_PRIVILEGED_CHANNEL_FALSE 0x00000000 #define NVOS04_FLAGS_PRIVILEGED_CHANNEL_TRUE 0x00000001 - #define NVOS04_FLAGS_DELAY_CHANNEL_SCHEDULING 6:6 #define NVOS04_FLAGS_DELAY_CHANNEL_SCHEDULING_FALSE 0x00000000 #define NVOS04_FLAGS_DELAY_CHANNEL_SCHEDULING_TRUE 0x00000001 - #define NVOS04_FLAGS_CHANNEL_DENY_PHYSICAL_MODE_CE 7:7 #define NVOS04_FLAGS_CHANNEL_DENY_PHYSICAL_MODE_CE_FALSE 0x00000000 #define NVOS04_FLAGS_CHANNEL_DENY_PHYSICAL_MODE_CE_TRUE 0x00000001 - #define NVOS04_FLAGS_CHANNEL_USERD_INDEX_VALUE 10:8 - #define NVOS04_FLAGS_CHANNEL_USERD_INDEX_FIXED 11:11 #define NVOS04_FLAGS_CHANNEL_USERD_INDEX_FIXED_FALSE 0x00000000 #define NVOS04_FLAGS_CHANNEL_USERD_INDEX_FIXED_TRUE 0x00000001 - #define NVOS04_FLAGS_CHANNEL_USERD_INDEX_PAGE_VALUE 20:12 - #define NVOS04_FLAGS_CHANNEL_USERD_INDEX_PAGE_FIXED 21:21 #define NVOS04_FLAGS_CHANNEL_USERD_INDEX_PAGE_FIXED_FALSE 0x00000000 #define NVOS04_FLAGS_CHANNEL_USERD_INDEX_PAGE_FIXED_TRUE 0x00000001 - #define NVOS04_FLAGS_CHANNEL_DENY_AUTH_LEVEL_PRIV 22:22 #define NVOS04_FLAGS_CHANNEL_DENY_AUTH_LEVEL_PRIV_FALSE 0x00000000 #define NVOS04_FLAGS_CHANNEL_DENY_AUTH_LEVEL_PRIV_TRUE 0x00000001 - #define NVOS04_FLAGS_CHANNEL_SKIP_SCRUBBER 23:23 #define NVOS04_FLAGS_CHANNEL_SKIP_SCRUBBER_FALSE 0x00000000 #define NVOS04_FLAGS_CHANNEL_SKIP_SCRUBBER_TRUE 0x00000001 - #define NVOS04_FLAGS_CHANNEL_CLIENT_MAP_FIFO 24:24 #define NVOS04_FLAGS_CHANNEL_CLIENT_MAP_FIFO_FALSE 0x00000000 #define NVOS04_FLAGS_CHANNEL_CLIENT_MAP_FIFO_TRUE 0x00000001 - #define NVOS04_FLAGS_SET_EVICT_LAST_CE_PREFETCH_CHANNEL 25:25 #define NVOS04_FLAGS_SET_EVICT_LAST_CE_PREFETCH_CHANNEL_FALSE 0x00000000 #define NVOS04_FLAGS_SET_EVICT_LAST_CE_PREFETCH_CHANNEL_TRUE 0x00000001 - #define NVOS04_FLAGS_CHANNEL_VGPU_PLUGIN_CONTEXT 26:26 #define NVOS04_FLAGS_CHANNEL_VGPU_PLUGIN_CONTEXT_FALSE 0x00000000 #define NVOS04_FLAGS_CHANNEL_VGPU_PLUGIN_CONTEXT_TRUE 0x00000001 - #define NVOS04_FLAGS_CHANNEL_PBDMA_ACQUIRE_TIMEOUT 27:27 #define NVOS04_FLAGS_CHANNEL_PBDMA_ACQUIRE_TIMEOUT_FALSE 0x00000000 #define NVOS04_FLAGS_CHANNEL_PBDMA_ACQUIRE_TIMEOUT_TRUE 0x00000001 - #define NVOS04_FLAGS_GROUP_CHANNEL_THREAD 29:28 #define NVOS04_FLAGS_GROUP_CHANNEL_THREAD_DEFAULT 0x00000000 #define NVOS04_FLAGS_GROUP_CHANNEL_THREAD_ONE 0x00000001 #define NVOS04_FLAGS_GROUP_CHANNEL_THREAD_TWO 0x00000002 - #define NVOS04_FLAGS_MAP_CHANNEL 30:30 #define NVOS04_FLAGS_MAP_CHANNEL_FALSE 0x00000000 #define NVOS04_FLAGS_MAP_CHANNEL_TRUE 0x00000001 - #define NVOS04_FLAGS_SKIP_CTXBUFFER_ALLOC 31:31 #define NVOS04_FLAGS_SKIP_CTXBUFFER_ALLOC_FALSE 0x00000000 #define NVOS04_FLAGS_SKIP_CTXBUFFER_ALLOC_TRUE 0x00000001 -#define CC_CHAN_ALLOC_IV_SIZE_DWORD 3U -#define CC_CHAN_ALLOC_NONCE_SIZE_DWORD 8U - -typedef struct NV_CHANNEL_ALLOC_PARAMS { - - NvHandle hObjectError; // error context DMA - NvHandle hObjectBuffer; // no longer used - NV_DECLARE_ALIGNED(NvU64 gpFifoOffset, 8); // offset to beginning of GP FIFO - NvU32 gpFifoEntries; // number of GP FIFO entries - - NvU32 flags; - - - NvHandle hContextShare; // context share handle - NvHandle hVASpace; // VASpace for the channel - - // handle to UserD memory object for channel, ignored if hUserdMemory[0]=0 - NvHandle hUserdMemory[NV_MAX_SUBDEVICES]; - - // offset to beginning of UserD within hUserdMemory[x] - NV_DECLARE_ALIGNED(NvU64 userdOffset[NV_MAX_SUBDEVICES], 8); - - // engine type(NV2080_ENGINE_TYPE_*) with which this channel is associated - NvU32 engineType; - // Channel identifier that is unique for the duration of a RM session - NvU32 cid; - // One-hot encoded bitmask to match SET_SUBDEVICE_MASK methods - NvU32 subDeviceId; - NvHandle hObjectEccError; // ECC error context DMA - - NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS instanceMem, 8); - NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS userdMem, 8); - NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS ramfcMem, 8); - NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS mthdbufMem, 8); - - NvHandle hPhysChannelGroup; // reserved - NvU32 internalFlags; // reserved - NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS errorNotifierMem, 8); // reserved - NV_DECLARE_ALIGNED(NV_MEMORY_DESC_PARAMS eccErrorNotifierMem, 8); // reserved - NvU32 ProcessID; // reserved - NvU32 SubProcessID; // reserved - // IV used for CPU-side encryption / GPU-side decryption. - NvU32 encryptIv[CC_CHAN_ALLOC_IV_SIZE_DWORD]; // reserved - // IV used for CPU-side decryption / GPU-side encryption. - NvU32 decryptIv[CC_CHAN_ALLOC_IV_SIZE_DWORD]; // reserved - // Nonce used CPU-side signing / GPU-side signature verification. - NvU32 hmacNonce[CC_CHAN_ALLOC_NONCE_SIZE_DWORD]; // reserved -} NV_CHANNEL_ALLOC_PARAMS; - -typedef NV_CHANNEL_ALLOC_PARAMS NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS; - +typedef enum { + /*! + * Initial state as passed in NV_CHANNEL_ALLOC_PARAMS by + * kernel CPU-RM clients. + */ + ERROR_NOTIFIER_TYPE_UNKNOWN = 0, + /*! @brief Error notifier is explicitly not set. + * + * The corresponding hErrorContext or hEccErrorContext must be + * NV01_NULL_OBJECT. + */ + ERROR_NOTIFIER_TYPE_NONE, + /*! @brief Error notifier is a ContextDma */ + ERROR_NOTIFIER_TYPE_CTXDMA, + /*! @brief Error notifier is a NvNotification array in sysmem/vidmem */ + ERROR_NOTIFIER_TYPE_MEMORY +} ErrorNotifierType; + +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE 1:0 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE_USER 0x0 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE_ADMIN 0x1 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_PRIVILEGE_KERNEL 0x2 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE 3:2 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_UNKNOWN ERROR_NOTIFIER_TYPE_UNKNOWN +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_NONE ERROR_NOTIFIER_TYPE_NONE +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_CTXDMA ERROR_NOTIFIER_TYPE_CTXDMA +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ERROR_NOTIFIER_TYPE_MEMORY ERROR_NOTIFIER_TYPE_MEMORY +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE 5:4 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_UNKNOWN ERROR_NOTIFIER_TYPE_UNKNOWN +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_NONE ERROR_NOTIFIER_TYPE_NONE +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_CTXDMA ERROR_NOTIFIER_TYPE_CTXDMA +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_ECC_ERROR_NOTIFIER_TYPE_MEMORY ERROR_NOTIFIER_TYPE_MEMORY +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_GSP_OWNED 6:6 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_GSP_OWNED_NO 0x0 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_GSP_OWNED_YES 0x1 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_UVM_OWNED 7:7 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_UVM_OWNED_NO 0x0 +#define NV_KERNELCHANNEL_ALLOC_INTERNALFLAGS_UVM_OWNED_YES 0x1 + +typedef struct rpc_rc_triggered_v17_02 +{ + NvU32 nv2080EngineType; + NvU32 chid; + NvU32 gfid; + NvU32 exceptLevel; + NvU32 exceptType; + NvU32 scope; + NvU16 partitionAttributionId; + NvU32 mmuFaultAddrLo; + NvU32 mmuFaultAddrHi; + NvU32 mmuFaultType; + NvBool bCallbackNeeded; + NvU32 rcJournalBufferSize; + NvU8 rcJournalBuffer[]; +} rpc_rc_triggered_v17_02; + +#define NV2080_CTRL_GPU_MAX_CONSTRUCTED_FALCONS 0x40 + +typedef struct NV2080_CTRL_GPU_CONSTRUCTED_FALCON_INFO { + NvU32 engDesc; + NvU32 ctxAttr; + NvU32 ctxBufferSize; + NvU32 addrSpaceList; + NvU32 registerBase; +} NV2080_CTRL_GPU_CONSTRUCTED_FALCON_INFO; + +#define NV2080_CTRL_CMD_GPU_GET_CONSTRUCTED_FALCON_INFO (0x208001b0) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_GPU_INTERFACE_ID << 8) | NV2080_CTRL_GPU_GET_CONSTRUCTED_FALCON_INFO_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_GPU_GET_CONSTRUCTED_FALCON_INFO_PARAMS { + NvU32 numConstructedFalcons; + NV2080_CTRL_GPU_CONSTRUCTED_FALCON_INFO constructedFalconsTable[NV2080_CTRL_GPU_MAX_CONSTRUCTED_FALCONS]; +} NV2080_CTRL_GPU_GET_CONSTRUCTED_FALCON_INFO_PARAMS; + +typedef struct NV2080_CTRL_CMD_INTERNAL_FIFO_TOGGLE_ACTIVE_CHANNEL_SCHEDULING_PARAMS { + NvBool bDisableActiveChannels; +} NV2080_CTRL_CMD_INTERNAL_FIFO_TOGGLE_ACTIVE_CHANNEL_SCHEDULING_PARAMS; + +#define NV2080_CTRL_CMD_INTERNAL_FIFO_TOGGLE_ACTIVE_CHANNEL_SCHEDULING (0x20800ac3) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_CMD_INTERNAL_FIFO_TOGGLE_ACTIVE_CHANNEL_SCHEDULING_PARAMS_MESSAGE_ID" */ #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gr.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gr.h new file mode 100644 index 000000000000..feed1dabd9d2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gr.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_GR_H__ +#define __NVRM_GR_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/570.144 */ + +#define NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO (0x20800a32) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO_PARAMS_MESSAGE_ID" */ + +#define NV2080_CTRL_INTERNAL_GR_MAX_ENGINES 8 + +#define NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT 0x1a + +typedef struct NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO { + NvU32 size; + NvU32 alignment; +} NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO; + +typedef struct NV2080_CTRL_INTERNAL_STATIC_GR_CONTEXT_BUFFERS_INFO { + NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO engine[NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT]; +} NV2080_CTRL_INTERNAL_STATIC_GR_CONTEXT_BUFFERS_INFO; + +typedef struct NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS { + NV2080_CTRL_INTERNAL_STATIC_GR_CONTEXT_BUFFERS_INFO engineContextBuffersInfo[NV2080_CTRL_INTERNAL_GR_MAX_ENGINES]; +} NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS; + +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID 4:0 +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS (0x00000000) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_VLD (0x00000001) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_VIDEO (0x00000002) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_MPEG (0x00000003) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_CAPTURE (0x00000004) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_DISPLAY (0x00000005) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_ENCRYPTION (0x00000006) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_POSTPROCESS (0x00000007) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_ZCULL (0x00000008) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_PM (0x00000009) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COMPUTE_PREEMPT (0x0000000a) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_PREEMPT (0x0000000b) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_SPILL (0x0000000c) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_PAGEPOOL (0x0000000d) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_BETACB (0x0000000e) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_RTV (0x0000000f) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_PATCH (0x00000010) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_BUNDLE_CB (0x00000011) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_PAGEPOOL_GLOBAL (0x00000012) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_ATTRIBUTE_CB (0x00000013) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_RTV_CB_GLOBAL (0x00000014) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_GFXP_POOL (0x00000015) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_GFXP_CTRL_BLK (0x00000016) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_FECS_EVENT (0x00000017) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_PRIV_ACCESS_MAP (0x00000018) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_SETUP (0x00000019) +#define NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT (0x0000001a) + +#define NV2080_CTRL_CMD_GPU_GET_FERMI_GPC_INFO (0x20800137U) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_GPU_INTERFACE_ID << 8) | NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS { + NvU32 gpcMask; +} NV2080_CTRL_GPU_GET_FERMI_GPC_INFO_PARAMS; + +#define NV2080_CTRL_CMD_GPU_GET_FERMI_TPC_INFO (0x20800138U) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_GPU_INTERFACE_ID << 8) | NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS_MESSAGE_ID" */ +typedef struct NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS { + NvU32 gpcId; + NvU32 tpcMask; +} NV2080_CTRL_GPU_GET_FERMI_TPC_INFO_PARAMS; + +#define KGRAPHICS_SCRUBBER_HANDLE_VAS 0xdada0042 +#define KGRAPHICS_SCRUBBER_HANDLE_CHANNEL (KGRAPHICS_SCRUBBER_HANDLE_VAS + 3) +#define KGRAPHICS_SCRUBBER_HANDLE_3DOBJ (KGRAPHICS_SCRUBBER_HANDLE_VAS + 4) + +typedef struct NV2080_CTRL_INTERNAL_GR_INIT_BUG4208224_WAR_PARAMS { + NvBool bTeardown; +} NV2080_CTRL_INTERNAL_GR_INIT_BUG4208224_WAR_PARAMS; + +#define NV2080_CTRL_CMD_INTERNAL_KGR_INIT_BUG4208224_WAR (0x20800a46) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_0_INTERNAL_INTERFACE_ID << 8) | NV2080_CTRL_INTERNAL_KGR_INIT_BUG4208224_WAR_PARAMS_MESSAGE_ID" */ +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h new file mode 100644 index 000000000000..b6075021e74f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h @@ -0,0 +1,634 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_GSP_H__ +#define __NVRM_GSP_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/570.144 */ + +#define NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MAX_ENTRIES 16U + +#define NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MEM_TYPES 17U + +typedef NvBool NV2080_CTRL_CMD_FB_GET_FB_REGION_SURFACE_MEM_TYPE_FLAG[NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MEM_TYPES]; + +typedef struct NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO { + NV_DECLARE_ALIGNED(NvU64 base, 8); + NV_DECLARE_ALIGNED(NvU64 limit, 8); + NV_DECLARE_ALIGNED(NvU64 reserved, 8); + NvU32 performance; + NvBool supportCompressed; + NvBool supportISO; + NvBool bProtected; + NV2080_CTRL_CMD_FB_GET_FB_REGION_SURFACE_MEM_TYPE_FLAG blackList; +} NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO; + +typedef struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS { + NvU32 numFBRegions; + NV_DECLARE_ALIGNED(NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO fbRegion[NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_MAX_ENTRIES], 8); +} NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS; + +#define NV0080_CTRL_GR_CAPS_TBL_SIZE 23 + +#define NV2080_GPU_MAX_GID_LENGTH (0x000000100ULL) + +typedef struct NV2080_CTRL_GPU_GET_GID_INFO_PARAMS { + NvU32 index; + NvU32 flags; + NvU32 length; + NvU8 data[NV2080_GPU_MAX_GID_LENGTH]; +} NV2080_CTRL_GPU_GET_GID_INFO_PARAMS; + +typedef struct NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS { + NvU32 BoardID; + char chipSKU[9]; + char chipSKUMod[5]; + NvU32 skuConfigVersion; + char project[5]; + char projectSKU[5]; + char CDP[6]; + char projectSKUMod[2]; + NvU32 businessCycle; +} NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS; + +#define MAX_GPC_COUNT 32 + +typedef struct NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS { + NvU32 totalVFs; + NvU32 firstVfOffset; + NvU32 vfFeatureMask; + NV_DECLARE_ALIGNED(NvU64 FirstVFBar0Address, 8); + NV_DECLARE_ALIGNED(NvU64 FirstVFBar1Address, 8); + NV_DECLARE_ALIGNED(NvU64 FirstVFBar2Address, 8); + NV_DECLARE_ALIGNED(NvU64 bar0Size, 8); + NV_DECLARE_ALIGNED(NvU64 bar1Size, 8); + NV_DECLARE_ALIGNED(NvU64 bar2Size, 8); + NvBool b64bitBar0; + NvBool b64bitBar1; + NvBool b64bitBar2; + NvBool bSriovEnabled; + NvBool bSriovHeavyEnabled; + NvBool bEmulateVFBar0TlbInvalidationRegister; + NvBool bClientRmAllocatedCtxBuffer; + NvBool bNonPowerOf2ChannelCountSupported; + NvBool bVfResizableBAR1Supported; +} NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS; + +#include "engine.h" + +#define NVGPU_ENGINE_CAPS_MASK_BITS 32 + +#define NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX ((RM_ENGINE_TYPE_LAST-1)/NVGPU_ENGINE_CAPS_MASK_BITS + 1) + +#define NV2080_GPU_MAX_NAME_STRING_LENGTH (0x0000040U) + +typedef struct VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS +{ + NvU32 numHeads; + NvU32 maxNumHeads; +} VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS; + +typedef struct VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS +{ + NvU32 headIndex; + NvU32 maxHResolution; + NvU32 maxVResolution; +} VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS; + +#define MAX_GROUP_COUNT 2 + +typedef struct +{ + NvU32 ecidLow; + NvU32 ecidHigh; + NvU32 ecidExtended; +} EcidManufacturingInfo; + +typedef struct +{ + NvU64 nonWprHeapOffset; + NvU64 frtsOffset; +} FW_WPR_LAYOUT_OFFSET; + +typedef struct GspStaticConfigInfo_t +{ + NvU8 grCapsBits[NV0080_CTRL_GR_CAPS_TBL_SIZE]; + NV2080_CTRL_GPU_GET_GID_INFO_PARAMS gidInfo; + NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS SKUInfo; + NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS fbRegionInfoParams; + + NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS sriovCaps; + NvU32 sriovMaxGfid; + + NvU32 engineCaps[NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX]; + + NvBool poisonFuseEnabled; + + NvU64 fb_length; + NvU64 fbio_mask; + NvU32 fb_bus_width; + NvU32 fb_ram_type; + NvU64 fbp_mask; + NvU32 l2_cache_size; + + NvU8 gpuNameString[NV2080_GPU_MAX_NAME_STRING_LENGTH]; + NvU8 gpuShortNameString[NV2080_GPU_MAX_NAME_STRING_LENGTH]; + NvU16 gpuNameString_Unicode[NV2080_GPU_MAX_NAME_STRING_LENGTH]; + NvBool bGpuInternalSku; + NvBool bIsQuadroGeneric; + NvBool bIsQuadroAd; + NvBool bIsNvidiaNvs; + NvBool bIsVgx; + NvBool bGeforceSmb; + NvBool bIsTitan; + NvBool bIsTesla; + NvBool bIsMobile; + NvBool bIsGc6Rtd3Allowed; + NvBool bIsGc8Rtd3Allowed; + NvBool bIsGcOffRtd3Allowed; + NvBool bIsGcoffLegacyAllowed; + NvBool bIsMigSupported; + + /* "Total Board Power" refers to power requirement of GPU, + * while in GC6 state. Majority of this power will be used + * to keep V-RAM active to preserve its content. + * Some energy maybe consumed by Always-on components on GPU chip. + * This power will be provided by 3.3v voltage rail. + */ + NvU16 RTD3GC6TotalBoardPower; + + /* PERST# (i.e. PCI Express Reset) is a sideband signal + * generated by the PCIe Host to indicate the PCIe devices, + * that the power-rails and the reference-clock are stable. + * The endpoint device typically uses this signal as a global reset. + */ + NvU16 RTD3GC6PerstDelay; + + NvU64 bar1PdeBase; + NvU64 bar2PdeBase; + + NvBool bVbiosValid; + NvU32 vbiosSubVendor; + NvU32 vbiosSubDevice; + + NvBool bPageRetirementSupported; + + NvBool bSplitVasBetweenServerClientRm; + + NvBool bClRootportNeedsNosnoopWAR; + + VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS displaylessMaxHeads; + VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS displaylessMaxResolution; + NvU64 displaylessMaxPixels; + + // Client handle for internal RMAPI control. + NvHandle hInternalClient; + + // Device handle for internal RMAPI control. + NvHandle hInternalDevice; + + // Subdevice handle for internal RMAPI control. + NvHandle hInternalSubdevice; + + NvBool bSelfHostedMode; + NvBool bAtsSupported; + + NvBool bIsGpuUefi; + NvBool bIsEfiInit; + + EcidManufacturingInfo ecidInfo[MAX_GROUP_COUNT]; + + FW_WPR_LAYOUT_OFFSET fwWprLayoutOffset; +} GspStaticConfigInfo; + +typedef struct +{ + NvU16 deviceID; // deviceID + NvU16 vendorID; // vendorID + NvU16 subdeviceID; // subsystem deviceID + NvU16 subvendorID; // subsystem vendorID + NvU8 revisionID; // revision ID +} BUSINFO; + +#define NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS (16U) + +typedef struct DOD_METHOD_DATA +{ + NV_STATUS status; + NvU32 acpiIdListLen; + NvU32 acpiIdList[NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS]; +} DOD_METHOD_DATA; + +typedef struct JT_METHOD_DATA +{ + NV_STATUS status; + NvU32 jtCaps; + NvU16 jtRevId; + NvBool bSBIOSCaps; +} JT_METHOD_DATA; + +typedef struct MUX_METHOD_DATA_ELEMENT +{ + NvU32 acpiId; + NvU32 mode; + NV_STATUS status; +} MUX_METHOD_DATA_ELEMENT; + +#define NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS (16U) + +typedef struct MUX_METHOD_DATA +{ + NvU32 tableLen; + MUX_METHOD_DATA_ELEMENT acpiIdMuxModeTable[NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS]; + MUX_METHOD_DATA_ELEMENT acpiIdMuxPartTable[NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS]; + MUX_METHOD_DATA_ELEMENT acpiIdMuxStateTable[NV0073_CTRL_SYSTEM_ACPI_ID_MAP_MAX_DISPLAYS]; +} MUX_METHOD_DATA; + +typedef struct CAPS_METHOD_DATA +{ + NV_STATUS status; + NvU32 optimusCaps; +} CAPS_METHOD_DATA; + +typedef struct ACPI_METHOD_DATA +{ + NvBool bValid; + DOD_METHOD_DATA dodMethodData; + JT_METHOD_DATA jtMethodData; + MUX_METHOD_DATA muxMethodData; + CAPS_METHOD_DATA capsMethodData; +} ACPI_METHOD_DATA; + +typedef struct GSP_VF_INFO +{ + NvU32 totalVFs; + NvU32 firstVFOffset; + NvU64 FirstVFBar0Address; + NvU64 FirstVFBar1Address; + NvU64 FirstVFBar2Address; + NvBool b64bitBar0; + NvBool b64bitBar1; + NvBool b64bitBar2; +} GSP_VF_INFO; + +typedef struct +{ + // Link capabilities + NvU32 linkCap; +} GSP_PCIE_CONFIG_REG; + +typedef struct GspSystemInfo +{ + NvU64 gpuPhysAddr; + NvU64 gpuPhysFbAddr; + NvU64 gpuPhysInstAddr; + NvU64 gpuPhysIoAddr; + NvU64 nvDomainBusDeviceFunc; + NvU64 simAccessBufPhysAddr; + NvU64 notifyOpSharedSurfacePhysAddr; + NvU64 pcieAtomicsOpMask; + NvU64 consoleMemSize; + NvU64 maxUserVa; + NvU32 pciConfigMirrorBase; + NvU32 pciConfigMirrorSize; + NvU32 PCIDeviceID; + NvU32 PCISubDeviceID; + NvU32 PCIRevisionID; + NvU32 pcieAtomicsCplDeviceCapMask; + NvU8 oorArch; + NvU64 clPdbProperties; + NvU32 Chipset; + NvBool bGpuBehindBridge; + NvBool bFlrSupported; + NvBool b64bBar0Supported; + NvBool bMnocAvailable; + NvU32 chipsetL1ssEnable; + NvBool bUpstreamL0sUnsupported; + NvBool bUpstreamL1Unsupported; + NvBool bUpstreamL1PorSupported; + NvBool bUpstreamL1PorMobileOnly; + NvBool bSystemHasMux; + NvU8 upstreamAddressValid; + BUSINFO FHBBusInfo; + BUSINFO chipsetIDInfo; + ACPI_METHOD_DATA acpiMethodData; + NvU32 hypervisorType; + NvBool bIsPassthru; + NvU64 sysTimerOffsetNs; + GSP_VF_INFO gspVFInfo; + NvBool bIsPrimary; + NvBool isGridBuild; + GSP_PCIE_CONFIG_REG pcieConfigReg; + NvU32 gridBuildCsp; + NvBool bPreserveVideoMemoryAllocations; + NvBool bTdrEventSupported; + NvBool bFeatureStretchVblankCapable; + NvBool bEnableDynamicGranularityPageArrays; + NvBool bClockBoostSupported; + NvBool bRouteDispIntrsToCPU; + NvU64 hostPageSize; +} GspSystemInfo; + +typedef struct rpc_os_error_log_v17_00 +{ + NvU32 exceptType; + NvU32 runlistId; + NvU32 chid; + char errString[0x100]; + NvU32 preemptiveRemovalPreviousXid; +} rpc_os_error_log_v17_00; + +typedef struct +{ + // Magic + // BL to use for verification (i.e. Booter locked it in WPR2) + NvU64 magic; // = 0xdc3aae21371a60b3; + + // Revision number of Booter-BL-Sequencer handoff interface + // Bumped up when we change this interface so it is not backward compatible. + // Bumped up when we revoke GSP-RM ucode + NvU64 revision; // = 1; + + // ---- Members regarding data in SYSMEM ---------------------------- + // Consumed by Booter for DMA + + NvU64 sysmemAddrOfRadix3Elf; + NvU64 sizeOfRadix3Elf; + + NvU64 sysmemAddrOfBootloader; + NvU64 sizeOfBootloader; + + // Offsets inside bootloader image needed by Booter + NvU64 bootloaderCodeOffset; + NvU64 bootloaderDataOffset; + NvU64 bootloaderManifestOffset; + + union + { + // Used only at initial boot + struct + { + NvU64 sysmemAddrOfSignature; + NvU64 sizeOfSignature; + }; + + // + // Used at suspend/resume to read GspFwHeapFreeList + // Offset relative to GspFwWprMeta FBMEM PA (gspFwWprStart) + // + struct + { + NvU32 gspFwHeapFreeListWprOffset; + NvU32 unused0; + NvU64 unused1; + }; + }; + + // ---- Members describing FB layout -------------------------------- + NvU64 gspFwRsvdStart; + + NvU64 nonWprHeapOffset; + NvU64 nonWprHeapSize; + + NvU64 gspFwWprStart; + + // GSP-RM to use to setup heap. + NvU64 gspFwHeapOffset; + NvU64 gspFwHeapSize; + + // BL to use to find ELF for jump + NvU64 gspFwOffset; + // Size is sizeOfRadix3Elf above. + + NvU64 bootBinOffset; + // Size is sizeOfBootloader above. + + NvU64 frtsOffset; + NvU64 frtsSize; + + NvU64 gspFwWprEnd; + + // GSP-RM to use for fbRegionInfo? + NvU64 fbSize; + + // ---- Other members ----------------------------------------------- + + // GSP-RM to use for fbRegionInfo? + NvU64 vgaWorkspaceOffset; + NvU64 vgaWorkspaceSize; + + // Boot count. Used to determine whether to load the firmware image. + NvU64 bootCount; + + // This union is organized the way it is to start at an 8-byte boundary and achieve natural + // packing of the internal struct fields. + union + { + struct + { + // TODO: the partitionRpc* fields below do not really belong in this + // structure. The values are patched in by the partition bootstrapper + // when GSP-RM is booted in a partition, and this structure was a + // convenient place for the bootstrapper to access them. These should + // be moved to a different comm. mechanism between the bootstrapper + // and the GSP-RM tasks. + + // Shared partition RPC memory (physical address) + NvU64 partitionRpcAddr; + + // Offsets relative to partitionRpcAddr + NvU16 partitionRpcRequestOffset; + NvU16 partitionRpcReplyOffset; + + // Code section and dataSection offset and size. + NvU32 elfCodeOffset; + NvU32 elfDataOffset; + NvU32 elfCodeSize; + NvU32 elfDataSize; + + // Used during GSP-RM resume to check for revocation + NvU32 lsUcodeVersion; + }; + + struct + { + // Pad for the partitionRpc* fields, plus 4 bytes + NvU32 partitionRpcPadding[4]; + + // CrashCat (contiguous) buffer size/location - occupies same bytes as the + // elf(Code|Data)(Offset|Size) fields above. + // TODO: move to GSP_FMC_INIT_PARAMS + NvU64 sysmemAddrOfCrashReportQueue; + NvU32 sizeOfCrashReportQueue; + + // Pad for the lsUcodeVersion field + NvU32 lsUcodeVersionPadding[1]; + }; + }; + + // Number of VF partitions allocating sub-heaps from the WPR heap + // Used during boot to ensure the heap is adequately sized + NvU8 gspFwHeapVfPartitionCount; + + // Flags to help decide GSP-FW flow. + NvU8 flags; + + // Pad structure to exactly 256 bytes. Can replace padding with additional + // fields without incrementing revision. Padding initialized to 0. + NvU8 padding[2]; + + // + // Starts at gspFwWprEnd+frtsSize b/c FRTS is positioned + // to end where this allocation starts (when RM requests FSP to create + // FRTS). + // + NvU32 pmuReservedSize; + + // BL to use for verification (i.e. Booter says OK to boot) + NvU64 verified; // 0x0 -> unverified, 0xa0a0a0a0a0a0a0a0 -> verified +} GspFwWprMeta; + +#define GSP_FW_WPR_META_MAGIC 0xdc3aae21371a60b3ULL + +#define GSP_FW_WPR_META_REVISION 1 + +typedef struct { + NvU64 sharedMemPhysAddr; + NvU32 pageTableEntryCount; + NvLength cmdQueueOffset; + NvLength statQueueOffset; +} MESSAGE_QUEUE_INIT_ARGUMENTS; + +typedef struct { + NvU32 oldLevel; + NvU32 flags; + NvBool bInPMTransition; +} GSP_SR_INIT_ARGUMENTS; + +typedef struct +{ + MESSAGE_QUEUE_INIT_ARGUMENTS messageQueueInitArguments; + GSP_SR_INIT_ARGUMENTS srInitArguments; + NvU32 gpuInstance; + NvBool bDmemStack; + + struct + { + NvU64 pa; + NvU64 size; + } profilerArgs; +} GSP_ARGUMENTS_CACHED; + +#define NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3 (0x00000003U) + +typedef struct +{ + // Magic for verification by secure ucode + NvU64 magic; // = GSP_FW_SR_META_MAGIC; + + // + // Revision number + // Bumped up when we change this interface so it is not backward compatible. + // + NvU64 revision; // = GSP_FW_SR_META_MAGIC_REVISION; + + // Members regarding data in SYSMEM + NvU64 sysmemAddrOfSuspendResumeData; + NvU64 sizeOfSuspendResumeData; + + // + // Internal members for use by secure ucode + // Must be exactly GSP_FW_SR_META_INTERNAL_SIZE bytes. + // + NvU32 internal[32]; + + // Same as flags of GspFwWprMeta + NvU32 flags; + + // Subrevision number used by secure ucode + NvU32 subrevision; + + // + // Pad structure to exactly 256 bytes (1 DMA chunk). + // Padding initialized to zero. + // + NvU32 padding[22]; +} GspFwSRMeta; + +#define GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2 (0 << 20) // No FB heap usage + +#define GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BAREMETAL (22 << 20) + +#define GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X (8 << 20) // Turing thru Ada + +#define GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB (64u) + +#define BULLSEYE_ROOT_HEAP_ALLOC_RM_DATA_SECTION_SIZE_DELTA (12u) + +#define BULLSEYE_ROOT_HEAP_ALLOC_BAREMETAL_LIBOS_HEAP_SIZE_DELTA (70u) + +#define GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB \ + (88u + (BULLSEYE_ROOT_HEAP_ALLOC_RM_DATA_SECTION_SIZE_DELTA) + \ + (BULLSEYE_ROOT_HEAP_ALLOC_BAREMETAL_LIBOS_HEAP_SIZE_DELTA)) + +typedef struct GSP_FMC_INIT_PARAMS +{ + // CC initialization "registry keys" + NvU32 regkeys; +} GSP_FMC_INIT_PARAMS; + +typedef enum { + GSP_DMA_TARGET_LOCAL_FB, + GSP_DMA_TARGET_COHERENT_SYSTEM, + GSP_DMA_TARGET_NONCOHERENT_SYSTEM, + GSP_DMA_TARGET_COUNT +} GSP_DMA_TARGET; + +typedef struct GSP_ACR_BOOT_GSP_RM_PARAMS +{ + // Physical memory aperture through which gspRmDescPa is accessed + GSP_DMA_TARGET target; + // Size in bytes of the GSP-RM descriptor structure + NvU32 gspRmDescSize; + // Physical offset in the target aperture of the GSP-RM descriptor structure + NvU64 gspRmDescOffset; + // Physical offset in FB to set the start of the WPR containing GSP-RM + NvU64 wprCarveoutOffset; + // Size in bytes of the WPR containing GSP-RM + NvU32 wprCarveoutSize; + // Whether to boot GSP-RM or GSP-Proxy through ACR + NvBool bIsGspRmBoot; +} GSP_ACR_BOOT_GSP_RM_PARAMS; + +typedef struct GSP_RM_PARAMS +{ + // Physical memory aperture through which bootArgsOffset is accessed + GSP_DMA_TARGET target; + // Physical offset in the memory aperture that will be passed to GSP-RM + NvU64 bootArgsOffset; +} GSP_RM_PARAMS; + +typedef struct GSP_SPDM_PARAMS +{ + // Physical Memory Aperture through which all addresses are accessed + GSP_DMA_TARGET target; + + // Physical offset in the memory aperture where SPDM payload is stored + NvU64 payloadBufferOffset; + + // Size of the above payload buffer + NvU32 payloadBufferSize; +} GSP_SPDM_PARAMS; + +typedef struct GSP_FMC_BOOT_PARAMS +{ + GSP_FMC_INIT_PARAMS initParams; + GSP_ACR_BOOT_GSP_RM_PARAMS bootGspRmParams; + GSP_RM_PARAMS gspRmParams; + GSP_SPDM_PARAMS gspSpdmParams; +} GSP_FMC_BOOT_PARAMS; + +#define GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100 (14 << 20) // Hopper+ +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/msgfn.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/msgfn.h new file mode 100644 index 000000000000..e06643f57695 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/msgfn.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_MSGFN_H__ +#define __NVRM_MSGFN_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/570.144 */ + +#ifndef E +# define E(RPC, VAL) NV_VGPU_MSG_EVENT_##RPC = VAL, +# define DEFINING_E_IN_RPC_GLOBAL_ENUMS_H +enum { +#endif + E(FIRST_EVENT, 0x1000) + E(GSP_INIT_DONE, 0x1001) + E(GSP_RUN_CPU_SEQUENCER, 0x1002) + E(POST_EVENT, 0x1003) + E(RC_TRIGGERED, 0x1004) + E(MMU_FAULT_QUEUED, 0x1005) + E(OS_ERROR_LOG, 0x1006) + E(RG_LINE_INTR, 0x1007) + E(GPUACCT_PERFMON_UTIL_SAMPLES, 0x1008) + E(SIM_READ, 0x1009) + E(SIM_WRITE, 0x100a) + E(SEMAPHORE_SCHEDULE_CALLBACK, 0x100b) + E(UCODE_LIBOS_PRINT, 0x100c) + E(VGPU_GSP_PLUGIN_TRIGGERED, 0x100d) + E(PERF_GPU_BOOST_SYNC_LIMITS_CALLBACK, 0x100e) + E(PERF_BRIDGELESS_INFO_UPDATE, 0x100f) + E(VGPU_CONFIG, 0x1010) + E(DISPLAY_MODESET, 0x1011) + E(EXTDEV_INTR_SERVICE, 0x1012) + E(NVLINK_INBAND_RECEIVED_DATA_256, 0x1013) + E(NVLINK_INBAND_RECEIVED_DATA_512, 0x1014) + E(NVLINK_INBAND_RECEIVED_DATA_1024, 0x1015) + E(NVLINK_INBAND_RECEIVED_DATA_2048, 0x1016) + E(NVLINK_INBAND_RECEIVED_DATA_4096, 0x1017) + E(TIMED_SEMAPHORE_RELEASE, 0x1018) + E(NVLINK_IS_GPU_DEGRADED, 0x1019) + E(PFM_REQ_HNDLR_STATE_SYNC_CALLBACK, 0x101a) + E(NVLINK_FAULT_UP, 0x101b) + E(GSP_LOCKDOWN_NOTICE, 0x101c) + E(MIG_CI_CONFIG_UPDATE, 0x101d) + E(UPDATE_GSP_TRACE, 0x101e) + E(NVLINK_FATAL_ERROR_RECOVERY, 0x101f) + E(GSP_POST_NOCAT_RECORD, 0x1020) + E(FECS_ERROR, 0x1021) + E(RECOVERY_ACTION, 0x1022) + E(NUM_EVENTS, 0x1023) +#ifdef DEFINING_E_IN_RPC_GLOBAL_ENUMS_H +}; +# undef E +# undef DEFINING_E_IN_RPC_GLOBAL_ENUMS_H +#endif +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/ofa.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/ofa.h new file mode 100644 index 000000000000..fcaef7f553a6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/ofa.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_OFA_H__ +#define __NVRM_OFA_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/570.144 */ + +typedef struct +{ + NvU32 size; + NvU32 prohibitMultipleInstances; // Prohibit multiple allocations of OFA? + NvU32 engineInstance; +} NV_OFA_ALLOCATION_PARAMETERS; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/rpcfn.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/rpcfn.h new file mode 100644 index 000000000000..2d67b598c58b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/rpcfn.h @@ -0,0 +1,249 @@ +/* SPDX-License-Identifier: MIT */ + +/* Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. */ + +#ifndef __NVRM_RPCFN_H__ +#define __NVRM_RPCFN_H__ +#include <nvrm/nvtypes.h> + +/* Excerpt of RM headers from https://github.com/NVIDIA/open-gpu-kernel-modules/tree/570.144 */ + +#ifndef X +# define X(UNIT, RPC, VAL) NV_VGPU_MSG_FUNCTION_##RPC = VAL, +# define DEFINING_X_IN_RPC_GLOBAL_ENUMS_H +enum { +#endif + X(RM, NOP, 0) + X(RM, SET_GUEST_SYSTEM_INFO, 1) + X(RM, ALLOC_ROOT, 2) + X(RM, ALLOC_DEVICE, 3) // deprecated + X(RM, ALLOC_MEMORY, 4) + X(RM, ALLOC_CTX_DMA, 5) + X(RM, ALLOC_CHANNEL_DMA, 6) + X(RM, MAP_MEMORY, 7) + X(RM, BIND_CTX_DMA, 8) // deprecated + X(RM, ALLOC_OBJECT, 9) + X(RM, FREE, 10) + X(RM, LOG, 11) + X(RM, ALLOC_VIDMEM, 12) + X(RM, UNMAP_MEMORY, 13) + X(RM, MAP_MEMORY_DMA, 14) + X(RM, UNMAP_MEMORY_DMA, 15) + X(RM, GET_EDID, 16) // deprecated + X(RM, ALLOC_DISP_CHANNEL, 17) + X(RM, ALLOC_DISP_OBJECT, 18) + X(RM, ALLOC_SUBDEVICE, 19) + X(RM, ALLOC_DYNAMIC_MEMORY, 20) + X(RM, DUP_OBJECT, 21) + X(RM, IDLE_CHANNELS, 22) + X(RM, ALLOC_EVENT, 23) + X(RM, SEND_EVENT, 24) // deprecated + X(RM, REMAPPER_CONTROL, 25) // deprecated + X(RM, DMA_CONTROL, 26) // deprecated + X(RM, DMA_FILL_PTE_MEM, 27) + X(RM, MANAGE_HW_RESOURCE, 28) + X(RM, BIND_ARBITRARY_CTX_DMA, 29) // deprecated + X(RM, CREATE_FB_SEGMENT, 30) + X(RM, DESTROY_FB_SEGMENT, 31) + X(RM, ALLOC_SHARE_DEVICE, 32) + X(RM, DEFERRED_API_CONTROL, 33) + X(RM, REMOVE_DEFERRED_API, 34) + X(RM, SIM_ESCAPE_READ, 35) + X(RM, SIM_ESCAPE_WRITE, 36) + X(RM, SIM_MANAGE_DISPLAY_CONTEXT_DMA, 37) + X(RM, FREE_VIDMEM_VIRT, 38) + X(RM, PERF_GET_PSTATE_INFO, 39) // deprecated + X(RM, PERF_GET_PERFMON_SAMPLE, 40) + X(RM, PERF_GET_VIRTUAL_PSTATE_INFO, 41) // deprecated + X(RM, PERF_GET_LEVEL_INFO, 42) + X(RM, MAP_SEMA_MEMORY, 43) + X(RM, UNMAP_SEMA_MEMORY, 44) + X(RM, SET_SURFACE_PROPERTIES, 45) + X(RM, CLEANUP_SURFACE, 46) + X(RM, UNLOADING_GUEST_DRIVER, 47) + X(RM, TDR_SET_TIMEOUT_STATE, 48) + X(RM, SWITCH_TO_VGA, 49) + X(RM, GPU_EXEC_REG_OPS, 50) + X(RM, GET_STATIC_INFO, 51) + X(RM, ALLOC_VIRTMEM, 52) + X(RM, UPDATE_PDE_2, 53) + X(RM, SET_PAGE_DIRECTORY, 54) + X(RM, GET_STATIC_PSTATE_INFO, 55) + X(RM, TRANSLATE_GUEST_GPU_PTES, 56) + X(RM, RESERVED_57, 57) + X(RM, RESET_CURRENT_GR_CONTEXT, 58) + X(RM, SET_SEMA_MEM_VALIDATION_STATE, 59) + X(RM, GET_ENGINE_UTILIZATION, 60) + X(RM, UPDATE_GPU_PDES, 61) + X(RM, GET_ENCODER_CAPACITY, 62) + X(RM, VGPU_PF_REG_READ32, 63) // deprecated + X(RM, SET_GUEST_SYSTEM_INFO_EXT, 64) + X(GSP, GET_GSP_STATIC_INFO, 65) + X(RM, RMFS_INIT, 66) // deprecated + X(RM, RMFS_CLOSE_QUEUE, 67) // deprecated + X(RM, RMFS_CLEANUP, 68) // deprecated + X(RM, RMFS_TEST, 69) // deprecated + X(RM, UPDATE_BAR_PDE, 70) + X(RM, CONTINUATION_RECORD, 71) + X(RM, GSP_SET_SYSTEM_INFO, 72) + X(RM, SET_REGISTRY, 73) + X(GSP, GSP_INIT_POST_OBJGPU, 74) // deprecated + X(RM, SUBDEV_EVENT_SET_NOTIFICATION, 75) // deprecated + X(GSP, GSP_RM_CONTROL, 76) + X(RM, GET_STATIC_INFO2, 77) + X(RM, DUMP_PROTOBUF_COMPONENT, 78) + X(RM, UNSET_PAGE_DIRECTORY, 79) + X(RM, GET_CONSOLIDATED_STATIC_INFO, 80) // deprecated + X(RM, GMMU_REGISTER_FAULT_BUFFER, 81) // deprecated + X(RM, GMMU_UNREGISTER_FAULT_BUFFER, 82) // deprecated + X(RM, GMMU_REGISTER_CLIENT_SHADOW_FAULT_BUFFER, 83) // deprecated + X(RM, GMMU_UNREGISTER_CLIENT_SHADOW_FAULT_BUFFER, 84) // deprecated + X(RM, CTRL_SET_VGPU_FB_USAGE, 85) + X(RM, CTRL_NVFBC_SW_SESSION_UPDATE_INFO, 86) + X(RM, CTRL_NVENC_SW_SESSION_UPDATE_INFO, 87) + X(RM, CTRL_RESET_CHANNEL, 88) + X(RM, CTRL_RESET_ISOLATED_CHANNEL, 89) + X(RM, CTRL_GPU_HANDLE_VF_PRI_FAULT, 90) + X(RM, CTRL_CLK_GET_EXTENDED_INFO, 91) + X(RM, CTRL_PERF_BOOST, 92) + X(RM, CTRL_PERF_VPSTATES_GET_CONTROL, 93) + X(RM, CTRL_GET_ZBC_CLEAR_TABLE, 94) + X(RM, CTRL_SET_ZBC_COLOR_CLEAR, 95) + X(RM, CTRL_SET_ZBC_DEPTH_CLEAR, 96) + X(RM, CTRL_GPFIFO_SCHEDULE, 97) + X(RM, CTRL_SET_TIMESLICE, 98) + X(RM, CTRL_PREEMPT, 99) + X(RM, CTRL_FIFO_DISABLE_CHANNELS, 100) + X(RM, CTRL_SET_TSG_INTERLEAVE_LEVEL, 101) + X(RM, CTRL_SET_CHANNEL_INTERLEAVE_LEVEL, 102) + X(GSP, GSP_RM_ALLOC, 103) + X(RM, CTRL_GET_P2P_CAPS_V2, 104) + X(RM, CTRL_CIPHER_AES_ENCRYPT, 105) + X(RM, CTRL_CIPHER_SESSION_KEY, 106) + X(RM, CTRL_CIPHER_SESSION_KEY_STATUS, 107) + X(RM, CTRL_DBG_CLEAR_ALL_SM_ERROR_STATES, 108) + X(RM, CTRL_DBG_READ_ALL_SM_ERROR_STATES, 109) + X(RM, CTRL_DBG_SET_EXCEPTION_MASK, 110) + X(RM, CTRL_GPU_PROMOTE_CTX, 111) + X(RM, CTRL_GR_CTXSW_PREEMPTION_BIND, 112) + X(RM, CTRL_GR_SET_CTXSW_PREEMPTION_MODE, 113) + X(RM, CTRL_GR_CTXSW_ZCULL_BIND, 114) + X(RM, CTRL_GPU_INITIALIZE_CTX, 115) + X(RM, CTRL_VASPACE_COPY_SERVER_RESERVED_PDES, 116) + X(RM, CTRL_FIFO_CLEAR_FAULTED_BIT, 117) + X(RM, CTRL_GET_LATEST_ECC_ADDRESSES, 118) + X(RM, CTRL_MC_SERVICE_INTERRUPTS, 119) + X(RM, CTRL_DMA_SET_DEFAULT_VASPACE, 120) + X(RM, CTRL_GET_CE_PCE_MASK, 121) + X(RM, CTRL_GET_ZBC_CLEAR_TABLE_ENTRY, 122) + X(RM, CTRL_GET_NVLINK_PEER_ID_MASK, 123) // deprecated + X(RM, CTRL_GET_NVLINK_STATUS, 124) + X(RM, CTRL_GET_P2P_CAPS, 125) + X(RM, CTRL_GET_P2P_CAPS_MATRIX, 126) + X(RM, RESERVED_0, 127) + X(RM, CTRL_RESERVE_PM_AREA_SMPC, 128) + X(RM, CTRL_RESERVE_HWPM_LEGACY, 129) + X(RM, CTRL_B0CC_EXEC_REG_OPS, 130) + X(RM, CTRL_BIND_PM_RESOURCES, 131) + X(RM, CTRL_DBG_SUSPEND_CONTEXT, 132) + X(RM, CTRL_DBG_RESUME_CONTEXT, 133) + X(RM, CTRL_DBG_EXEC_REG_OPS, 134) + X(RM, CTRL_DBG_SET_MODE_MMU_DEBUG, 135) + X(RM, CTRL_DBG_READ_SINGLE_SM_ERROR_STATE, 136) + X(RM, CTRL_DBG_CLEAR_SINGLE_SM_ERROR_STATE, 137) + X(RM, CTRL_DBG_SET_MODE_ERRBAR_DEBUG, 138) + X(RM, CTRL_DBG_SET_NEXT_STOP_TRIGGER_TYPE, 139) + X(RM, CTRL_ALLOC_PMA_STREAM, 140) + X(RM, CTRL_PMA_STREAM_UPDATE_GET_PUT, 141) + X(RM, CTRL_FB_GET_INFO_V2, 142) + X(RM, CTRL_FIFO_SET_CHANNEL_PROPERTIES, 143) + X(RM, CTRL_GR_GET_CTX_BUFFER_INFO, 144) + X(RM, CTRL_KGR_GET_CTX_BUFFER_PTES, 145) + X(RM, CTRL_GPU_EVICT_CTX, 146) + X(RM, CTRL_FB_GET_FS_INFO, 147) + X(RM, CTRL_GRMGR_GET_GR_FS_INFO, 148) + X(RM, CTRL_STOP_CHANNEL, 149) + X(RM, CTRL_GR_PC_SAMPLING_MODE, 150) + X(RM, CTRL_PERF_RATED_TDP_GET_STATUS, 151) + X(RM, CTRL_PERF_RATED_TDP_SET_CONTROL, 152) + X(RM, CTRL_FREE_PMA_STREAM, 153) + X(RM, CTRL_TIMER_SET_GR_TICK_FREQ, 154) + X(RM, CTRL_FIFO_SETUP_VF_ZOMBIE_SUBCTX_PDB, 155) + X(RM, GET_CONSOLIDATED_GR_STATIC_INFO, 156) + X(RM, CTRL_DBG_SET_SINGLE_SM_SINGLE_STEP, 157) + X(RM, CTRL_GR_GET_TPC_PARTITION_MODE, 158) + X(RM, CTRL_GR_SET_TPC_PARTITION_MODE, 159) + X(UVM, UVM_PAGING_CHANNEL_ALLOCATE, 160) + X(UVM, UVM_PAGING_CHANNEL_DESTROY, 161) + X(UVM, UVM_PAGING_CHANNEL_MAP, 162) + X(UVM, UVM_PAGING_CHANNEL_UNMAP, 163) + X(UVM, UVM_PAGING_CHANNEL_PUSH_STREAM, 164) + X(UVM, UVM_PAGING_CHANNEL_SET_HANDLES, 165) + X(UVM, UVM_METHOD_STREAM_GUEST_PAGES_OPERATION, 166) + X(RM, CTRL_INTERNAL_QUIESCE_PMA_CHANNEL, 167) + X(RM, DCE_RM_INIT, 168) + X(RM, REGISTER_VIRTUAL_EVENT_BUFFER, 169) + X(RM, CTRL_EVENT_BUFFER_UPDATE_GET, 170) + X(RM, GET_PLCABLE_ADDRESS_KIND, 171) + X(RM, CTRL_PERF_LIMITS_SET_STATUS_V2, 172) + X(RM, CTRL_INTERNAL_SRIOV_PROMOTE_PMA_STREAM, 173) + X(RM, CTRL_GET_MMU_DEBUG_MODE, 174) + X(RM, CTRL_INTERNAL_PROMOTE_FAULT_METHOD_BUFFERS, 175) + X(RM, CTRL_FLCN_GET_CTX_BUFFER_SIZE, 176) + X(RM, CTRL_FLCN_GET_CTX_BUFFER_INFO, 177) + X(RM, DISABLE_CHANNELS, 178) + X(RM, CTRL_FABRIC_MEMORY_DESCRIBE, 179) + X(RM, CTRL_FABRIC_MEM_STATS, 180) + X(RM, SAVE_HIBERNATION_DATA, 181) + X(RM, RESTORE_HIBERNATION_DATA, 182) + X(RM, CTRL_INTERNAL_MEMSYS_SET_ZBC_REFERENCED, 183) + X(RM, CTRL_EXEC_PARTITIONS_CREATE, 184) + X(RM, CTRL_EXEC_PARTITIONS_DELETE, 185) + X(RM, CTRL_GPFIFO_GET_WORK_SUBMIT_TOKEN, 186) + X(RM, CTRL_GPFIFO_SET_WORK_SUBMIT_TOKEN_NOTIF_INDEX, 187) + X(RM, PMA_SCRUBBER_SHARED_BUFFER_GUEST_PAGES_OPERATION, 188) + X(RM, CTRL_MASTER_GET_VIRTUAL_FUNCTION_ERROR_CONT_INTR_MASK, 189) + X(RM, SET_SYSMEM_DIRTY_PAGE_TRACKING_BUFFER, 190) + X(RM, CTRL_SUBDEVICE_GET_P2P_CAPS, 191) + X(RM, CTRL_BUS_SET_P2P_MAPPING, 192) + X(RM, CTRL_BUS_UNSET_P2P_MAPPING, 193) + X(RM, CTRL_FLA_SETUP_INSTANCE_MEM_BLOCK, 194) + X(RM, CTRL_GPU_MIGRATABLE_OPS, 195) + X(RM, CTRL_GET_TOTAL_HS_CREDITS, 196) + X(RM, CTRL_GET_HS_CREDITS, 197) + X(RM, CTRL_SET_HS_CREDITS, 198) + X(RM, CTRL_PM_AREA_PC_SAMPLER, 199) + X(RM, INVALIDATE_TLB, 200) + X(RM, CTRL_GPU_QUERY_ECC_STATUS, 201) // deprecated + X(RM, ECC_NOTIFIER_WRITE_ACK, 202) + X(RM, CTRL_DBG_GET_MODE_MMU_DEBUG, 203) + X(RM, RM_API_CONTROL, 204) + X(RM, CTRL_CMD_INTERNAL_GPU_START_FABRIC_PROBE, 205) + X(RM, CTRL_NVLINK_GET_INBAND_RECEIVED_DATA, 206) + X(RM, GET_STATIC_DATA, 207) + X(RM, RESERVED_208, 208) + X(RM, CTRL_GPU_GET_INFO_V2, 209) + X(RM, GET_BRAND_CAPS, 210) + X(RM, CTRL_CMD_NVLINK_INBAND_SEND_DATA, 211) + X(RM, UPDATE_GPM_GUEST_BUFFER_INFO, 212) + X(RM, CTRL_CMD_INTERNAL_CONTROL_GSP_TRACE, 213) + X(RM, CTRL_SET_ZBC_STENCIL_CLEAR, 214) + X(RM, CTRL_SUBDEVICE_GET_VGPU_HEAP_STATS, 215) + X(RM, CTRL_SUBDEVICE_GET_LIBOS_HEAP_STATS, 216) + X(RM, CTRL_DBG_SET_MODE_MMU_GCC_DEBUG, 217) + X(RM, CTRL_DBG_GET_MODE_MMU_GCC_DEBUG, 218) + X(RM, CTRL_RESERVE_HES, 219) + X(RM, CTRL_RELEASE_HES, 220) + X(RM, CTRL_RESERVE_CCU_PROF, 221) + X(RM, CTRL_RELEASE_CCU_PROF, 222) + X(RM, RESERVED, 223) + X(RM, CTRL_CMD_GET_CHIPLET_HS_CREDIT_POOL, 224) + X(RM, CTRL_CMD_GET_HS_CREDITS_MAPPING, 225) + X(RM, CTRL_EXEC_PARTITIONS_EXPORT, 226) + X(RM, NUM_FUNCTIONS, 227) +#ifdef DEFINING_X_IN_RPC_GLOBAL_ENUMS_H +}; +# undef X +# undef DEFINING_X_IN_RPC_GLOBAL_ENUMS_H +#endif +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/ofa.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/ofa.c new file mode 100644 index 000000000000..6fb3083edde3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/ofa.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <rm/engine.h> + +#include "nvrm/ofa.h" + +static int +r570_ofa_alloc(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, int inst, + struct nvkm_gsp_object *ofa) +{ + NV_OFA_ALLOCATION_PARAMETERS *args; + + args = nvkm_gsp_rm_alloc_get(parent, handle, oclass, sizeof(*args), ofa); + if (WARN_ON(IS_ERR(args))) + return PTR_ERR(args); + + args->size = sizeof(*args); + args->engineInstance = inst; + + return nvkm_gsp_rm_alloc_wr(ofa, args); +} + +const struct nvkm_rm_api_engine +r570_ofa = { + .alloc = r570_ofa_alloc, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c new file mode 100644 index 000000000000..498658d0c60c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <rm/rm.h> + +#include "nvrm/gsp.h" + +static const struct nvkm_rm_wpr +r570_wpr_libos2 = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB, +}; + +static const struct nvkm_rm_wpr +r570_wpr_libos3 = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BAREMETAL, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, +}; + +static const struct nvkm_rm_wpr +r570_wpr_libos3_gh100 = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BAREMETAL, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, + .heap_size_non_wpr = 0x200000, + .offset_set_by_acr = true, +}; + +static const struct nvkm_rm_wpr +r570_wpr_libos3_gb10x = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BAREMETAL, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, + .heap_size_non_wpr = 0x200000, + .rsvd_size_pmu = ALIGN(0x0800000 + 0x1000000 + 0x0001000, 0x20000), + .offset_set_by_acr = true, +}; + +static const struct nvkm_rm_wpr +r570_wpr_libos3_gb20x = { + .os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS3_BAREMETAL, + .base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_GH100, + .heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS3_BAREMETAL_MIN_MB, + .heap_size_non_wpr = 0x220000, + .rsvd_size_pmu = ALIGN(0x0800000 + 0x1000000 + 0x0001000, 0x20000), + .offset_set_by_acr = true, +}; + +static const struct nvkm_rm_api +r570_api = { + .gsp = &r570_gsp, + .rpc = &r535_rpc, + .ctrl = &r535_ctrl, + .alloc = &r535_alloc, + .client = &r570_client, + .device = &r535_device, + .fbsr = &r570_fbsr, + .disp = &r570_disp, + .fifo = &r570_fifo, + .ce = &r535_ce, + .gr = &r570_gr, + .nvdec = &r535_nvdec, + .nvenc = &r535_nvenc, + .nvjpg = &r535_nvjpg, + .ofa = &r570_ofa, +}; + +const struct nvkm_rm_impl +r570_rm_tu102 = { + .wpr = &r570_wpr_libos2, + .api = &r570_api, +}; + +const struct nvkm_rm_impl +r570_rm_ga102 = { + .wpr = &r570_wpr_libos3, + .api = &r570_api, +}; + +const struct nvkm_rm_impl +r570_rm_gh100 = { + .wpr = &r570_wpr_libos3_gh100, + .api = &r570_api, +}; + +const struct nvkm_rm_impl +r570_rm_gb10x = { + .wpr = &r570_wpr_libos3_gb10x, + .api = &r570_api, +}; + +const struct nvkm_rm_impl +r570_rm_gb20x = { + .wpr = &r570_wpr_libos3_gb20x, + .api = &r570_api, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h new file mode 100644 index 000000000000..393ea775941f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include <subdev/gsp.h> +#ifndef __NVKM_RM_H__ +#define __NVKM_RM_H__ +#include "handles.h" +struct nvkm_outp; +struct r535_gr; + +struct nvkm_rm_impl { + const struct nvkm_rm_wpr *wpr; + const struct nvkm_rm_api *api; +}; + +struct nvkm_rm { + struct nvkm_device *device; + const struct nvkm_rm_gpu *gpu; + const struct nvkm_rm_wpr *wpr; + const struct nvkm_rm_api *api; +}; + +struct nvkm_rm_wpr { + u32 os_carveout_size; + u32 base_size; + u64 heap_size_min; + u32 heap_size_non_wpr; + u32 rsvd_size_pmu; + bool offset_set_by_acr; +}; + +struct nvkm_rm_api { + const struct nvkm_rm_api_gsp { + void (*set_rmargs)(struct nvkm_gsp *, bool resume); + int (*set_system_info)(struct nvkm_gsp *); + int (*get_static_info)(struct nvkm_gsp *); + bool (*xlat_mc_engine_idx)(u32 mc_engine_idx, enum nvkm_subdev_type *, int *inst); + void (*drop_send_user_shared_data)(struct nvkm_gsp *); + void (*drop_post_nocat_record)(struct nvkm_gsp *); + u32 (*sr_data_size)(struct nvkm_gsp *); + } *gsp; + + const struct nvkm_rm_api_rpc { + void *(*get)(struct nvkm_gsp *, u32 fn, u32 argc); + void *(*push)(struct nvkm_gsp *gsp, void *argv, + enum nvkm_gsp_rpc_reply_policy policy, u32 repc); + void (*done)(struct nvkm_gsp *gsp, void *repv); + } *rpc; + + const struct nvkm_rm_api_ctrl { + void *(*get)(struct nvkm_gsp_object *, u32 cmd, u32 params_size); + int (*push)(struct nvkm_gsp_object *, void **params, u32 repc); + void (*done)(struct nvkm_gsp_object *, void *params); + } *ctrl; + + const struct nvkm_rm_api_alloc { + void *(*get)(struct nvkm_gsp_object *, u32 oclass, u32 params_size); + void *(*push)(struct nvkm_gsp_object *, void *params); + void (*done)(struct nvkm_gsp_object *, void *params); + + int (*free)(struct nvkm_gsp_object *); + } *alloc; + + const struct nvkm_rm_api_client { + int (*ctor)(struct nvkm_gsp_client *, u32 handle); + } *client; + + const struct nvkm_rm_api_device { + int (*ctor)(struct nvkm_gsp_client *, struct nvkm_gsp_device *); + void (*dtor)(struct nvkm_gsp_device *); + + struct { + int (*ctor)(struct nvkm_gsp_device *, u32 handle, u32 id, + nvkm_gsp_event_func, struct nvkm_gsp_event *); + void (*dtor)(struct nvkm_gsp_event *); + } event; + } *device; + + const struct nvkm_rm_api_fbsr { + int (*suspend)(struct nvkm_gsp *); + void (*resume)(struct nvkm_gsp *); + } *fbsr; + + const struct nvkm_rm_api_disp { + int (*get_static_info)(struct nvkm_disp *); + int (*get_supported)(struct nvkm_disp *, unsigned long *display_mask); + int (*get_connect_state)(struct nvkm_disp *, unsigned display_id); + int (*get_active)(struct nvkm_disp *, unsigned head, u32 *display_id); + + int (*bl_ctrl)(struct nvkm_disp *, unsigned display_id, bool set, int *val); + + struct { + int (*get_caps)(struct nvkm_disp *, int *link_bw, bool *mst, bool *wm); + int (*set_indexed_link_rates)(struct nvkm_outp *); + } dp; + + struct { + int (*set_pushbuf)(struct nvkm_disp *, s32 oclass, int inst, + struct nvkm_memory *); + int (*dmac_alloc)(struct nvkm_disp *, u32 oclass, int inst, u32 put_offset, + struct nvkm_gsp_object *); + } chan; + } *disp; + + const struct nvkm_rm_api_fifo { + int (*xlat_rm_engine_type)(u32 rm_engine_type, + enum nvkm_subdev_type *, int *nv2080_type); + int (*ectx_size)(struct nvkm_fifo *); + unsigned rsvd_chids; + int (*rc_triggered)(void *priv, u32 fn, void *repv, u32 repc); + struct { + int (*alloc)(struct nvkm_gsp_device *, u32 handle, + u32 nv2080_engine_type, u8 runq, bool priv, int chid, + u64 inst_addr, u64 userd_addr, u64 mthdbuf_addr, + struct nvkm_vmm *, u64 gpfifo_offset, u32 gpfifo_length, + struct nvkm_gsp_object *); + } chan; + } *fifo; + + const struct nvkm_rm_api_engine { + int (*alloc)(struct nvkm_gsp_object *chan, u32 handle, u32 class, int inst, + struct nvkm_gsp_object *); + } *ce, *nvdec, *nvenc, *nvjpg, *ofa; + + const struct nvkm_rm_api_gr { + int (*get_ctxbufs_info)(struct r535_gr *); + struct { + int (*init)(struct r535_gr *); + void (*fini)(struct r535_gr *); + } scrubber; + } *gr; +}; + +extern const struct nvkm_rm_impl r535_rm_tu102; +extern const struct nvkm_rm_impl r535_rm_ga102; +extern const struct nvkm_rm_api_gsp r535_gsp; +typedef struct DOD_METHOD_DATA DOD_METHOD_DATA; +typedef struct JT_METHOD_DATA JT_METHOD_DATA; +typedef struct CAPS_METHOD_DATA CAPS_METHOD_DATA; +void r535_gsp_acpi_dod(acpi_handle, DOD_METHOD_DATA *); +void r535_gsp_acpi_jt(acpi_handle, JT_METHOD_DATA *); +void r535_gsp_acpi_caps(acpi_handle, CAPS_METHOD_DATA *); +struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS; +void r535_gsp_get_static_info_fb(struct nvkm_gsp *, + const struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS *); +extern const struct nvkm_rm_api_rpc r535_rpc; +extern const struct nvkm_rm_api_ctrl r535_ctrl; +extern const struct nvkm_rm_api_alloc r535_alloc; +extern const struct nvkm_rm_api_client r535_client; +void r535_gsp_client_dtor(struct nvkm_gsp_client *); +extern const struct nvkm_rm_api_device r535_device; +int r535_mmu_vaspace_new(struct nvkm_vmm *, u32 handle, bool external); +void r535_mmu_vaspace_del(struct nvkm_vmm *); +extern const struct nvkm_rm_api_fbsr r535_fbsr; +void r535_fbsr_resume(struct nvkm_gsp *); +int r535_fbsr_memlist(struct nvkm_gsp_device *, u32 handle, enum nvkm_memory_target, + u64 phys, u64 size, struct sg_table *, struct nvkm_gsp_object *); +extern const struct nvkm_rm_api_disp r535_disp; +extern const struct nvkm_rm_api_fifo r535_fifo; +void r535_fifo_rc_chid(struct nvkm_fifo *, int chid); +extern const struct nvkm_rm_api_engine r535_ce; +extern const struct nvkm_rm_api_gr r535_gr; +void *r535_gr_dtor(struct nvkm_gr *); +int r535_gr_oneinit(struct nvkm_gr *); +u64 r535_gr_units(struct nvkm_gr *); +int r535_gr_chan_new(struct nvkm_gr *, struct nvkm_chan *, const struct nvkm_oclass *, + struct nvkm_object **); +int r535_gr_promote_ctx(struct r535_gr *, bool golden, struct nvkm_vmm *, + struct nvkm_memory **pctxbuf_mem, struct nvkm_vma **pctxbuf_vma, + struct nvkm_gsp_object *chan); +extern const struct nvkm_rm_api_engine r535_nvdec; +extern const struct nvkm_rm_api_engine r535_nvenc; +extern const struct nvkm_rm_api_engine r535_nvjpg; +extern const struct nvkm_rm_api_engine r535_ofa; + +extern const struct nvkm_rm_impl r570_rm_tu102; +extern const struct nvkm_rm_impl r570_rm_ga102; +extern const struct nvkm_rm_impl r570_rm_gh100; +extern const struct nvkm_rm_impl r570_rm_gb10x; +extern const struct nvkm_rm_impl r570_rm_gb20x; +extern const struct nvkm_rm_api_gsp r570_gsp; +extern const struct nvkm_rm_api_client r570_client; +extern const struct nvkm_rm_api_fbsr r570_fbsr; +extern const struct nvkm_rm_api_disp r570_disp; +extern const struct nvkm_rm_api_fifo r570_fifo; +extern const struct nvkm_rm_api_gr r570_gr; +int r570_gr_gpc_mask(struct nvkm_gsp *, u32 *mask); +int r570_gr_tpc_mask(struct nvkm_gsp *, int gpc, u32 *mask); +extern const struct nvkm_rm_api_engine r570_ofa; +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rpc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rpc.h new file mode 100644 index 000000000000..4431e33b3304 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rpc.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#ifndef __NVKM_RM_RPC_H__ +#define __NVKM_RM_RPC_H__ +#include "rm.h" + +#define to_payload_hdr(p, header) \ + container_of((void *)p, typeof(*header), params) + +int r535_gsp_rpc_poll(struct nvkm_gsp *, u32 fn); + +struct nvfw_gsp_rpc *r535_gsp_msg_recv(struct nvkm_gsp *, int fn, u32 gsp_rpc_len); +int r535_gsp_msg_ntfy_add(struct nvkm_gsp *, u32 fn, nvkm_gsp_msg_ntfy_func, void *priv); + +int r535_rpc_status_to_errno(uint32_t rpc_status); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c new file mode 100644 index 000000000000..423502f870db --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/tu1xx.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "gpu.h" + +#include <engine/fifo/priv.h> + +#include <nvif/class.h> + +const struct nvkm_rm_gpu +tu1xx_gpu = { + .disp.class = { + .root = TU102_DISP, + .caps = GV100_DISP_CAPS, + .core = TU102_DISP_CORE_CHANNEL_DMA, + .wndw = TU102_DISP_WINDOW_CHANNEL_DMA, + .wimm = TU102_DISP_WINDOW_IMM_CHANNEL_DMA, + .curs = TU102_DISP_CURSOR, + }, + + .usermode.class = TURING_USERMODE_A, + + .fifo.chan = { + .class = TURING_CHANNEL_GPFIFO_A, + .doorbell_handle = tu102_chan_doorbell_handle, + }, + + .ce.class = TURING_DMA_COPY_A, + .gr.class = { + .i2m = KEPLER_INLINE_TO_MEMORY_B, + .twod = FERMI_TWOD_A, + .threed = TURING_A, + .compute = TURING_COMPUTE_A, + }, + .nvdec.class = NVC4B0_VIDEO_DECODER, + .nvenc.class = NVC4B7_VIDEO_ENCODER, +}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c index 59c5f2b9172a..58e233bc53b1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c @@ -22,11 +22,45 @@ #include "priv.h" #include <subdev/fb.h> +#include <engine/sec2.h> + +#include <rm/r535/nvrm/gsp.h> #include <nvfw/flcn.h> #include <nvfw/fw.h> #include <nvfw/hs.h> +static int +tu102_gsp_booter_unload(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + struct nvkm_device *device = subdev->device; + u32 wpr2_hi; + int ret; + + wpr2_hi = nvkm_rd32(device, 0x1fa828); + if (!wpr2_hi) { + nvkm_debug(subdev, "WPR2 not set - skipping booter unload\n"); + return 0; + } + + ret = nvkm_falcon_fw_boot(&gsp->booter.unload, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); + if (WARN_ON(ret)) + return ret; + + wpr2_hi = nvkm_rd32(device, 0x1fa828); + if (WARN_ON(wpr2_hi)) + return -EIO; + + return 0; +} + +static int +tu102_gsp_booter_load(struct nvkm_gsp *gsp, u32 mbox0, u32 mbox1) +{ + return nvkm_falcon_fw_boot(&gsp->booter.load, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); +} + int tu102_gsp_booter_ctor(struct nvkm_gsp *gsp, const char *name, const struct firmware *blob, struct nvkm_falcon *falcon, struct nvkm_falcon_fw *fw) @@ -114,6 +148,118 @@ tu102_gsp_reset(struct nvkm_gsp *gsp) return gsp->falcon.func->reset_eng(&gsp->falcon); } +int +tu102_gsp_fini(struct nvkm_gsp *gsp, bool suspend) +{ + u32 mbox0 = 0xff, mbox1 = 0xff; + int ret; + + ret = r535_gsp_fini(gsp, suspend); + if (ret && suspend) + return ret; + + nvkm_falcon_reset(&gsp->falcon); + + ret = nvkm_gsp_fwsec_sb(gsp); + WARN_ON(ret); + + if (suspend) { + mbox0 = lower_32_bits(gsp->sr.meta.addr); + mbox1 = upper_32_bits(gsp->sr.meta.addr); + } + + ret = tu102_gsp_booter_unload(gsp, mbox0, mbox1); + WARN_ON(ret); + return 0; +} + +int +tu102_gsp_init(struct nvkm_gsp *gsp) +{ + u32 mbox0, mbox1; + int ret; + + if (!gsp->sr.meta.data) { + mbox0 = lower_32_bits(gsp->wpr_meta.addr); + mbox1 = upper_32_bits(gsp->wpr_meta.addr); + } else { + gsp->rm->api->gsp->set_rmargs(gsp, true); + + mbox0 = lower_32_bits(gsp->sr.meta.addr); + mbox1 = upper_32_bits(gsp->sr.meta.addr); + } + + /* Execute booter to handle (eventually...) booting GSP-RM. */ + ret = tu102_gsp_booter_load(gsp, mbox0, mbox1); + if (WARN_ON(ret)) + return ret; + + return r535_gsp_init(gsp); +} + +static int +tu102_gsp_wpr_meta_init(struct nvkm_gsp *gsp) +{ + GspFwWprMeta *meta; + int ret; + + ret = nvkm_gsp_mem_ctor(gsp, sizeof(*meta), &gsp->wpr_meta); + if (ret) + return ret; + + meta = gsp->wpr_meta.data; + + meta->magic = GSP_FW_WPR_META_MAGIC; + meta->revision = GSP_FW_WPR_META_REVISION; + + meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr; + meta->sizeOfRadix3Elf = gsp->fb.wpr2.elf.size; + + meta->sysmemAddrOfBootloader = gsp->boot.fw.addr; + meta->sizeOfBootloader = gsp->boot.fw.size; + meta->bootloaderCodeOffset = gsp->boot.code_offset; + meta->bootloaderDataOffset = gsp->boot.data_offset; + meta->bootloaderManifestOffset = gsp->boot.manifest_offset; + + meta->sysmemAddrOfSignature = gsp->sig.addr; + meta->sizeOfSignature = gsp->sig.size; + + meta->gspFwRsvdStart = gsp->fb.heap.addr; + meta->nonWprHeapOffset = gsp->fb.heap.addr; + meta->nonWprHeapSize = gsp->fb.heap.size; + meta->gspFwWprStart = gsp->fb.wpr2.addr; + meta->gspFwHeapOffset = gsp->fb.wpr2.heap.addr; + meta->gspFwHeapSize = gsp->fb.wpr2.heap.size; + meta->gspFwOffset = gsp->fb.wpr2.elf.addr; + meta->bootBinOffset = gsp->fb.wpr2.boot.addr; + meta->frtsOffset = gsp->fb.wpr2.frts.addr; + meta->frtsSize = gsp->fb.wpr2.frts.size; + meta->gspFwWprEnd = ALIGN_DOWN(gsp->fb.bios.vga_workspace.addr, 0x20000); + meta->fbSize = gsp->fb.size; + meta->vgaWorkspaceOffset = gsp->fb.bios.vga_workspace.addr; + meta->vgaWorkspaceSize = gsp->fb.bios.vga_workspace.size; + meta->bootCount = 0; + meta->partitionRpcAddr = 0; + meta->partitionRpcRequestOffset = 0; + meta->partitionRpcReplyOffset = 0; + meta->verified = 0; + return 0; +} + +u64 +tu102_gsp_wpr_heap_size(struct nvkm_gsp *gsp) +{ + u32 fb_size_gb = DIV_ROUND_UP_ULL(gsp->fb.size, 1 << 30); + u64 heap_size; + + heap_size = gsp->rm->wpr->os_carveout_size + + gsp->rm->wpr->base_size + + ALIGN(GSP_FW_HEAP_PARAM_SIZE_PER_GB_FB * fb_size_gb, 1 << 20) + + ALIGN(GSP_FW_HEAP_PARAM_CLIENT_ALLOC_SIZE, 1 << 20); + + return max(heap_size, gsp->rm->wpr->heap_size_min); +} + static u64 tu102_gsp_vga_workspace_addr(struct nvkm_gsp *gsp, u64 fb_size) { @@ -136,14 +282,67 @@ tu102_gsp_vga_workspace_addr(struct nvkm_gsp *gsp, u64 fb_size) int tu102_gsp_oneinit(struct nvkm_gsp *gsp) { - gsp->fb.size = nvkm_fb_vidmem_size(gsp->subdev.device); + struct nvkm_device *device = gsp->subdev.device; + int ret; + + gsp->fb.size = nvkm_fb_vidmem_size(device); gsp->fb.bios.vga_workspace.addr = tu102_gsp_vga_workspace_addr(gsp, gsp->fb.size); gsp->fb.bios.vga_workspace.size = gsp->fb.size - gsp->fb.bios.vga_workspace.addr; gsp->fb.bios.addr = gsp->fb.bios.vga_workspace.addr; gsp->fb.bios.size = gsp->fb.bios.vga_workspace.size; - return r535_gsp_oneinit(gsp); + ret = gsp->func->booter.ctor(gsp, "booter-load", gsp->fws.booter.load, + &device->sec2->falcon, &gsp->booter.load); + if (ret) + return ret; + + ret = gsp->func->booter.ctor(gsp, "booter-unload", gsp->fws.booter.unload, + &device->sec2->falcon, &gsp->booter.unload); + if (ret) + return ret; + + ret = r535_gsp_oneinit(gsp); + if (ret) + return ret; + + /* Calculate FB layout. */ + gsp->fb.wpr2.frts.size = 0x100000; + gsp->fb.wpr2.frts.addr = ALIGN_DOWN(gsp->fb.bios.addr, 0x20000) - gsp->fb.wpr2.frts.size; + + gsp->fb.wpr2.boot.size = gsp->boot.fw.size; + gsp->fb.wpr2.boot.addr = ALIGN_DOWN(gsp->fb.wpr2.frts.addr - gsp->fb.wpr2.boot.size, 0x1000); + + gsp->fb.wpr2.elf.size = gsp->fw.len; + gsp->fb.wpr2.elf.addr = ALIGN_DOWN(gsp->fb.wpr2.boot.addr - gsp->fb.wpr2.elf.size, 0x10000); + + gsp->fb.wpr2.heap.size = tu102_gsp_wpr_heap_size(gsp); + + gsp->fb.wpr2.heap.addr = ALIGN_DOWN(gsp->fb.wpr2.elf.addr - gsp->fb.wpr2.heap.size, 0x100000); + gsp->fb.wpr2.heap.size = ALIGN_DOWN(gsp->fb.wpr2.elf.addr - gsp->fb.wpr2.heap.addr, 0x100000); + + gsp->fb.wpr2.addr = ALIGN_DOWN(gsp->fb.wpr2.heap.addr - sizeof(GspFwWprMeta), 0x100000); + gsp->fb.wpr2.size = gsp->fb.wpr2.frts.addr + gsp->fb.wpr2.frts.size - gsp->fb.wpr2.addr; + + gsp->fb.heap.size = 0x100000; + gsp->fb.heap.addr = gsp->fb.wpr2.addr - gsp->fb.heap.size; + + ret = tu102_gsp_wpr_meta_init(gsp); + if (ret) + return ret; + + ret = nvkm_gsp_fwsec_frts(gsp); + if (WARN_ON(ret)) + return ret; + + /* Reset GSP into RISC-V mode. */ + ret = gsp->func->reset(gsp); + if (ret) + return ret; + + nvkm_falcon_wr32(&gsp->falcon, 0x040, lower_32_bits(gsp->libos.addr)); + nvkm_falcon_wr32(&gsp->falcon, 0x044, upper_32_bits(gsp->libos.addr)); + return 0; } const struct nvkm_falcon_func @@ -163,29 +362,73 @@ tu102_gsp_flcn = { }; static const struct nvkm_gsp_func -tu102_gsp_r535_113_01 = { +tu102_gsp = { .flcn = &tu102_gsp_flcn, .fwsec = &tu102_gsp_fwsec, .sig_section = ".fwsignature_tu10x", - .wpr_heap.base_size = 8 << 20, - .wpr_heap.min_size = 64 << 20, - .booter.ctor = tu102_gsp_booter_ctor, .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, - .rm = &r535_gsp_rm, + .rm.gpu = &tu1xx_gpu, }; +int +tu102_gsp_load_rm(struct nvkm_gsp *gsp, const struct nvkm_gsp_fwif *fwif) +{ + struct nvkm_subdev *subdev = &gsp->subdev; + bool enable_gsp = fwif->enable; + int ret; + +#if IS_ENABLED(CONFIG_DRM_NOUVEAU_GSP_DEFAULT) + enable_gsp = true; +#endif + if (!nvkm_boolopt(subdev->device->cfgopt, "NvGspRm", enable_gsp)) + return -EINVAL; + + ret = nvkm_gsp_load_fw(gsp, "gsp", fwif->ver, &gsp->fws.rm); + if (ret) + return ret; + + ret = nvkm_gsp_load_fw(gsp, "bootloader", fwif->ver, &gsp->fws.bl); + if (ret) + return ret; + + return 0; +} + +int +tu102_gsp_load(struct nvkm_gsp *gsp, int ver, const struct nvkm_gsp_fwif *fwif) +{ + int ret; + + ret = tu102_gsp_load_rm(gsp, fwif); + if (ret) + goto done; + + ret = nvkm_gsp_load_fw(gsp, "booter_load", fwif->ver, &gsp->fws.booter.load); + if (ret) + goto done; + + ret = nvkm_gsp_load_fw(gsp, "booter_unload", fwif->ver, &gsp->fws.booter.unload); + +done: + if (ret) + nvkm_gsp_dtor_fws(gsp); + + return ret; +} + static struct nvkm_gsp_fwif tu102_gsps[] = { - { 0, r535_gsp_load, &tu102_gsp_r535_113_01, "535.113.01" }, + { 1, tu102_gsp_load, &tu102_gsp, &r570_rm_tu102, "570.144" }, + { 0, tu102_gsp_load, &tu102_gsp, &r535_rm_tu102, "535.113.01" }, { -1, gv100_gsp_nofw, &gv100_gsp }, {} }; @@ -196,3 +439,11 @@ tu102_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { return nvkm_gsp_new_(tu102_gsps, device, type, inst, pgsp); } + +NVKM_GSP_FIRMWARE_BOOTER(tu102, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(tu104, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(tu106, 535.113.01); + +NVKM_GSP_FIRMWARE_BOOTER(tu102, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(tu104, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(tu106, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c index 04fbd9ed28b1..97eb046c25d0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu116.c @@ -22,29 +22,27 @@ #include "priv.h" static const struct nvkm_gsp_func -tu116_gsp_r535_113_01 = { +tu116_gsp = { .flcn = &tu102_gsp_flcn, .fwsec = &tu102_gsp_fwsec, .sig_section = ".fwsignature_tu11x", - .wpr_heap.base_size = 8 << 20, - .wpr_heap.min_size = 64 << 20, - .booter.ctor = tu102_gsp_booter_ctor, .dtor = r535_gsp_dtor, .oneinit = tu102_gsp_oneinit, - .init = r535_gsp_init, - .fini = r535_gsp_fini, + .init = tu102_gsp_init, + .fini = tu102_gsp_fini, .reset = tu102_gsp_reset, - .rm = &r535_gsp_rm, + .rm.gpu = &tu1xx_gpu, }; static struct nvkm_gsp_fwif tu116_gsps[] = { - { 0, r535_gsp_load, &tu116_gsp_r535_113_01, "535.113.01" }, + { 1, tu102_gsp_load, &tu116_gsp, &r570_rm_tu102, "570.144" }, + { 0, tu102_gsp_load, &tu116_gsp, &r535_rm_tu102, "535.113.01" }, { -1, gv100_gsp_nofw, &gv100_gsp }, {} }; @@ -55,3 +53,9 @@ tu116_gsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { return nvkm_gsp_new_(tu116_gsps, device, type, inst, pgsp); } + +NVKM_GSP_FIRMWARE_BOOTER(tu116, 535.113.01); +NVKM_GSP_FIRMWARE_BOOTER(tu117, 535.113.01); + +NVKM_GSP_FIRMWARE_BOOTER(tu116, 570.144); +NVKM_GSP_FIRMWARE_BOOTER(tu117, 570.144); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild index 553d540f2736..fa7a2862dd1f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild @@ -4,5 +4,4 @@ nvkm-y += nvkm/subdev/instmem/nv04.o nvkm-y += nvkm/subdev/instmem/nv40.o nvkm-y += nvkm/subdev/instmem/nv50.o nvkm-y += nvkm/subdev/instmem/gk20a.o - -nvkm-y += nvkm/subdev/instmem/r535.o +nvkm-y += nvkm/subdev/instmem/gh100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index a2cd3330efc6..2f55bab8e132 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -182,9 +182,11 @@ nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend) int ret; if (suspend) { - ret = imem->func->suspend(imem); - if (ret) - return ret; + if (imem->func->suspend) { + ret = imem->func->suspend(imem); + if (ret) + return ret; + } imem->suspend = true; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gh100.c new file mode 100644 index 000000000000..8d8dd5f8a6c7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gh100.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/ref/gh100/pri_nv_xal_ep.h> + +static void +gh100_instmem_set_bar0_window_addr(struct nvkm_device *device, u64 addr) +{ + nvkm_wr32(device, NV_XAL_EP_BAR0_WINDOW, addr >> NV_XAL_EP_BAR0_WINDOW_BASE_SHIFT); +} + +static const struct nvkm_instmem_func +gh100_instmem = { + .fini = nv50_instmem_fini, + .memory_new = nv50_instobj_new, + .memory_wrap = nv50_instobj_wrap, + .set_bar0_window_addr = gh100_instmem_set_bar0_window_addr, +}; + +int +gh100_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_instmem **pimem) +{ + return r535_instmem_new(&gh100_instmem, device, type, inst, pimem); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c index 6b462f960922..2544b9f0ec85 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c @@ -239,7 +239,6 @@ nv40_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int ins struct nvkm_instmem **pimem) { struct nv40_instmem *imem; - int bar; if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL))) return -ENOMEM; @@ -247,13 +246,8 @@ nv40_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int ins *pimem = &imem->base; /* map bar */ - if (device->func->resource_size(device, 2)) - bar = 2; - else - bar = 3; - - imem->iomem = ioremap_wc(device->func->resource_addr(device, bar), - device->func->resource_size(device, bar)); + imem->iomem = ioremap_wc(device->func->resource_addr(device, NVKM_BAR2_INST), + device->func->resource_size(device, NVKM_BAR2_INST)); if (!imem->iomem) { nvkm_error(&imem->base.subdev, "unable to map PRAMIN BAR\n"); return -EFAULT; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index dd5b5a17ece0..4ca6fb30743d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -65,7 +65,7 @@ nv50_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data) spin_lock_irqsave(&imem->base.lock, flags); if (unlikely(imem->addr != base)) { - nvkm_wr32(device, 0x001700, base >> 16); + imem->base.func->set_bar0_window_addr(device, base); imem->addr = base; } nvkm_wr32(device, 0x700000 + addr, data); @@ -85,7 +85,7 @@ nv50_instobj_rd32_slow(struct nvkm_memory *memory, u64 offset) spin_lock_irqsave(&imem->base.lock, flags); if (unlikely(imem->addr != base)) { - nvkm_wr32(device, 0x001700, base >> 16); + imem->base.func->set_bar0_window_addr(device, base); imem->addr = base; } data = nvkm_rd32(device, 0x700000 + addr); @@ -172,7 +172,7 @@ nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm) /* Make the mapping visible to the host. */ iobj->bar = bar; - iobj->map = ioremap_wc(device->func->resource_addr(device, 3) + + iobj->map = ioremap_wc(device->func->resource_addr(device, NVKM_BAR2_INST) + (u32)iobj->bar->addr, size); if (!iobj->map) { nvkm_warn(subdev, "PRAMIN ioremap failed\n"); @@ -353,7 +353,7 @@ nv50_instobj_func = { .map = nv50_instobj_map, }; -static int +int nv50_instobj_wrap(struct nvkm_instmem *base, struct nvkm_memory *memory, struct nvkm_memory **pmemory) { @@ -373,7 +373,7 @@ nv50_instobj_wrap(struct nvkm_instmem *base, return 0; } -static int +int nv50_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, struct nvkm_memory **pmemory) { @@ -395,6 +395,12 @@ nv50_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, *****************************************************************************/ static void +nv50_instmem_set_bar0_window_addr(struct nvkm_device *device, u64 addr) +{ + nvkm_wr32(device, 0x001700, addr >> 16); +} + +void nv50_instmem_fini(struct nvkm_instmem *base) { nv50_instmem(base)->addr = ~0ULL; @@ -415,6 +421,7 @@ nv50_instmem = { .memory_new = nv50_instobj_new, .memory_wrap = nv50_instobj_wrap, .zero = false, + .set_bar0_window_addr = nv50_instmem_set_bar0_window_addr, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h index 4c14c96fb60a..87bbdd786eaa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h @@ -16,10 +16,16 @@ struct nvkm_instmem_func { bool zero, struct nvkm_memory **); int (*memory_wrap)(struct nvkm_instmem *, struct nvkm_memory *, struct nvkm_memory **); bool zero; + void (*set_bar0_window_addr)(struct nvkm_device *, u64 addr); }; int nv50_instmem_new_(const struct nvkm_instmem_func *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **); +void nv50_instmem_fini(struct nvkm_instmem *); +int nv50_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero, + struct nvkm_memory **); +int nv50_instobj_wrap(struct nvkm_instmem *, struct nvkm_memory *vram, + struct nvkm_memory **bar2); void nvkm_instmem_ctor(const struct nvkm_instmem_func *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild index 7ba35ea59c06..ea4848931540 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild @@ -15,8 +15,7 @@ nvkm-y += nvkm/subdev/mmu/gp100.o nvkm-y += nvkm/subdev/mmu/gp10b.o nvkm-y += nvkm/subdev/mmu/gv100.o nvkm-y += nvkm/subdev/mmu/tu102.o - -nvkm-y += nvkm/subdev/mmu/r535.o +nvkm-y += nvkm/subdev/mmu/gh100.o nvkm-y += nvkm/subdev/mmu/mem.o nvkm-y += nvkm/subdev/mmu/memnv04.o @@ -38,6 +37,7 @@ nvkm-y += nvkm/subdev/mmu/vmmgp100.o nvkm-y += nvkm/subdev/mmu/vmmgp10b.o nvkm-y += nvkm/subdev/mmu/vmmgv100.o nvkm-y += nvkm/subdev/mmu/vmmtu102.o +nvkm-y += nvkm/subdev/mmu/vmmgh100.o nvkm-y += nvkm/subdev/mmu/umem.o nvkm-y += nvkm/subdev/mmu/ummu.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gh100.c new file mode 100644 index 000000000000..2918fb32cc91 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gh100.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "mem.h" +#include "vmm.h" + +#include <nvif/class.h> + +static const struct nvkm_mmu_func +gh100_mmu = { + .dma_bits = 52, + .mmu = {{ -1, -1, NVIF_CLASS_MMU_GF100}}, + .mem = {{ -1, 0, NVIF_CLASS_MEM_GF100}, gf100_mem_new, gf100_mem_map }, + .vmm = {{ -1, 0, NVIF_CLASS_VMM_GP100}, gh100_vmm_new }, + .kind = tu102_mmu_kind, + .kind_sys = true, +}; + +int +gh100_mmu_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_mmu **pmmu) +{ + return r535_mmu_new(&gh100_mmu, device, type, inst, pmmu); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c index d9c9bee45222..160a5749a29f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memgf100.c @@ -60,7 +60,7 @@ gf100_mem_map(struct nvkm_mmu *mmu, struct nvkm_memory *memory, void *argv, if (ret) return ret; - *paddr = device->func->resource_addr(device, 1) + (*pvma)->addr; + *paddr = device->func->resource_addr(device, NVKM_BAR1_FB) + (*pvma)->addr; *psize = (*pvma)->size; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c index 79a3b0cc9f5b..1e3db52de6cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv04.c @@ -41,7 +41,7 @@ nv04_mem_map(struct nvkm_mmu *mmu, struct nvkm_memory *memory, void *argv, if ((ret = nvif_unvers(ret, &argv, &argc, args->vn))) return ret; - *paddr = device->func->resource_addr(device, 1) + addr; + *paddr = device->func->resource_addr(device, NVKM_BAR1_FB) + addr; *psize = nvkm_memory_size(memory); *pvma = ERR_PTR(-ENODEV); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c index 46759b89fc1f..33b2321e9d87 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/memnv50.c @@ -57,7 +57,7 @@ nv50_mem_map(struct nvkm_mmu *mmu, struct nvkm_memory *memory, void *argv, if (ret) return ret; - *paddr = device->func->resource_addr(device, 1) + (*pvma)->addr; + *paddr = device->func->resource_addr(device, NVKM_BAR1_FB) + (*pvma)->addr; *psize = (*pvma)->size; return nvkm_memory_map(memory, 0, bar, *pvma, &uvmm, sizeof(uvmm)); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h index e9ca6537778c..90efef8f0b54 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/priv.h @@ -53,6 +53,8 @@ const u8 *gf100_mmu_kind(struct nvkm_mmu *, int *count, u8 *invalid); const u8 *gm200_mmu_kind(struct nvkm_mmu *, int *, u8 *); +const u8 *tu102_mmu_kind(struct nvkm_mmu *, int *, u8 *); + struct nvkm_mmu_pt { union { struct nvkm_mmu_ptc *ptc; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c index df662ce4a4b0..7acff3642e20 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/tu102.c @@ -28,7 +28,7 @@ #include <nvif/class.h> -static const u8 * +const u8 * tu102_mmu_kind(struct nvkm_mmu *mmu, int *count, u8 *invalid) { static const u8 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 9c97800fe037..f95c58b67633 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -19,7 +19,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ -#define NVKM_VMM_LEVELS_MAX 5 +#define NVKM_VMM_LEVELS_MAX 6 #include "vmm.h" #include <subdev/fb.h> @@ -1030,12 +1030,8 @@ nvkm_vmm_dtor(struct nvkm_vmm *vmm) struct nvkm_vma *vma; struct rb_node *node; - if (vmm->rm.client.gsp) { - nvkm_gsp_rm_free(&vmm->rm.object); - nvkm_gsp_device_dtor(&vmm->rm.device); - nvkm_gsp_client_dtor(&vmm->rm.client); - nvkm_vmm_put(vmm, &vmm->rm.rsvd); - } + if (vmm->rm.client.gsp) + r535_mmu_vaspace_del(vmm); if (0) nvkm_vmm_dump(vmm); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h index f9bc30cdb2b3..4586a425dbe4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h @@ -143,6 +143,8 @@ struct nvkm_vmm_func { int (*aper)(enum nvkm_memory_target); int (*valid)(struct nvkm_vmm *, void *argv, u32 argc, struct nvkm_vmm_map *); + int (*valid2)(struct nvkm_vmm *, bool ro, bool priv, u8 kind, u8 comp, + struct nvkm_vmm_map *); void (*flush)(struct nvkm_vmm *, int depth); int (*mthd)(struct nvkm_vmm *, struct nvkm_client *, @@ -254,6 +256,8 @@ void gp100_vmm_invalidate_pdb(struct nvkm_vmm *, u64 addr); int gv100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *); +void tu102_vmm_flush(struct nvkm_vmm *, int depth); + int nv04_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); int nv41_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, @@ -296,6 +300,9 @@ int gv100_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, int tu102_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, struct lock_class_key *, const char *, struct nvkm_vmm **); +int gh100_vmm_new(struct nvkm_mmu *, bool, u64, u64, void *, u32, + struct lock_class_key *, const char *, + struct nvkm_vmm **); #define VMM_PRINT(l,v,p,f,a...) do { \ struct nvkm_vmm *_vmm = (v); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgh100.c new file mode 100644 index 000000000000..5614df3432da --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgh100.c @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "vmm.h" + +#include <subdev/fb.h> + +#include <nvhw/drf.h> +#include <nvhw/ref/gh100/dev_mmu.h> + +static inline void +gh100_vmm_pgt_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes, + struct nvkm_vmm_map *map, u64 addr) +{ + u64 data = addr | map->type; + + while (ptes--) { + VMM_WO064(pt, vmm, ptei++ * NV_MMU_VER3_PTE__SIZE, data); + data += map->next; + } +} + +static void +gh100_vmm_pgt_sgl(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes, + struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_SGL(vmm, pt, ptei, ptes, map, gh100_vmm_pgt_pte); +} + +static void +gh100_vmm_pgt_dma(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes, + struct nvkm_vmm_map *map) +{ + if (map->page->shift == PAGE_SHIFT) { + VMM_SPAM(vmm, "DMAA %08x %08x PTE(s)", ptei, ptes); + + nvkm_kmap(pt->memory); + while (ptes--) { + const u64 data = *map->dma++ | map->type; + + VMM_WO064(pt, vmm, ptei++ * NV_MMU_VER3_PTE__SIZE, data); + } + nvkm_done(pt->memory); + return; + } + + VMM_MAP_ITER_DMA(vmm, pt, ptei, ptes, map, gh100_vmm_pgt_pte); +} + +static void +gh100_vmm_pgt_mem(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes, + struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_MEM(vmm, pt, ptei, ptes, map, gh100_vmm_pgt_pte); +} + +static void +gh100_vmm_pgt_sparse(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + const u64 data = NVDEF(NV_MMU, VER3_PTE, PCF, SPARSE); + + VMM_FO064(pt, vmm, ptei * NV_MMU_VER3_PTE__SIZE, data, ptes); +} + +static const struct nvkm_vmm_desc_func +gh100_vmm_desc_spt = { + .unmap = gf100_vmm_pgt_unmap, + .sparse = gh100_vmm_pgt_sparse, + .mem = gh100_vmm_pgt_mem, + .dma = gh100_vmm_pgt_dma, + .sgl = gh100_vmm_pgt_sgl, +}; + +static void +gh100_vmm_lpt_invalid(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 ptei, u32 ptes) +{ + const u64 data = NVDEF(NV_MMU, VER3_PTE, PCF, NO_VALID_4KB_PAGE); + + VMM_FO064(pt, vmm, ptei * NV_MMU_VER3_PTE__SIZE, data, ptes); +} + +static const struct nvkm_vmm_desc_func +gh100_vmm_desc_lpt = { + .invalid = gh100_vmm_lpt_invalid, + .unmap = gf100_vmm_pgt_unmap, + .sparse = gh100_vmm_pgt_sparse, + .mem = gh100_vmm_pgt_mem, +}; + +static inline void +gh100_vmm_pd0_pte(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map, u64 addr) +{ + u64 data = addr | map->type; + + while (ptes--) { + VMM_WO128(pt, vmm, ptei++ * NV_MMU_VER3_DUAL_PDE__SIZE, data, 0ULL); + data += map->next; + } +} + +static void +gh100_vmm_pd0_mem(struct nvkm_vmm *vmm, struct nvkm_mmu_pt *pt, + u32 ptei, u32 ptes, struct nvkm_vmm_map *map) +{ + VMM_MAP_ITER_MEM(vmm, pt, ptei, ptes, map, gh100_vmm_pd0_pte); +} + +static inline bool +gh100_vmm_pde(struct nvkm_mmu_pt *pt, u64 *data) +{ + switch (nvkm_memory_target(pt->memory)) { + case NVKM_MEM_TARGET_VRAM: + *data |= NVDEF(NV_MMU, VER3_PDE, APERTURE, VIDEO_MEMORY); + *data |= NVDEF(NV_MMU, VER3_PDE, PCF, VALID_CACHED_ATS_NOT_ALLOWED); + break; + case NVKM_MEM_TARGET_HOST: + *data |= NVDEF(NV_MMU, VER3_PDE, APERTURE, SYSTEM_COHERENT_MEMORY); + *data |= NVDEF(NV_MMU, VER3_PDE, PCF, VALID_UNCACHED_ATS_ALLOWED); + break; + case NVKM_MEM_TARGET_NCOH: + *data |= NVDEF(NV_MMU, VER3_PDE, APERTURE, SYSTEM_NON_COHERENT_MEMORY); + *data |= NVDEF(NV_MMU, VER3_PDE, PCF, VALID_CACHED_ATS_ALLOWED); + break; + default: + WARN_ON(1); + return false; + } + + *data |= pt->addr; + return true; +} + +static void +gh100_vmm_pd0_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgd, u32 pdei) +{ + struct nvkm_vmm_pt *pgt = pgd->pde[pdei]; + struct nvkm_mmu_pt *pd = pgd->pt[0]; + u64 data[2] = {}; + + if (pgt->pt[0] && !gh100_vmm_pde(pgt->pt[0], &data[0])) + return; + if (pgt->pt[1] && !gh100_vmm_pde(pgt->pt[1], &data[1])) + return; + + nvkm_kmap(pd->memory); + VMM_WO128(pd, vmm, pdei * NV_MMU_VER3_DUAL_PDE__SIZE, data[0], data[1]); + nvkm_done(pd->memory); +} + +static void +gh100_vmm_pd0_sparse(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 pdei, u32 pdes) +{ + const u64 data = NVDEF(NV_MMU, VER3_DUAL_PDE, PCF_BIG, SPARSE_ATS_ALLOWED); + + VMM_FO128(pt, vmm, pdei * NV_MMU_VER3_DUAL_PDE__SIZE, data, 0ULL, pdes); +} + +static void +gh100_vmm_pd0_unmap(struct nvkm_vmm *vmm, + struct nvkm_mmu_pt *pt, u32 pdei, u32 pdes) +{ + VMM_FO128(pt, vmm, pdei * NV_MMU_VER3_DUAL_PDE__SIZE, 0ULL, 0ULL, pdes); +} + +static const struct nvkm_vmm_desc_func +gh100_vmm_desc_pd0 = { + .unmap = gh100_vmm_pd0_unmap, + .sparse = gh100_vmm_pd0_sparse, + .pde = gh100_vmm_pd0_pde, + .mem = gh100_vmm_pd0_mem, +}; + +static void +gh100_vmm_pd1_pde(struct nvkm_vmm *vmm, struct nvkm_vmm_pt *pgd, u32 pdei) +{ + struct nvkm_vmm_pt *pgt = pgd->pde[pdei]; + struct nvkm_mmu_pt *pd = pgd->pt[0]; + u64 data = 0; + + if (!gh100_vmm_pde(pgt->pt[0], &data)) + return; + + nvkm_kmap(pd->memory); + VMM_WO064(pd, vmm, pdei * NV_MMU_VER3_PDE__SIZE, data); + nvkm_done(pd->memory); +} + +static const struct nvkm_vmm_desc_func +gh100_vmm_desc_pd1 = { + .unmap = gf100_vmm_pgt_unmap, + .sparse = gh100_vmm_pgt_sparse, + .pde = gh100_vmm_pd1_pde, +}; + +static const struct nvkm_vmm_desc +gh100_vmm_desc_16[] = { + { LPT, 5, 8, 0x0100, &gh100_vmm_desc_lpt }, + { PGD, 8, 16, 0x1000, &gh100_vmm_desc_pd0 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 1, 8, 0x1000, &gh100_vmm_desc_pd1 }, + {} +}; + +static const struct nvkm_vmm_desc +gh100_vmm_desc_12[] = { + { SPT, 9, 8, 0x1000, &gh100_vmm_desc_spt }, + { PGD, 8, 16, 0x1000, &gh100_vmm_desc_pd0 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 9, 8, 0x1000, &gh100_vmm_desc_pd1 }, + { PGD, 1, 8, 0x1000, &gh100_vmm_desc_pd1 }, + {} +}; + +static int +gh100_vmm_valid(struct nvkm_vmm *vmm, bool ro, bool priv, u8 kind, u8 comp, + struct nvkm_vmm_map *map) +{ + const enum nvkm_memory_target target = nvkm_memory_target(map->memory); + const bool vol = target == NVKM_MEM_TARGET_HOST; + const struct nvkm_vmm_page *page = map->page; + u8 kind_inv, pcf; + int kindn, aper; + const u8 *kindm; + + map->next = 1ULL << page->shift; + map->type = 0; + + aper = vmm->func->aper(target); + if (WARN_ON(aper < 0)) + return aper; + + kindm = vmm->mmu->func->kind(vmm->mmu, &kindn, &kind_inv); + if (kind >= kindn || kindm[kind] == kind_inv) { + VMM_DEBUG(vmm, "kind %02x", kind); + return -EINVAL; + } + + if (priv) { + if (ro) { + if (vol) + pcf = NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_UNCACHED_ACD; + else + pcf = NV_MMU_VER3_PTE_PCF_PRIVILEGE_RO_ATOMIC_CACHED_ACD; + } else { + if (vol) + pcf = NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_UNCACHED_ACD; + else + pcf = NV_MMU_VER3_PTE_PCF_PRIVILEGE_RW_ATOMIC_CACHED_ACD; + } + } else { + if (ro) { + if (vol) + pcf = NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_UNCACHED_ACD; + else + pcf = NV_MMU_VER3_PTE_PCF_REGULAR_RO_ATOMIC_CACHED_ACD; + } else { + if (vol) + pcf = NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_UNCACHED_ACD; + else + pcf = NV_MMU_VER3_PTE_PCF_REGULAR_RW_ATOMIC_CACHED_ACD; + } + } + + map->type |= NVDEF(NV_MMU, VER3_PTE, VALID, TRUE); + map->type |= NVVAL(NV_MMU, VER3_PTE, APERTURE, aper); + map->type |= NVVAL(NV_MMU, VER3_PTE, PCF, pcf); + map->type |= NVVAL(NV_MMU, VER3_PTE, KIND, kind); + return 0; +} + +static const struct nvkm_vmm_func +gh100_vmm = { + .join = gv100_vmm_join, + .part = gf100_vmm_part, + .aper = gf100_vmm_aper, + .valid = gp100_vmm_valid, + .valid2 = gh100_vmm_valid, + .flush = tu102_vmm_flush, + .page = { + { 56, &gh100_vmm_desc_16[5], NVKM_VMM_PAGE_Sxxx }, + { 47, &gh100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx }, + { 38, &gh100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx }, + { 29, &gh100_vmm_desc_16[2], NVKM_VMM_PAGE_SVxC }, + { 21, &gh100_vmm_desc_16[1], NVKM_VMM_PAGE_SVxC }, + { 16, &gh100_vmm_desc_16[0], NVKM_VMM_PAGE_SVxC }, + { 12, &gh100_vmm_desc_12[0], NVKM_VMM_PAGE_SVHx }, + {} + } +}; + +int +gh100_vmm_new(struct nvkm_mmu *mmu, bool managed, u64 addr, u64 size, + void *argv, u32 argc, struct lock_class_key *key, + const char *name, struct nvkm_vmm **pvmm) +{ + return gp100_vmm_new_(&gh100_vmm, mmu, managed, addr, size, + argv, argc, key, name, pvmm); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c index bddac77f48f0..851fd847a2a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c @@ -436,6 +436,9 @@ gp100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc, return ret; } + if (vmm->func->valid2) + return vmm->func->valid2(vmm, ro, priv, kind, 0, map); + aper = vmm->func->aper(target); if (WARN_ON(aper < 0)) return aper; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c index 8379e72d77ab..4b30eab40bba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c @@ -23,7 +23,7 @@ #include <subdev/timer.h> -static void +void tu102_vmm_flush(struct nvkm_vmm *vmm, int depth) { struct nvkm_device *device = vmm->mmu->subdev.device; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild index 174bdf995271..a14ea0f7b1c8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild @@ -13,3 +13,4 @@ nvkm-y += nvkm/subdev/pci/gf100.o nvkm-y += nvkm/subdev/pci/gf106.o nvkm-y += nvkm/subdev/pci/gk104.o nvkm-y += nvkm/subdev/pci/gp100.o +nvkm-y += nvkm/subdev/pci/gh100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index 5a0de45d36ce..6867934256a7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c @@ -39,26 +39,26 @@ nvkm_pci_msi_rearm(struct nvkm_device *device) u32 nvkm_pci_rd32(struct nvkm_pci *pci, u16 addr) { - return pci->func->rd32(pci, addr); + return nvkm_rd32(pci->subdev.device, pci->func->cfg.addr + addr); } void nvkm_pci_wr08(struct nvkm_pci *pci, u16 addr, u8 data) { - pci->func->wr08(pci, addr, data); + nvkm_wr08(pci->subdev.device, pci->func->cfg.addr + addr, data); } void nvkm_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data) { - pci->func->wr32(pci, addr, data); + nvkm_wr32(pci->subdev.device, pci->func->cfg.addr + addr, data); } u32 nvkm_pci_mask(struct nvkm_pci *pci, u16 addr, u32 mask, u32 value) { - u32 data = pci->func->rd32(pci, addr); - pci->func->wr32(pci, addr, (data & ~mask) | value); + u32 data = nvkm_pci_rd32(pci, addr); + nvkm_pci_wr32(pci, addr, (data & ~mask) | value); return data; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c index 5b29aacedef3..5308f6539a3f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c @@ -132,10 +132,9 @@ g84_pcie_init(struct nvkm_pci *pci) static const struct nvkm_pci_func g84_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = nv46_pci_msi_rearm, .pcie.init = g84_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g92.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g92.c index a9e0674009c6..8ae7aa02e675 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g92.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g92.c @@ -33,10 +33,9 @@ g92_pcie_version_supported(struct nvkm_pci *pci) static const struct nvkm_pci_func g92_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = nv46_pci_msi_rearm, .pcie.init = g84_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c index 7bacd0693283..df745d0690ca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c @@ -25,10 +25,9 @@ static const struct nvkm_pci_func g94_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = nv40_pci_msi_rearm, .pcie.init = g84_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c index 099906092fe1..6ce941df87b7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c @@ -78,10 +78,9 @@ gf100_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) static const struct nvkm_pci_func gf100_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = gf100_pci_msi_rearm, .pcie.init = gf100_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf106.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf106.c index bcde609ba866..712ca7e0959a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf106.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf106.c @@ -25,10 +25,9 @@ static const struct nvkm_pci_func gf106_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = nv40_pci_msi_rearm, .pcie.init = gf100_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gh100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gh100.c new file mode 100644 index 000000000000..42da92d7a5fe --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gh100.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. + */ +#include "priv.h" + +#include <nvhw/drf.h> +#include <nvhw/ref/gh100/dev_xtl_ep_pri.h> + +static void +gh100_pci_msi_rearm(struct nvkm_pci *pci) +{ + /* Handled by top-level intr ACK. */ +} + +static const struct nvkm_pci_func +gh100_pci = { + .cfg = { + .addr = DRF_LO(NV_EP_PCFGM), + .size = DRF_HI(NV_EP_PCFGM) - DRF_LO(NV_EP_PCFGM) + 1, + }, + .msi_rearm = gh100_pci_msi_rearm, +}; + +int +gh100_pci_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_pci **ppci) +{ + return nvkm_pci_new_(&gh100_pci, device, type, inst, ppci); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gk104.c index 6be87ecffc89..ec6d0a7de995 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gk104.c @@ -204,10 +204,9 @@ gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) static const struct nvkm_pci_func gk104_pci_func = { + .cfg = { .addr = 0x088000, .size = 0x1000 }, + .init = g84_pci_init, - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, .msi_rearm = nv40_pci_msi_rearm, .pcie.init = gk104_pcie_init, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gp100.c index a5fafda0014d..4204316a544f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gp100.c @@ -31,9 +31,7 @@ gp100_pci_msi_rearm(struct nvkm_pci *pci) static const struct nvkm_pci_func gp100_pci_func = { - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, + .cfg = { .addr = 0x088000, .size = 0x1000 }, .msi_rearm = gp100_pci_msi_rearm, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv04.c index 9ab64194b185..b8a3f6850fa7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv04.c @@ -23,32 +23,9 @@ */ #include "priv.h" -static u32 -nv04_pci_rd32(struct nvkm_pci *pci, u16 addr) -{ - struct nvkm_device *device = pci->subdev.device; - return nvkm_rd32(device, 0x001800 + addr); -} - -static void -nv04_pci_wr08(struct nvkm_pci *pci, u16 addr, u8 data) -{ - struct nvkm_device *device = pci->subdev.device; - nvkm_wr08(device, 0x001800 + addr, data); -} - -static void -nv04_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data) -{ - struct nvkm_device *device = pci->subdev.device; - nvkm_wr32(device, 0x001800 + addr, data); -} - static const struct nvkm_pci_func nv04_pci_func = { - .rd32 = nv04_pci_rd32, - .wr08 = nv04_pci_wr08, - .wr32 = nv04_pci_wr32, + .cfg = { .addr = 0x001800, .size = 0x1000 }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c index 6a3c31cf0200..1971dbbdeb2b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c @@ -23,27 +23,6 @@ */ #include "priv.h" -u32 -nv40_pci_rd32(struct nvkm_pci *pci, u16 addr) -{ - struct nvkm_device *device = pci->subdev.device; - return nvkm_rd32(device, 0x088000 + addr); -} - -void -nv40_pci_wr08(struct nvkm_pci *pci, u16 addr, u8 data) -{ - struct nvkm_device *device = pci->subdev.device; - nvkm_wr08(device, 0x088000 + addr, data); -} - -void -nv40_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data) -{ - struct nvkm_device *device = pci->subdev.device; - nvkm_wr32(device, 0x088000 + addr, data); -} - void nv40_pci_msi_rearm(struct nvkm_pci *pci) { @@ -52,9 +31,7 @@ nv40_pci_msi_rearm(struct nvkm_pci *pci) static const struct nvkm_pci_func nv40_pci_func = { - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, + .cfg = { .addr = 0x088000, .size = 0x1000 }, .msi_rearm = nv40_pci_msi_rearm, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c index 9cad17f178ec..0093eabac9ae 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c @@ -38,9 +38,7 @@ nv46_pci_msi_rearm(struct nvkm_pci *pci) static const struct nvkm_pci_func nv46_pci_func = { - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, + .cfg = { .addr = 0x088000, .size = 0x1000 }, .msi_rearm = nv46_pci_msi_rearm, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv4c.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv4c.c index 741e34bf307c..b445081bb80e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv4c.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv4c.c @@ -25,9 +25,7 @@ static const struct nvkm_pci_func nv4c_pci_func = { - .rd32 = nv40_pci_rd32, - .wr08 = nv40_pci_wr08, - .wr32 = nv40_pci_wr32, + .cfg = { .addr = 0x088000, .size = 0x1000 }, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h index 9b7583532962..988eeee1471c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h @@ -8,10 +8,12 @@ int nvkm_pci_new_(const struct nvkm_pci_func *, struct nvkm_device *, enum nvkm_ struct nvkm_pci **); struct nvkm_pci_func { + struct { + u32 addr; + u16 size; + } cfg; + void (*init)(struct nvkm_pci *); - u32 (*rd32)(struct nvkm_pci *, u16 addr); - void (*wr08)(struct nvkm_pci *, u16 addr, u8 data); - void (*wr32)(struct nvkm_pci *, u16 addr, u32 data); void (*msi_rearm)(struct nvkm_pci *); struct { @@ -27,9 +29,6 @@ struct nvkm_pci_func { } pcie; }; -u32 nv40_pci_rd32(struct nvkm_pci *, u16); -void nv40_pci_wr08(struct nvkm_pci *, u16, u8); -void nv40_pci_wr32(struct nvkm_pci *, u16, u32); void nv40_pci_msi_rearm(struct nvkm_pci *); void nv46_pci_msi_rearm(struct nvkm_pci *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c index dce337306cab..9446049642e1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c @@ -21,6 +21,8 @@ */ #include "priv.h" +#include <rm/gpu.h> + static void r535_vfn_dtor(struct nvkm_vfn *vfn) { @@ -32,6 +34,7 @@ r535_vfn_new(const struct nvkm_vfn_func *hw, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, u32 addr, struct nvkm_vfn **pvfn) { + const struct nvkm_rm_gpu *gpu = device->gsp->rm->gpu; struct nvkm_vfn_func *rm; int ret; @@ -39,8 +42,12 @@ r535_vfn_new(const struct nvkm_vfn_func *hw, return -ENOMEM; rm->dtor = r535_vfn_dtor; - rm->intr = hw->intr; - rm->user = hw->user; + rm->intr = &tu102_vfn_intr, + rm->user.addr = 0x030000; + rm->user.size = 0x010000; + rm->user.base.minver = -1; + rm->user.base.maxver = -1; + rm->user.base.oclass = gpu->usermode.class; ret = nvkm_vfn_new_(rm, device, type, inst, addr, pvfn); if (ret) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c index c5460a14c541..4e64d8843373 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c @@ -36,7 +36,7 @@ nvkm_uvfn_map(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_vfn *vfn = nvkm_uvfn(object)->vfn; struct nvkm_device *device = vfn->subdev.device; - *addr = device->func->resource_addr(device, 0) + vfn->addr.user; + *addr = device->func->resource_addr(device, NVKM_BAR0_PRI) + vfn->addr.user; *size = vfn->func->user.size; *type = NVKM_OBJECT_MAP_IO; return 0; diff --git a/drivers/gpu/drm/nova/Kconfig b/drivers/gpu/drm/nova/Kconfig new file mode 100644 index 000000000000..cca6a3fea879 --- /dev/null +++ b/drivers/gpu/drm/nova/Kconfig @@ -0,0 +1,14 @@ +config DRM_NOVA + tristate "Nova DRM driver" + depends on DRM=y + depends on PCI + depends on RUST + select AUXILIARY_BUS + default n + help + Choose this if you want to build the Nova DRM driver for Nvidia + GSP-based GPUs. + + This driver is work in progress and may not be functional. + + If M is selected, the module will be called nova. diff --git a/drivers/gpu/drm/nova/Makefile b/drivers/gpu/drm/nova/Makefile new file mode 100644 index 000000000000..42019bff3173 --- /dev/null +++ b/drivers/gpu/drm/nova/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_DRM_NOVA) += nova.o diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs new file mode 100644 index 000000000000..b28b2e05cc15 --- /dev/null +++ b/drivers/gpu/drm/nova/driver.rs @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 + +use kernel::{auxiliary, c_str, device::Core, drm, drm::gem, drm::ioctl, prelude::*, types::ARef}; + +use crate::file::File; +use crate::gem::NovaObject; + +pub(crate) struct NovaDriver { + #[expect(unused)] + drm: ARef<drm::Device<Self>>, +} + +/// Convienence type alias for the DRM device type for this driver +pub(crate) type NovaDevice = drm::Device<NovaDriver>; + +#[pin_data] +pub(crate) struct NovaData { + pub(crate) adev: ARef<auxiliary::Device>, +} + +const INFO: drm::DriverInfo = drm::DriverInfo { + major: 0, + minor: 0, + patchlevel: 0, + name: c_str!("nova"), + desc: c_str!("Nvidia Graphics"), +}; + +const NOVA_CORE_MODULE_NAME: &CStr = c_str!("NovaCore"); +const AUXILIARY_NAME: &CStr = c_str!("nova-drm"); + +kernel::auxiliary_device_table!( + AUX_TABLE, + MODULE_AUX_TABLE, + <NovaDriver as auxiliary::Driver>::IdInfo, + [( + auxiliary::DeviceId::new(NOVA_CORE_MODULE_NAME, AUXILIARY_NAME), + () + )] +); + +impl auxiliary::Driver for NovaDriver { + type IdInfo = (); + const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE; + + fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> { + let data = try_pin_init!(NovaData { adev: adev.into() }); + + let drm = drm::Device::<Self>::new(adev.as_ref(), data)?; + drm::Registration::new_foreign_owned(&drm, adev.as_ref(), 0)?; + + Ok(KBox::new(Self { drm }, GFP_KERNEL)?.into()) + } +} + +#[vtable] +impl drm::Driver for NovaDriver { + type Data = NovaData; + type File = File; + type Object = gem::Object<NovaObject>; + + const INFO: drm::DriverInfo = INFO; + + kernel::declare_drm_ioctls! { + (NOVA_GETPARAM, drm_nova_getparam, ioctl::RENDER_ALLOW, File::get_param), + (NOVA_GEM_CREATE, drm_nova_gem_create, ioctl::AUTH | ioctl::RENDER_ALLOW, File::gem_create), + (NOVA_GEM_INFO, drm_nova_gem_info, ioctl::AUTH | ioctl::RENDER_ALLOW, File::gem_info), + } +} diff --git a/drivers/gpu/drm/nova/file.rs b/drivers/gpu/drm/nova/file.rs new file mode 100644 index 000000000000..7e59a34b830d --- /dev/null +++ b/drivers/gpu/drm/nova/file.rs @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 + +use crate::driver::{NovaDevice, NovaDriver}; +use crate::gem::NovaObject; +use crate::uapi::{GemCreate, GemInfo, Getparam}; +use kernel::{ + alloc::flags::*, + drm::{self, gem::BaseObject}, + pci, + prelude::*, + types::Opaque, + uapi, +}; + +pub(crate) struct File; + +impl drm::file::DriverFile for File { + type Driver = NovaDriver; + + fn open(_dev: &NovaDevice) -> Result<Pin<KBox<Self>>> { + Ok(KBox::new(Self, GFP_KERNEL)?.into()) + } +} + +impl File { + /// IOCTL: get_param: Query GPU / driver metadata. + pub(crate) fn get_param( + dev: &NovaDevice, + getparam: &Opaque<uapi::drm_nova_getparam>, + _file: &drm::File<File>, + ) -> Result<u32> { + let adev = &dev.adev; + let parent = adev.parent().ok_or(ENOENT)?; + let pdev: &pci::Device = parent.try_into()?; + let getparam: &Getparam = getparam.into(); + + let value = match getparam.param() as u32 { + uapi::NOVA_GETPARAM_VRAM_BAR_SIZE => pdev.resource_len(1)?, + _ => return Err(EINVAL), + }; + + getparam.set_value(value); + + Ok(0) + } + + /// IOCTL: gem_create: Create a new DRM GEM object. + pub(crate) fn gem_create( + dev: &NovaDevice, + req: &Opaque<uapi::drm_nova_gem_create>, + file: &drm::File<File>, + ) -> Result<u32> { + let req: &GemCreate = req.into(); + let obj = NovaObject::new(dev, req.size().try_into()?)?; + + req.set_handle(obj.create_handle(file)?); + + Ok(0) + } + + /// IOCTL: gem_info: Query GEM metadata. + pub(crate) fn gem_info( + _dev: &NovaDevice, + req: &Opaque<uapi::drm_nova_gem_info>, + file: &drm::File<File>, + ) -> Result<u32> { + let req: &GemInfo = req.into(); + let bo = NovaObject::lookup_handle(file, req.handle())?; + + req.set_size(bo.size().try_into()?); + + Ok(0) + } +} diff --git a/drivers/gpu/drm/nova/gem.rs b/drivers/gpu/drm/nova/gem.rs new file mode 100644 index 000000000000..33b62d21400c --- /dev/null +++ b/drivers/gpu/drm/nova/gem.rs @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 + +use kernel::{ + drm, + drm::{gem, gem::BaseObject}, + prelude::*, + types::ARef, +}; + +use crate::{ + driver::{NovaDevice, NovaDriver}, + file::File, +}; + +/// GEM Object inner driver data +#[pin_data] +pub(crate) struct NovaObject {} + +impl gem::BaseDriverObject<gem::Object<NovaObject>> for NovaObject { + fn new(_dev: &NovaDevice, _size: usize) -> impl PinInit<Self, Error> { + try_pin_init!(NovaObject {}) + } +} + +impl gem::DriverObject for NovaObject { + type Driver = NovaDriver; +} + +impl NovaObject { + /// Create a new DRM GEM object. + pub(crate) fn new(dev: &NovaDevice, size: usize) -> Result<ARef<gem::Object<Self>>> { + let aligned_size = size.next_multiple_of(1 << 12); + + if size == 0 || size > aligned_size { + return Err(EINVAL); + } + + gem::Object::new(dev, aligned_size) + } + + /// Look up a GEM object handle for a `File` and return an `ObjectRef` for it. + #[inline] + pub(crate) fn lookup_handle( + file: &drm::File<File>, + handle: u32, + ) -> Result<ARef<gem::Object<Self>>> { + gem::Object::lookup_handle(file, handle) + } +} diff --git a/drivers/gpu/drm/nova/nova.rs b/drivers/gpu/drm/nova/nova.rs new file mode 100644 index 000000000000..902876aa14d1 --- /dev/null +++ b/drivers/gpu/drm/nova/nova.rs @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Nova DRM Driver + +mod driver; +mod file; +mod gem; +mod uapi; + +use crate::driver::NovaDriver; + +kernel::module_auxiliary_driver! { + type: NovaDriver, + name: "Nova", + author: "Danilo Krummrich", + description: "Nova GPU driver", + license: "GPL v2", +} diff --git a/drivers/gpu/drm/nova/uapi.rs b/drivers/gpu/drm/nova/uapi.rs new file mode 100644 index 000000000000..eb228a58d423 --- /dev/null +++ b/drivers/gpu/drm/nova/uapi.rs @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0 + +use kernel::uapi; + +// TODO Work out some common infrastructure to avoid boilerplate code for uAPI abstractions. + +macro_rules! define_uapi_abstraction { + ($name:ident <= $inner:ty) => { + #[repr(transparent)] + pub struct $name(::kernel::types::Opaque<$inner>); + + impl ::core::convert::From<&::kernel::types::Opaque<$inner>> for &$name { + fn from(value: &::kernel::types::Opaque<$inner>) -> Self { + // SAFETY: `Self` is a transparent wrapper of `$inner`. + unsafe { ::core::mem::transmute(value) } + } + } + }; +} + +define_uapi_abstraction!(Getparam <= uapi::drm_nova_getparam); + +impl Getparam { + pub fn param(&self) -> u64 { + // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_getparam`. + unsafe { (*self.0.get()).param } + } + + pub fn set_value(&self, v: u64) { + // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_getparam`. + unsafe { (*self.0.get()).value = v }; + } +} + +define_uapi_abstraction!(GemCreate <= uapi::drm_nova_gem_create); + +impl GemCreate { + pub fn size(&self) -> u64 { + // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_create`. + unsafe { (*self.0.get()).size } + } + + pub fn set_handle(&self, handle: u32) { + // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_create`. + unsafe { (*self.0.get()).handle = handle }; + } +} + +define_uapi_abstraction!(GemInfo <= uapi::drm_nova_gem_info); + +impl GemInfo { + pub fn handle(&self) -> u32 { + // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_info`. + unsafe { (*self.0.get()).handle } + } + + pub fn set_size(&self, size: u64) { + // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_info`. + unsafe { (*self.0.get()).size = size }; + } +} diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 639f4324db61..721581d425b4 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -517,6 +517,16 @@ config DRM_PANEL_NOVATEK_NT36672E LCD panel module. The panel has a resolution of 1080x2408 and uses 24 bit RGB per pixel. +config DRM_PANEL_NOVATEK_NT37801 + tristate "Novatek NT37801/NT37810 AMOLED DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for Novatek NT37801 (or + NT37810) AMOLED DSI Video Mode LCD panel module with 1440x3200 + resolution. + config DRM_PANEL_NOVATEK_NT39016 tristate "Novatek NT39016 RGB/SPI panel" depends on OF && SPI diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 5eec88e4ac3d..714cbac830e3 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36523) += panel-novatek-nt36523.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672E) += panel-novatek-nt36672e.o +obj-$(CONFIG_DRM_PANEL_NOVATEK_NT37801) += panel-novatek-nt37801.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o diff --git a/drivers/gpu/drm/panel/panel-novatek-nt37801.c b/drivers/gpu/drm/panel/panel-novatek-nt37801.c new file mode 100644 index 000000000000..84d367eab058 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-novatek-nt37801.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2024 Linaro Limited + +#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/regulator/consumer.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> + +#include <drm/display/drm_dsc.h> +#include <drm/display/drm_dsc_helper.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> + +#include <video/mipi_display.h> + +struct novatek_nt37801 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct drm_dsc_config dsc; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data *supplies; +}; + +static const struct regulator_bulk_data novatek_nt37801_supplies[] = { + { .supply = "vddio" }, + { .supply = "vci" }, + { .supply = "vdd" }, +}; + +static inline struct novatek_nt37801 *to_novatek_nt37801(struct drm_panel *panel) +{ + return container_of(panel, struct novatek_nt37801, panel); +} + +static void novatek_nt37801_reset(struct novatek_nt37801 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 21000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(10000, 21000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 21000); +} + +#define NT37801_DCS_SWITCH_PAGE 0xf0 + +#define novatek_nt37801_switch_page(dsi_ctx, page) \ + mipi_dsi_dcs_write_seq_multi((dsi_ctx), NT37801_DCS_SWITCH_PAGE, \ + 0x55, 0xaa, 0x52, 0x08, (page)) + +static int novatek_nt37801_on(struct novatek_nt37801 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + novatek_nt37801_switch_page(&dsi_ctx, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xc5, 0x0b, 0x0b, 0x0b); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0xaa, 0x55, 0xa5, 0x80); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf5, 0x10); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x1b); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf4, 0x55); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x18); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf8, 0x19); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x0f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfc, 0x00); + mipi_dsi_dcs_set_column_address_multi(&dsi_ctx, 0x0000, 0x059f); + mipi_dsi_dcs_set_page_address_multi(&dsi_ctx, 0x0000, 0x0c7f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x90, 0x03, 0x03); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x91, + 0x89, 0x28, 0x00, 0x28, 0xc2, 0x00, 0x02, + 0x68, 0x04, 0x6c, 0x00, 0x0a, 0x02, 0x77, + 0x01, 0xe9, 0x10, 0xf0); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0xaa, 0x55, 0xa5, 0x81); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x23); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfb, + 0x00, 0x01, 0x00, 0x11, 0x33, 0x33, 0x33, + 0x55, 0x57, 0xd0, 0x00, 0x00, 0x44, 0x56, + 0x77, 0x78, 0x9a, 0xbc, 0xdd, 0xf0); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x06); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf3, 0xdc); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_SET_GAMMA_CURVE, 0x00); + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3b, 0x00, 0x18, 0x00, 0x10); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, + 0x20); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51, + 0x07, 0xff, 0x07, 0xff, 0x0f, 0xff); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9c, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_MEMORY_START); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x00); + + novatek_nt37801_switch_page(&dsi_ctx, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb2, 0x55, 0x01, 0xff, 0x03); + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); + + return dsi_ctx.accum_err; +} + +static int novatek_nt37801_off(struct novatek_nt37801 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 20); + + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); + + return dsi_ctx.accum_err; +} + +static int novatek_nt37801_prepare(struct drm_panel *panel) +{ + struct novatek_nt37801 *ctx = to_novatek_nt37801(panel); + struct device *dev = &ctx->dsi->dev; + struct drm_dsc_picture_parameter_set pps; + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(novatek_nt37801_supplies), + ctx->supplies); + if (ret < 0) + return ret; + + novatek_nt37801_reset(ctx); + + ret = novatek_nt37801_on(ctx); + if (ret < 0) + goto err; + + drm_dsc_pps_payload_pack(&pps, &ctx->dsc); + + ret = mipi_dsi_picture_parameter_set(ctx->dsi, &pps); + if (ret < 0) { + dev_err(panel->dev, "failed to transmit PPS: %d\n", ret); + goto err; + } + + ret = mipi_dsi_compression_mode(ctx->dsi, true); + if (ret < 0) { + dev_err(dev, "failed to enable compression mode: %d\n", ret); + goto err; + } + + msleep(28); + + return 0; + +err: + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(novatek_nt37801_supplies), + ctx->supplies); + + return ret; +} + +static int novatek_nt37801_unprepare(struct drm_panel *panel) +{ + struct novatek_nt37801 *ctx = to_novatek_nt37801(panel); + struct device *dev = &ctx->dsi->dev; + int ret; + + ret = novatek_nt37801_off(ctx); + if (ret < 0) + dev_err(dev, "Failed to un-initialize panel: %d\n", ret); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + + regulator_bulk_disable(ARRAY_SIZE(novatek_nt37801_supplies), + ctx->supplies); + + return 0; +} + +static const struct drm_display_mode novatek_nt37801_mode = { + .clock = (1440 + 20 + 4 + 20) * (3200 + 20 + 2 + 18) * 120 / 1000, + .hdisplay = 1440, + .hsync_start = 1440 + 20, + .hsync_end = 1440 + 20 + 4, + .htotal = 1440 + 20 + 4 + 20, + .vdisplay = 3200, + .vsync_start = 3200 + 20, + .vsync_end = 3200 + 20 + 2, + .vtotal = 3200 + 20 + 2 + 18, + .type = DRM_MODE_TYPE_DRIVER, +}; + +static int novatek_nt37801_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, + &novatek_nt37801_mode); +} + +static const struct drm_panel_funcs novatek_nt37801_panel_funcs = { + .prepare = novatek_nt37801_prepare, + .unprepare = novatek_nt37801_unprepare, + .get_modes = novatek_nt37801_get_modes, +}; + +static int novatek_nt37801_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return 0; +} + +static const struct backlight_ops novatek_nt37801_bl_ops = { + .update_status = novatek_nt37801_bl_update_status, +}; + +static struct backlight_device * +novatek_nt37801_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = 4095, + .max_brightness = 4095, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &novatek_nt37801_bl_ops, &props); +} + +static int novatek_nt37801_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct novatek_nt37801 *ctx; + int ret; + + ctx = devm_drm_panel_alloc(dev, struct novatek_nt37801, panel, + &novatek_nt37801_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (!ctx) + return -ENOMEM; + + ret = devm_regulator_bulk_get_const(dev, + ARRAY_SIZE(novatek_nt37801_supplies), + novatek_nt37801_supplies, + &ctx->supplies); + if (ret < 0) + return ret; + + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "Failed to get reset-gpios\n"); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_CLOCK_NON_CONTINUOUS; + + ctx->panel.prepare_prev_first = true; + ctx->panel.backlight = novatek_nt37801_create_backlight(dsi); + if (IS_ERR(ctx->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), + "Failed to create backlight\n"); + + drm_panel_add(&ctx->panel); + + /* This panel only supports DSC; unconditionally enable it */ + dsi->dsc = &ctx->dsc; + ctx->dsc.dsc_version_major = 1; + ctx->dsc.dsc_version_minor = 1; + ctx->dsc.slice_height = 40; + ctx->dsc.slice_width = 720; + ctx->dsc.slice_count = 1440 / ctx->dsc.slice_width; + ctx->dsc.bits_per_component = 8; + ctx->dsc.bits_per_pixel = 8 << 4; /* 4 fractional bits */ + ctx->dsc.block_pred_enable = true; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + drm_panel_remove(&ctx->panel); + return dev_err_probe(dev, ret, "Failed to attach to DSI host\n"); + } + + return 0; +} + +static void novatek_nt37801_remove(struct mipi_dsi_device *dsi) +{ + struct novatek_nt37801 *ctx = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret < 0) + dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); + + drm_panel_remove(&ctx->panel); +} + +static const struct of_device_id novatek_nt37801_of_match[] = { + { .compatible = "novatek,nt37801" }, + {} +}; +MODULE_DEVICE_TABLE(of, novatek_nt37801_of_match); + +static struct mipi_dsi_driver novatek_nt37801_driver = { + .probe = novatek_nt37801_probe, + .remove = novatek_nt37801_remove, + .driver = { + .name = "panel-novatek-nt37801", + .of_match_table = novatek_nt37801_of_match, + }, +}; +module_mipi_dsi_driver(novatek_nt37801_driver); + +MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>"); +MODULE_DESCRIPTION("Panel driver for the Novatek NT37801/NT37810 AMOLED DSI panel"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 11a492f21157..51a3e0fc2f56 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -8548,7 +8548,7 @@ int cik_suspend(struct radeon_device *rdev) */ int cik_init(struct radeon_device *rdev) { - struct radeon_ring *ring; + struct radeon_ring *ring, *ring_cp1, *ring_cp2; int r; /* Read BIOS */ @@ -8623,19 +8623,22 @@ int cik_init(struct radeon_device *rdev) ring->ring_obj = NULL; r600_ring_init(rdev, ring, 1024 * 1024); - ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 1024 * 1024); - r = radeon_doorbell_get(rdev, &ring->doorbell_index); + ring_cp1 = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; + ring_cp2 = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; + ring_cp1->ring_obj = NULL; + ring_cp2->ring_obj = NULL; + ring_cp1->doorbell_index = RADEON_MAX_DOORBELLS; + ring_cp2->doorbell_index = RADEON_MAX_DOORBELLS; + + r600_ring_init(rdev, ring_cp1, 1024 * 1024); + r = radeon_doorbell_get(rdev, &ring_cp1->doorbell_index); if (r) return r; - ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 1024 * 1024); - r = radeon_doorbell_get(rdev, &ring->doorbell_index); + r600_ring_init(rdev, ring_cp2, 1024 * 1024); + r = radeon_doorbell_get(rdev, &ring_cp2->doorbell_index); if (r) - return r; + goto out; ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; ring->ring_obj = NULL; @@ -8653,12 +8656,16 @@ int cik_init(struct radeon_device *rdev) r = r600_pcie_gart_init(rdev); if (r) - return r; + goto out; rdev->accel_working = true; r = cik_startup(rdev); if (r) { dev_err(rdev->dev, "disabling GPU acceleration\n"); + radeon_doorbell_free(rdev, ring_cp1->doorbell_index); + radeon_doorbell_free(rdev, ring_cp2->doorbell_index); + ring_cp1->doorbell_index = RADEON_MAX_DOORBELLS; + ring_cp2->doorbell_index = RADEON_MAX_DOORBELLS; cik_cp_fini(rdev); cik_sdma_fini(rdev); cik_irq_fini(rdev); @@ -8678,10 +8685,16 @@ int cik_init(struct radeon_device *rdev) */ if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { DRM_ERROR("radeon: MC ucode required for NI+.\n"); - return -EINVAL; + r = -EINVAL; + goto out; } return 0; + +out: + radeon_doorbell_free(rdev, ring_cp1->doorbell_index); + radeon_doorbell_free(rdev, ring_cp2->doorbell_index); + return r; } /** @@ -8695,6 +8708,7 @@ int cik_init(struct radeon_device *rdev) */ void cik_fini(struct radeon_device *rdev) { + struct radeon_ring *ring; radeon_pm_fini(rdev); cik_cp_fini(rdev); cik_sdma_fini(rdev); @@ -8708,6 +8722,10 @@ void cik_fini(struct radeon_device *rdev) radeon_ib_pool_fini(rdev); radeon_irq_kms_fini(rdev); uvd_v1_0_fini(rdev); + ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; + radeon_doorbell_free(rdev, ring->doorbell_index); + ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; + radeon_doorbell_free(rdev, ring->doorbell_index); radeon_uvd_fini(rdev); radeon_vce_fini(rdev); cik_pcie_gart_fini(rdev); diff --git a/drivers/gpu/drm/sitronix/Kconfig b/drivers/gpu/drm/sitronix/Kconfig new file mode 100644 index 000000000000..c069d0d41775 --- /dev/null +++ b/drivers/gpu/drm/sitronix/Kconfig @@ -0,0 +1,51 @@ +config DRM_ST7571_I2C + tristate "DRM support for Sitronix ST7571 display panels (I2C)" + depends on DRM && I2C && MMU + select DRM_CLIENT_SELECTION + select DRM_GEM_SHMEM_HELPER + select DRM_KMS_HELPER + select REGMAP_I2C + help + DRM driver for Sitronix ST7571 panels controlled over I2C. + + if M is selected the module will be called st7571-i2c. + +config TINYDRM_ST7586 + tristate + default n + +config DRM_ST7586 + tristate "DRM support for Sitronix ST7586 display panels" + depends on DRM && SPI + select DRM_CLIENT_SELECTION + select DRM_KMS_HELPER + select DRM_GEM_DMA_HELPER + select DRM_MIPI_DBI + default TINYDRM_ST7586 + help + DRM driver for the following Sitronix ST7586 panels: + * LEGO MINDSTORMS EV3 + + If M is selected the module will be called st7586. + +config TINYDRM_ST7735R + tristate + default n + +config DRM_ST7735R + tristate "DRM support for Sitronix ST7715R/ST7735R display panels" + depends on DRM && SPI + select DRM_CLIENT_SELECTION + select DRM_KMS_HELPER + select DRM_GEM_DMA_HELPER + select DRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE + default TINYDRM_ST7735R + help + DRM driver for Sitronix ST7715R/ST7735R with one of the following + LCDs: + * Jianda JD-T18003-T01 1.8" 128x160 TFT + * Okaya RH128128T 1.44" 128x128 TFT + + If M is selected the module will be called st7735r. + diff --git a/drivers/gpu/drm/sitronix/Makefile b/drivers/gpu/drm/sitronix/Makefile new file mode 100644 index 000000000000..bd139e5a6995 --- /dev/null +++ b/drivers/gpu/drm/sitronix/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_DRM_ST7571_I2C) += st7571-i2c.o +obj-$(CONFIG_DRM_ST7586) += st7586.o +obj-$(CONFIG_DRM_ST7735R) += st7735r.o diff --git a/drivers/gpu/drm/tiny/st7571-i2c.c b/drivers/gpu/drm/sitronix/st7571-i2c.c index eec846892962..eec846892962 100644 --- a/drivers/gpu/drm/tiny/st7571-i2c.c +++ b/drivers/gpu/drm/sitronix/st7571-i2c.c diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/sitronix/st7586.c index a29672d84ede..a29672d84ede 100644 --- a/drivers/gpu/drm/tiny/st7586.c +++ b/drivers/gpu/drm/sitronix/st7586.c diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/sitronix/st7735r.c index 1d60f6e5b3bc..1d60f6e5b3bc 100644 --- a/drivers/gpu/drm/tiny/st7735r.c +++ b/drivers/gpu/drm/sitronix/st7735r.c diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index daa1adbb1b43..6d1b3e2cb3fb 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -199,44 +199,3 @@ config TINYDRM_SHARP_MEMORY * 4.40" Sharp Memory LCD (LS044Q7DH01) If M is selected the module will be called sharp_memory. - -config TINYDRM_ST7586 - tristate "DRM support for Sitronix ST7586 display panels" - depends on DRM && SPI - select DRM_CLIENT_SELECTION - select DRM_KMS_HELPER - select DRM_GEM_DMA_HELPER - select DRM_MIPI_DBI - help - DRM driver for the following Sitronix ST7586 panels: - * LEGO MINDSTORMS EV3 - - If M is selected the module will be called st7586. - -config DRM_ST7571_I2C - tristate "DRM support for Sitronix ST7571 display panels (I2C)" - depends on DRM && I2C && MMU - select DRM_CLIENT_SELECTION - select DRM_GEM_SHMEM_HELPER - select DRM_KMS_HELPER - select REGMAP_I2C - help - DRM driver for Sitronix ST7571 panels controlled over I2C. - - if M is selected the module will be called st7571-i2c. - -config TINYDRM_ST7735R - tristate "DRM support for Sitronix ST7715R/ST7735R display panels" - depends on DRM && SPI - select DRM_CLIENT_SELECTION - select DRM_KMS_HELPER - select DRM_GEM_DMA_HELPER - select DRM_MIPI_DBI - select BACKLIGHT_CLASS_DEVICE - help - DRM driver for Sitronix ST7715R/ST7735R with one of the following - LCDs: - * Jianda JD-T18003-T01 1.8" 128x160 TFT - * Okaya RH128128T 1.44" 128x128 TFT - - If M is selected the module will be called st7735r. diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile index 0151590db5cb..4a9ff61ec254 100644 --- a/drivers/gpu/drm/tiny/Makefile +++ b/drivers/gpu/drm/tiny/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_DRM_BOCHS) += bochs.o obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus-qemu.o obj-$(CONFIG_DRM_GM12U320) += gm12u320.o obj-$(CONFIG_DRM_PANEL_MIPI_DBI) += panel-mipi-dbi.o -obj-$(CONFIG_DRM_ST7571_I2C) += st7571-i2c.o obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o obj-$(CONFIG_TINYDRM_ILI9163) += ili9163.o obj-$(CONFIG_TINYDRM_ILI9225) += ili9225.o @@ -15,5 +14,3 @@ obj-$(CONFIG_TINYDRM_ILI9486) += ili9486.o obj-$(CONFIG_TINYDRM_MI0283QT) += mi0283qt.o obj-$(CONFIG_TINYDRM_REPAPER) += repaper.o obj-$(CONFIG_TINYDRM_SHARP_MEMORY) += sharp-memory.o -obj-$(CONFIG_TINYDRM_ST7586) += st7586.o -obj-$(CONFIG_TINYDRM_ST7735R) += st7735r.o diff --git a/drivers/gpu/drm/tiny/cirrus-qemu.c b/drivers/gpu/drm/tiny/cirrus-qemu.c index ccf3f6551344..97a93adc5669 100644 --- a/drivers/gpu/drm/tiny/cirrus-qemu.c +++ b/drivers/gpu/drm/tiny/cirrus-qemu.c @@ -578,7 +578,7 @@ static int cirrus_pci_probe(struct pci_dev *pdev, if (ret) return ret; - ret = pci_request_regions(pdev, DRIVER_NAME); + ret = pcim_request_all_regions(pdev, DRIVER_NAME); if (ret) return ret; diff --git a/drivers/gpu/nova-core/Kconfig b/drivers/gpu/nova-core/Kconfig index ad0c06756516..8726d80d6ba4 100644 --- a/drivers/gpu/nova-core/Kconfig +++ b/drivers/gpu/nova-core/Kconfig @@ -3,6 +3,7 @@ config NOVA_CORE depends on PCI depends on RUST depends on RUST_FW_LOADER_ABSTRACTIONS + select AUXILIARY_BUS default n help Choose this if you want to build the Nova Core driver for Nvidia diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs index a08fb6599267..8c86101c26cb 100644 --- a/drivers/gpu/nova-core/driver.rs +++ b/drivers/gpu/nova-core/driver.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 -use kernel::{bindings, c_str, device::Core, pci, prelude::*}; +use kernel::{auxiliary, bindings, c_str, device::Core, pci, prelude::*}; use crate::gpu::Gpu; @@ -8,6 +8,7 @@ use crate::gpu::Gpu; pub(crate) struct NovaCore { #[pin] pub(crate) gpu: Gpu, + _reg: auxiliary::Registration, } const BAR0_SIZE: usize = 8; @@ -38,6 +39,12 @@ impl pci::Driver for NovaCore { let this = KBox::pin_init( try_pin_init!(Self { gpu <- Gpu::new(pdev, bar)?, + _reg: auxiliary::Registration::new( + pdev.as_ref(), + c_str!("nova-drm"), + 0, // TODO: Once it lands, use XArray; for now we don't use the ID. + crate::MODULE_NAME + )?, }), GFP_KERNEL, )?; diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs index 6e6361c59ca1..4b8a38358a4f 100644 --- a/drivers/gpu/nova-core/firmware.rs +++ b/drivers/gpu/nova-core/firmware.rs @@ -1,13 +1,49 @@ // SPDX-License-Identifier: GPL-2.0 -use crate::gpu; +//! Contains structures and functions dedicated to the parsing, building and patching of firmwares +//! to be loaded into a given execution unit. + +use kernel::device; use kernel::firmware; +use kernel::prelude::*; +use kernel::str::CString; + +use crate::gpu; +use crate::gpu::Chipset; + +pub(crate) const FIRMWARE_VERSION: &str = "535.113.01"; + +/// Structure encapsulating the firmware blobs required for the GPU to operate. +#[expect(dead_code)] +pub(crate) struct Firmware { + booter_load: firmware::Firmware, + booter_unload: firmware::Firmware, + bootloader: firmware::Firmware, + gsp: firmware::Firmware, +} + +impl Firmware { + pub(crate) fn new(dev: &device::Device, chipset: Chipset, ver: &str) -> Result<Firmware> { + let mut chip_name = CString::try_from_fmt(fmt!("{}", chipset))?; + chip_name.make_ascii_lowercase(); + + let request = |name_| { + CString::try_from_fmt(fmt!("nvidia/{}/gsp/{}-{}.bin", &*chip_name, name_, ver)) + .and_then(|path| firmware::Firmware::request(&path, dev)) + }; + + Ok(Firmware { + booter_load: request("booter_load")?, + booter_unload: request("booter_unload")?, + bootloader: request("bootloader")?, + gsp: request("gsp")?, + }) + } +} pub(crate) struct ModInfoBuilder<const N: usize>(firmware::ModInfoBuilder<N>); impl<const N: usize> ModInfoBuilder<N> { - const VERSION: &'static str = "535.113.01"; - const fn make_entry_file(self, chipset: &str, fw: &str) -> Self { ModInfoBuilder( self.0 @@ -17,7 +53,7 @@ impl<const N: usize> ModInfoBuilder<N> { .push("/gsp/") .push(fw) .push("-") - .push(Self::VERSION) + .push(FIRMWARE_VERSION) .push(".bin"), ) } diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index 17c9660da450..99c6796e73e9 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -1,10 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 -use kernel::{ - device, devres::Devres, error::code::*, firmware, fmt, pci, prelude::*, str::CString, -}; +use kernel::{device, devres::Devres, error::code::*, pci, prelude::*}; use crate::driver::Bar0; +use crate::firmware::{Firmware, FIRMWARE_VERSION}; use crate::regs; use crate::util; use core::fmt; @@ -13,7 +12,7 @@ macro_rules! define_chipset { ({ $($variant:ident = $value:expr),* $(,)* }) => { /// Enum representation of the GPU chipset. - #[derive(fmt::Debug)] + #[derive(fmt::Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)] pub(crate) enum Chipset { $($variant = $value),*, } @@ -54,6 +53,7 @@ define_chipset!({ TU117 = 0x167, TU116 = 0x168, // Ampere + GA100 = 0x170, GA102 = 0x172, GA103 = 0x173, GA104 = 0x174, @@ -73,7 +73,7 @@ impl Chipset { Self::TU102 | Self::TU104 | Self::TU106 | Self::TU117 | Self::TU116 => { Architecture::Turing } - Self::GA102 | Self::GA103 | Self::GA104 | Self::GA106 | Self::GA107 => { + Self::GA100 | Self::GA102 | Self::GA103 | Self::GA104 | Self::GA106 | Self::GA107 => { Architecture::Ampere } Self::AD102 | Self::AD103 | Self::AD104 | Self::AD106 | Self::AD107 => { @@ -100,9 +100,22 @@ impl fmt::Display for Chipset { /// Enum representation of the GPU generation. #[derive(fmt::Debug)] pub(crate) enum Architecture { - Turing, - Ampere, - Ada, + Turing = 0x16, + Ampere = 0x17, + Ada = 0x19, +} + +impl TryFrom<u8> for Architecture { + type Error = Error; + + fn try_from(value: u8) -> Result<Self> { + match value { + 0x16 => Ok(Self::Turing), + 0x17 => Ok(Self::Ampere), + 0x19 => Ok(Self::Ada), + _ => Err(ENODEV), + } + } } pub(crate) struct Revision { @@ -111,10 +124,10 @@ pub(crate) struct Revision { } impl Revision { - fn from_boot0(boot0: regs::Boot0) -> Self { + fn from_boot0(boot0: regs::NV_PMC_BOOT_0) -> Self { Self { - major: boot0.major_rev(), - minor: boot0.minor_rev(), + major: boot0.major_revision(), + minor: boot0.minor_revision(), } } } @@ -133,45 +146,16 @@ pub(crate) struct Spec { } impl Spec { - fn new(bar: &Devres<Bar0>) -> Result<Spec> { - let bar = bar.try_access().ok_or(ENXIO)?; - let boot0 = regs::Boot0::read(&bar); + fn new(bar: &Bar0) -> Result<Spec> { + let boot0 = regs::NV_PMC_BOOT_0::read(bar); Ok(Self { - chipset: boot0.chipset().try_into()?, + chipset: boot0.chipset()?, revision: Revision::from_boot0(boot0), }) } } -/// Structure encapsulating the firmware blobs required for the GPU to operate. -#[expect(dead_code)] -pub(crate) struct Firmware { - booter_load: firmware::Firmware, - booter_unload: firmware::Firmware, - bootloader: firmware::Firmware, - gsp: firmware::Firmware, -} - -impl Firmware { - fn new(dev: &device::Device, spec: &Spec, ver: &str) -> Result<Firmware> { - let mut chip_name = CString::try_from_fmt(fmt!("{}", spec.chipset))?; - chip_name.make_ascii_lowercase(); - - let request = |name_| { - CString::try_from_fmt(fmt!("nvidia/{}/gsp/{}-{}.bin", &*chip_name, name_, ver)) - .and_then(|path| firmware::Firmware::request(&path, dev)) - }; - - Ok(Firmware { - booter_load: request("booter_load")?, - booter_unload: request("booter_unload")?, - bootloader: request("bootloader")?, - gsp: request("gsp")?, - }) - } -} - /// Structure holding the resources required to operate the GPU. #[pin_data] pub(crate) struct Gpu { @@ -182,9 +166,13 @@ pub(crate) struct Gpu { } impl Gpu { - pub(crate) fn new(pdev: &pci::Device, bar: Devres<Bar0>) -> Result<impl PinInit<Self>> { - let spec = Spec::new(&bar)?; - let fw = Firmware::new(pdev.as_ref(), &spec, "535.113.01")?; + pub(crate) fn new( + pdev: &pci::Device<device::Bound>, + devres_bar: Devres<Bar0>, + ) -> Result<impl PinInit<Self>> { + let bar = devres_bar.access(pdev.as_ref())?; + let spec = Spec::new(bar)?; + let fw = Firmware::new(pdev.as_ref(), spec.chipset, FIRMWARE_VERSION)?; dev_info!( pdev.as_ref(), @@ -194,6 +182,10 @@ impl Gpu { spec.revision ); - Ok(pin_init!(Self { spec, bar, fw })) + Ok(pin_init!(Self { + spec, + bar: devres_bar, + fw + })) } } diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs index a91cd924054b..618632f0abcc 100644 --- a/drivers/gpu/nova-core/nova_core.rs +++ b/drivers/gpu/nova-core/nova_core.rs @@ -8,6 +8,8 @@ mod gpu; mod regs; mod util; +pub(crate) const MODULE_NAME: &kernel::str::CStr = <LocalModule as kernel::ModuleMetadata>::NAME; + kernel::module_pci_driver! { type: driver::NovaCore, name: "NovaCore", diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs index b1a25b86ef17..5a1273230306 100644 --- a/drivers/gpu/nova-core/regs.rs +++ b/drivers/gpu/nova-core/regs.rs @@ -1,55 +1,39 @@ // SPDX-License-Identifier: GPL-2.0 -use crate::driver::Bar0; - -// TODO -// -// Create register definitions via generic macros. See task "Generic register -// abstraction" in Documentation/gpu/nova/core/todo.rst. - -const BOOT0_OFFSET: usize = 0x00000000; - -// 3:0 - chipset minor revision -const BOOT0_MINOR_REV_SHIFT: u8 = 0; -const BOOT0_MINOR_REV_MASK: u32 = 0x0000000f; - -// 7:4 - chipset major revision -const BOOT0_MAJOR_REV_SHIFT: u8 = 4; -const BOOT0_MAJOR_REV_MASK: u32 = 0x000000f0; - -// 23:20 - chipset implementation Identifier (depends on architecture) -const BOOT0_IMPL_SHIFT: u8 = 20; -const BOOT0_IMPL_MASK: u32 = 0x00f00000; - -// 28:24 - chipset architecture identifier -const BOOT0_ARCH_MASK: u32 = 0x1f000000; - -// 28:20 - chipset identifier (virtual register field combining BOOT0_IMPL and -// BOOT0_ARCH) -const BOOT0_CHIPSET_SHIFT: u8 = BOOT0_IMPL_SHIFT; -const BOOT0_CHIPSET_MASK: u32 = BOOT0_IMPL_MASK | BOOT0_ARCH_MASK; - -#[derive(Copy, Clone)] -pub(crate) struct Boot0(u32); - -impl Boot0 { - #[inline] - pub(crate) fn read(bar: &Bar0) -> Self { - Self(bar.read32(BOOT0_OFFSET)) - } - - #[inline] - pub(crate) fn chipset(&self) -> u32 { - (self.0 & BOOT0_CHIPSET_MASK) >> BOOT0_CHIPSET_SHIFT - } - - #[inline] - pub(crate) fn minor_rev(&self) -> u8 { - ((self.0 & BOOT0_MINOR_REV_MASK) >> BOOT0_MINOR_REV_SHIFT) as u8 +// Required to retain the original register names used by OpenRM, which are all capital snake case +// but are mapped to types. +#![allow(non_camel_case_types)] + +#[macro_use] +mod macros; + +use crate::gpu::{Architecture, Chipset}; +use kernel::prelude::*; + +/* PMC */ + +register!(NV_PMC_BOOT_0 @ 0x00000000, "Basic revision information about the GPU" { + 3:0 minor_revision as u8, "Minor revision of the chip"; + 7:4 major_revision as u8, "Major revision of the chip"; + 8:8 architecture_1 as u8, "MSB of the architecture"; + 23:20 implementation as u8, "Implementation version of the architecture"; + 28:24 architecture_0 as u8, "Lower bits of the architecture"; +}); + +impl NV_PMC_BOOT_0 { + /// Combines `architecture_0` and `architecture_1` to obtain the architecture of the chip. + pub(crate) fn architecture(self) -> Result<Architecture> { + Architecture::try_from( + self.architecture_0() | (self.architecture_1() << Self::ARCHITECTURE_0.len()), + ) } - #[inline] - pub(crate) fn major_rev(&self) -> u8 { - ((self.0 & BOOT0_MAJOR_REV_MASK) >> BOOT0_MAJOR_REV_SHIFT) as u8 + /// Combines `architecture` and `implementation` to obtain a code unique to the chipset. + pub(crate) fn chipset(self) -> Result<Chipset> { + self.architecture() + .map(|arch| { + ((arch as u32) << Self::IMPLEMENTATION.len()) | self.implementation() as u32 + }) + .and_then(Chipset::try_from) } } diff --git a/drivers/gpu/nova-core/regs/macros.rs b/drivers/gpu/nova-core/regs/macros.rs new file mode 100644 index 000000000000..7ecc70efb3cd --- /dev/null +++ b/drivers/gpu/nova-core/regs/macros.rs @@ -0,0 +1,380 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Macro to define register layout and accessors. +//! +//! A single register typically includes several fields, which are accessed through a combination +//! of bit-shift and mask operations that introduce a class of potential mistakes, notably because +//! not all possible field values are necessarily valid. +//! +//! The macro in this module allow to define, using an intruitive and readable syntax, a dedicated +//! type for each register with its own field accessors that can return an error is a field's value +//! is invalid. + +/// Defines a dedicated type for a register with an absolute offset, alongside with getter and +/// setter methods for its fields and methods to read and write it from an `Io` region. +/// +/// Example: +/// +/// ```no_run +/// register!(BOOT_0 @ 0x00000100, "Basic revision information about the GPU" { +/// 3:0 minor_revision as u8, "Minor revision of the chip"; +/// 7:4 major_revision as u8, "Major revision of the chip"; +/// 28:20 chipset as u32 ?=> Chipset, "Chipset model"; +/// }); +/// ``` +/// +/// This defines a `BOOT_0` type which can be read or written from offset `0x100` of an `Io` +/// region. It is composed of 3 fields, for instance `minor_revision` is made of the 4 less +/// significant bits of the register. Each field can be accessed and modified using accessor +/// methods: +/// +/// ```no_run +/// // Read from the register's defined offset (0x100). +/// let boot0 = BOOT_0::read(&bar); +/// pr_info!("chip revision: {}.{}", boot0.major_revision(), boot0.minor_revision()); +/// +/// // `Chipset::try_from` will be called with the value of the field and returns an error if the +/// // value is invalid. +/// let chipset = boot0.chipset()?; +/// +/// // Update some fields and write the value back. +/// boot0.set_major_revision(3).set_minor_revision(10).write(&bar); +/// +/// // Or just read and update the register in a single step: +/// BOOT_0::alter(&bar, |r| r.set_major_revision(3).set_minor_revision(10)); +/// ``` +/// +/// Fields can be defined as follows: +/// +/// - `as <type>` simply returns the field value casted as the requested integer type, typically +/// `u32`, `u16`, `u8` or `bool`. Note that `bool` fields must have a range of 1 bit. +/// - `as <type> => <into_type>` calls `<into_type>`'s `From::<<type>>` implementation and returns +/// the result. +/// - `as <type> ?=> <try_into_type>` calls `<try_into_type>`'s `TryFrom::<<type>>` implementation +/// and returns the result. This is useful on fields for which not all values are value. +/// +/// The documentation strings are optional. If present, they will be added to the type's +/// definition, or the field getter and setter methods they are attached to. +/// +/// Putting a `+` before the address of the register makes it relative to a base: the `read` and +/// `write` methods take a `base` argument that is added to the specified address before access, +/// and `try_read` and `try_write` methods are also created, allowing access with offsets unknown +/// at compile-time: +/// +/// ```no_run +/// register!(CPU_CTL @ +0x0000010, "CPU core control" { +/// 0:0 start as bool, "Start the CPU core"; +/// }); +/// +/// // Flip the `start` switch for the CPU core which base address is at `CPU_BASE`. +/// let cpuctl = CPU_CTL::read(&bar, CPU_BASE); +/// pr_info!("CPU CTL: {:#x}", cpuctl); +/// cpuctl.set_start(true).write(&bar, CPU_BASE); +/// ``` +macro_rules! register { + // Creates a register at a fixed offset of the MMIO space. + ( + $name:ident @ $offset:literal $(, $comment:literal)? { + $($fields:tt)* + } + ) => { + register!(@common $name $(, $comment)?); + register!(@field_accessors $name { $($fields)* }); + register!(@io $name @ $offset); + }; + + // Creates a register at a relative offset from a base address. + ( + $name:ident @ + $offset:literal $(, $comment:literal)? { + $($fields:tt)* + } + ) => { + register!(@common $name $(, $comment)?); + register!(@field_accessors $name { $($fields)* }); + register!(@io$name @ + $offset); + }; + + // Defines the wrapper `$name` type, as well as its relevant implementations (`Debug`, `BitOr`, + // and conversion to regular `u32`). + (@common $name:ident $(, $comment:literal)?) => { + $( + #[doc=$comment] + )? + #[repr(transparent)] + #[derive(Clone, Copy, Default)] + pub(crate) struct $name(u32); + + // TODO: display the raw hex value, then the value of all the fields. This requires + // matching the fields, which will complexify the syntax considerably... + impl ::core::fmt::Debug for $name { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_tuple(stringify!($name)) + .field(&format_args!("0x{0:x}", &self.0)) + .finish() + } + } + + impl core::ops::BitOr for $name { + type Output = Self; + + fn bitor(self, rhs: Self) -> Self::Output { + Self(self.0 | rhs.0) + } + } + + impl ::core::convert::From<$name> for u32 { + fn from(reg: $name) -> u32 { + reg.0 + } + } + }; + + // Defines all the field getter/methods methods for `$name`. + ( + @field_accessors $name:ident { + $($hi:tt:$lo:tt $field:ident as $type:tt + $(?=> $try_into_type:ty)? + $(=> $into_type:ty)? + $(, $comment:literal)? + ; + )* + } + ) => { + $( + register!(@check_field_bounds $hi:$lo $field as $type); + )* + + #[allow(dead_code)] + impl $name { + $( + register!(@field_accessor $name $hi:$lo $field as $type + $(?=> $try_into_type)? + $(=> $into_type)? + $(, $comment)? + ; + ); + )* + } + }; + + // Boolean fields must have `$hi == $lo`. + (@check_field_bounds $hi:tt:$lo:tt $field:ident as bool) => { + #[allow(clippy::eq_op)] + const _: () = { + kernel::build_assert!( + $hi == $lo, + concat!("boolean field `", stringify!($field), "` covers more than one bit") + ); + }; + }; + + // Non-boolean fields must have `$hi >= $lo`. + (@check_field_bounds $hi:tt:$lo:tt $field:ident as $type:tt) => { + #[allow(clippy::eq_op)] + const _: () = { + kernel::build_assert!( + $hi >= $lo, + concat!("field `", stringify!($field), "`'s MSB is smaller than its LSB") + ); + }; + }; + + // Catches fields defined as `bool` and convert them into a boolean value. + ( + @field_accessor $name:ident $hi:tt:$lo:tt $field:ident as bool => $into_type:ty + $(, $comment:literal)?; + ) => { + register!( + @leaf_accessor $name $hi:$lo $field as bool + { |f| <$into_type>::from(if f != 0 { true } else { false }) } + $into_type => $into_type $(, $comment)?; + ); + }; + + // Shortcut for fields defined as `bool` without the `=>` syntax. + ( + @field_accessor $name:ident $hi:tt:$lo:tt $field:ident as bool $(, $comment:literal)?; + ) => { + register!(@field_accessor $name $hi:$lo $field as bool => bool $(, $comment)?;); + }; + + // Catches the `?=>` syntax for non-boolean fields. + ( + @field_accessor $name:ident $hi:tt:$lo:tt $field:ident as $type:tt ?=> $try_into_type:ty + $(, $comment:literal)?; + ) => { + register!(@leaf_accessor $name $hi:$lo $field as $type + { |f| <$try_into_type>::try_from(f as $type) } $try_into_type => + ::core::result::Result< + $try_into_type, + <$try_into_type as ::core::convert::TryFrom<$type>>::Error + > + $(, $comment)?;); + }; + + // Catches the `=>` syntax for non-boolean fields. + ( + @field_accessor $name:ident $hi:tt:$lo:tt $field:ident as $type:tt => $into_type:ty + $(, $comment:literal)?; + ) => { + register!(@leaf_accessor $name $hi:$lo $field as $type + { |f| <$into_type>::from(f as $type) } $into_type => $into_type $(, $comment)?;); + }; + + // Shortcut for fields defined as non-`bool` without the `=>` or `?=>` syntax. + ( + @field_accessor $name:ident $hi:tt:$lo:tt $field:ident as $type:tt + $(, $comment:literal)?; + ) => { + register!(@field_accessor $name $hi:$lo $field as $type => $type $(, $comment)?;); + }; + + // Generates the accessor methods for a single field. + ( + @leaf_accessor $name:ident $hi:tt:$lo:tt $field:ident as $type:ty + { $process:expr } $to_type:ty => $res_type:ty $(, $comment:literal)?; + ) => { + kernel::macros::paste!( + const [<$field:upper>]: ::core::ops::RangeInclusive<u8> = $lo..=$hi; + const [<$field:upper _MASK>]: u32 = ((((1 << $hi) - 1) << 1) + 1) - ((1 << $lo) - 1); + const [<$field:upper _SHIFT>]: u32 = Self::[<$field:upper _MASK>].trailing_zeros(); + ); + + $( + #[doc="Returns the value of this field:"] + #[doc=$comment] + )? + #[inline] + pub(crate) fn $field(self) -> $res_type { + kernel::macros::paste!( + const MASK: u32 = $name::[<$field:upper _MASK>]; + const SHIFT: u32 = $name::[<$field:upper _SHIFT>]; + ); + let field = ((self.0 & MASK) >> SHIFT); + + $process(field) + } + + kernel::macros::paste!( + $( + #[doc="Sets the value of this field:"] + #[doc=$comment] + )? + #[inline] + pub(crate) fn [<set_ $field>](mut self, value: $to_type) -> Self { + const MASK: u32 = $name::[<$field:upper _MASK>]; + const SHIFT: u32 = $name::[<$field:upper _SHIFT>]; + let value = ((value as u32) << SHIFT) & MASK; + self.0 = (self.0 & !MASK) | value; + + self + } + ); + }; + + // Creates the IO accessors for a fixed offset register. + (@io $name:ident @ $offset:literal) => { + #[allow(dead_code)] + impl $name { + #[inline] + pub(crate) fn read<const SIZE: usize, T>(io: &T) -> Self where + T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>, + { + Self(io.read32($offset)) + } + + #[inline] + pub(crate) fn write<const SIZE: usize, T>(self, io: &T) where + T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>, + { + io.write32(self.0, $offset) + } + + #[inline] + pub(crate) fn alter<const SIZE: usize, T, F>( + io: &T, + f: F, + ) where + T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>, + F: ::core::ops::FnOnce(Self) -> Self, + { + let reg = f(Self::read(io)); + reg.write(io); + } + } + }; + + // Create the IO accessors for a relative offset register. + (@io $name:ident @ + $offset:literal) => { + #[allow(dead_code)] + impl $name { + #[inline] + pub(crate) fn read<const SIZE: usize, T>( + io: &T, + base: usize, + ) -> Self where + T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>, + { + Self(io.read32(base + $offset)) + } + + #[inline] + pub(crate) fn write<const SIZE: usize, T>( + self, + io: &T, + base: usize, + ) where + T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>, + { + io.write32(self.0, base + $offset) + } + + #[inline] + pub(crate) fn alter<const SIZE: usize, T, F>( + io: &T, + base: usize, + f: F, + ) where + T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>, + F: ::core::ops::FnOnce(Self) -> Self, + { + let reg = f(Self::read(io, base)); + reg.write(io, base); + } + + #[inline] + pub(crate) fn try_read<const SIZE: usize, T>( + io: &T, + base: usize, + ) -> ::kernel::error::Result<Self> where + T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>, + { + io.try_read32(base + $offset).map(Self) + } + + #[inline] + pub(crate) fn try_write<const SIZE: usize, T>( + self, + io: &T, + base: usize, + ) -> ::kernel::error::Result<()> where + T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>, + { + io.try_write32(self.0, base + $offset) + } + + #[inline] + pub(crate) fn try_alter<const SIZE: usize, T, F>( + io: &T, + base: usize, + f: F, + ) -> ::kernel::error::Result<()> where + T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>, + F: ::core::ops::FnOnce(Self) -> Self, + { + let reg = f(Self::try_read(io, base)?); + reg.try_write(io, base) + } + } + }; +} diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 7b19192c7031..e4ca35143ff9 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -518,6 +518,11 @@ struct drm_dp_aux { * @powered_down: If true then the remote endpoint is powered down. */ bool powered_down; + + /** + * @no_zero_sized: If the hw can't use zero sized transfers (NVIDIA) + */ + bool no_zero_sized; }; int drm_dp_dpcd_probe(struct drm_dp_aux *aux, unsigned int offset); diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index a43d707b5f36..63b51942d606 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -473,6 +473,11 @@ drmm_cgroup_register_region(struct drm_device *dev, struct drm_device *drm_dev_alloc(const struct drm_driver *driver, struct device *parent); + +void *__drm_dev_alloc(struct device *parent, + const struct drm_driver *driver, + size_t size, size_t offset); + int drm_dev_register(struct drm_device *dev, unsigned long flags); void drm_dev_unregister(struct drm_device *dev); diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 4b8f0370b79b..9e524b51a001 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -937,6 +937,12 @@ struct drm_mode_config { struct drm_property *modifiers_property; /** + * @async_modifiers_property: Plane property to list support modifier/format + * combination for asynchronous flips. + */ + struct drm_property *async_modifiers_property; + + /** * @size_hints_property: Plane SIZE_HINTS property. */ struct drm_property *size_hints_property; diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index dd718c62ac31..01479dd94e76 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -549,6 +549,23 @@ struct drm_plane_funcs { */ bool (*format_mod_supported)(struct drm_plane *plane, uint32_t format, uint64_t modifier); + /** + * @format_mod_supported_async: + * + * This optional hook is used for the DRM to determine if for + * asynchronous flip the given format/modifier combination is valid for + * the plane. This allows the DRM to generate the correct format + * bitmask (which formats apply to which modifier), and to validate + * modifiers at atomic_check time. + * + * Returns: + * + * True if the given modifier is valid for that format on the plane. + * False otherwise. + */ + bool (*format_mod_supported_async)(struct drm_plane *plane, + u32 format, u64 modifier); + }; /** diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 1fd96474e64c..45c4fa13499c 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -1368,6 +1368,7 @@ struct drm_amdgpu_info_vbios { #define AMDGPU_VRAM_TYPE_DDR5 10 #define AMDGPU_VRAM_TYPE_LPDDR4 11 #define AMDGPU_VRAM_TYPE_LPDDR5 12 +#define AMDGPU_VRAM_TYPE_HBM3E 13 struct drm_amdgpu_info_device { /** PCI Device ID */ diff --git a/include/uapi/drm/nova_drm.h b/include/uapi/drm/nova_drm.h new file mode 100644 index 000000000000..3ca90ed9d2bb --- /dev/null +++ b/include/uapi/drm/nova_drm.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef __NOVA_DRM_H__ +#define __NOVA_DRM_H__ + +#include "drm.h" + +/* DISCLAIMER: Do not use, this is not a stable uAPI. + * + * This uAPI serves only testing purposes as long as this driver is still in + * development. It is required to implement and test infrastructure which is + * upstreamed in the context of this driver. See also [1]. + * + * [1] https://lore.kernel.org/dri-devel/Zfsj0_tb-0-tNrJy@cassiopeiae/T/#u + */ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * NOVA_GETPARAM_VRAM_BAR_SIZE + * + * Query the VRAM BAR size in bytes. + */ +#define NOVA_GETPARAM_VRAM_BAR_SIZE 0x1 + +/** + * struct drm_nova_getparam - query GPU and driver metadata + */ +struct drm_nova_getparam { + /** + * @param: The identifier of the parameter to query. + */ + __u64 param; + + /** + * @value: The value for the specified parameter. + */ + __u64 value; +}; + +/** + * struct drm_nova_gem_create - create a new DRM GEM object + */ +struct drm_nova_gem_create { + /** + * @handle: The handle of the new DRM GEM object. + */ + __u32 handle; + + /** + * @pad: 32 bit padding, should be 0. + */ + __u32 pad; + + /** + * @size: The size of the new DRM GEM object. + */ + __u64 size; +}; + +/** + * struct drm_nova_gem_info - query DRM GEM object metadata + */ +struct drm_nova_gem_info { + /** + * @handle: The handle of the DRM GEM object to query. + */ + __u32 handle; + + /** + * @pad: 32 bit padding, should be 0. + */ + __u32 pad; + + /** + * @size: The size of the DRM GEM obejct. + */ + __u64 size; +}; + +#define DRM_NOVA_GETPARAM 0x00 +#define DRM_NOVA_GEM_CREATE 0x01 +#define DRM_NOVA_GEM_INFO 0x02 + +/* Note: this is an enum so that it can be resolved by Rust bindgen. */ +enum { + DRM_IOCTL_NOVA_GETPARAM = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_GETPARAM, + struct drm_nova_getparam), + DRM_IOCTL_NOVA_GEM_CREATE = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_GEM_CREATE, + struct drm_nova_gem_create), + DRM_IOCTL_NOVA_GEM_INFO = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_GEM_INFO, + struct drm_nova_gem_info), +}; + +#if defined(__cplusplus) +} +#endif + +#endif /* __NOVA_DRM_H__ */ diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index ab37e1d35c70..e0676ba99d37 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -6,7 +6,13 @@ * Sorted alphabetically. */ +#include <drm/drm_device.h> +#include <drm/drm_drv.h> +#include <drm/drm_file.h> +#include <drm/drm_gem.h> +#include <drm/drm_ioctl.h> #include <kunit/test.h> +#include <linux/auxiliary_bus.h> #include <linux/blk-mq.h> #include <linux/blk_types.h> #include <linux/blkdev.h> @@ -55,3 +61,4 @@ const gfp_t RUST_CONST_HELPER___GFP_ZERO = __GFP_ZERO; const gfp_t RUST_CONST_HELPER___GFP_HIGHMEM = ___GFP_HIGHMEM; const gfp_t RUST_CONST_HELPER___GFP_NOWARN = ___GFP_NOWARN; const blk_features_t RUST_CONST_HELPER_BLK_FEAT_ROTATIONAL = BLK_FEAT_ROTATIONAL; +const fop_flags_t RUST_CONST_HELPER_FOP_UNSIGNED_OFFSET = FOP_UNSIGNED_OFFSET; diff --git a/rust/helpers/auxiliary.c b/rust/helpers/auxiliary.c new file mode 100644 index 000000000000..0db3860d774e --- /dev/null +++ b/rust/helpers/auxiliary.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/auxiliary_bus.h> + +void rust_helper_auxiliary_set_drvdata(struct auxiliary_device *adev, void *data) +{ + auxiliary_set_drvdata(adev, data); +} + +void *rust_helper_auxiliary_get_drvdata(struct auxiliary_device *adev) +{ + return auxiliary_get_drvdata(adev); +} + +void rust_helper_auxiliary_device_uninit(struct auxiliary_device *adev) +{ + return auxiliary_device_uninit(adev); +} + +void rust_helper_auxiliary_device_delete(struct auxiliary_device *adev) +{ + return auxiliary_device_delete(adev); +} diff --git a/rust/helpers/drm.c b/rust/helpers/drm.c new file mode 100644 index 000000000000..450b406c6f27 --- /dev/null +++ b/rust/helpers/drm.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <drm/drm_gem.h> +#include <drm/drm_vma_manager.h> + +#ifdef CONFIG_DRM + +void rust_helper_drm_gem_object_get(struct drm_gem_object *obj) +{ + drm_gem_object_get(obj); +} + +void rust_helper_drm_gem_object_put(struct drm_gem_object *obj) +{ + drm_gem_object_put(obj); +} + +__u64 rust_helper_drm_vma_node_offset_addr(struct drm_vma_offset_node *node) +{ + return drm_vma_node_offset_addr(node); +} + +#endif diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index 1e7c84df7252..c228a5363212 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -7,6 +7,7 @@ * Sorted alphabetically. */ +#include "auxiliary.c" #include "blk.c" #include "bug.c" #include "build_assert.c" @@ -15,6 +16,7 @@ #include "cred.c" #include "device.c" #include "dma.c" +#include "drm.c" #include "err.c" #include "fs.c" #include "io.c" diff --git a/rust/helpers/pci.c b/rust/helpers/pci.c index 8ba22f911459..cd0e6bf2cc4d 100644 --- a/rust/helpers/pci.c +++ b/rust/helpers/pci.c @@ -16,3 +16,8 @@ resource_size_t rust_helper_pci_resource_len(struct pci_dev *pdev, int bar) { return pci_resource_len(pdev, bar); } + +bool rust_helper_dev_is_pci(const struct device *dev) +{ + return dev_is_pci(dev); +} diff --git a/rust/helpers/platform.c b/rust/helpers/platform.c index ab9b9f317301..82171233d12f 100644 --- a/rust/helpers/platform.c +++ b/rust/helpers/platform.c @@ -11,3 +11,8 @@ void rust_helper_platform_set_drvdata(struct platform_device *pdev, void *data) { platform_set_drvdata(pdev, data); } + +bool rust_helper_dev_is_platform(const struct device *dev) +{ + return dev_is_platform(dev); +} diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs new file mode 100644 index 000000000000..5c072960dee0 --- /dev/null +++ b/rust/kernel/auxiliary.rs @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Abstractions for the auxiliary bus. +//! +//! C header: [`include/linux/auxiliary_bus.h`](srctree/include/linux/auxiliary_bus.h) + +use crate::{ + bindings, container_of, device, + device_id::RawDeviceId, + driver, + error::{to_result, Result}, + prelude::*, + str::CStr, + types::{ForeignOwnable, Opaque}, + ThisModule, +}; +use core::{ + marker::PhantomData, + ptr::{addr_of_mut, NonNull}, +}; + +/// An adapter for the registration of auxiliary drivers. +pub struct Adapter<T: Driver>(T); + +// SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if +// a preceding call to `register` has been successful. +unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { + type RegType = bindings::auxiliary_driver; + + unsafe fn register( + adrv: &Opaque<Self::RegType>, + name: &'static CStr, + module: &'static ThisModule, + ) -> Result { + // SAFETY: It's safe to set the fields of `struct auxiliary_driver` on initialization. + unsafe { + (*adrv.get()).name = name.as_char_ptr(); + (*adrv.get()).probe = Some(Self::probe_callback); + (*adrv.get()).remove = Some(Self::remove_callback); + (*adrv.get()).id_table = T::ID_TABLE.as_ptr(); + } + + // SAFETY: `adrv` is guaranteed to be a valid `RegType`. + to_result(unsafe { + bindings::__auxiliary_driver_register(adrv.get(), module.0, name.as_char_ptr()) + }) + } + + unsafe fn unregister(adrv: &Opaque<Self::RegType>) { + // SAFETY: `adrv` is guaranteed to be a valid `RegType`. + unsafe { bindings::auxiliary_driver_unregister(adrv.get()) } + } +} + +impl<T: Driver + 'static> Adapter<T> { + extern "C" fn probe_callback( + adev: *mut bindings::auxiliary_device, + id: *const bindings::auxiliary_device_id, + ) -> kernel::ffi::c_int { + // SAFETY: The auxiliary bus only ever calls the probe callback with a valid pointer to a + // `struct auxiliary_device`. + // + // INVARIANT: `adev` is valid for the duration of `probe_callback()`. + let adev = unsafe { &*adev.cast::<Device<device::Core>>() }; + + // SAFETY: `DeviceId` is a `#[repr(transparent)`] wrapper of `struct auxiliary_device_id` + // and does not add additional invariants, so it's safe to transmute. + let id = unsafe { &*id.cast::<DeviceId>() }; + let info = T::ID_TABLE.info(id.index()); + + match T::probe(adev, info) { + Ok(data) => { + // Let the `struct auxiliary_device` own a reference of the driver's private data. + // SAFETY: By the type invariant `adev.as_raw` returns a valid pointer to a + // `struct auxiliary_device`. + unsafe { bindings::auxiliary_set_drvdata(adev.as_raw(), data.into_foreign()) }; + } + Err(err) => return Error::to_errno(err), + } + + 0 + } + + extern "C" fn remove_callback(adev: *mut bindings::auxiliary_device) { + // SAFETY: The auxiliary bus only ever calls the remove callback with a valid pointer to a + // `struct auxiliary_device`. + let ptr = unsafe { bindings::auxiliary_get_drvdata(adev) }; + + // SAFETY: `remove_callback` is only ever called after a successful call to + // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized + // `KBox<T>` pointer created through `KBox::into_foreign`. + drop(unsafe { KBox::<T>::from_foreign(ptr) }); + } +} + +/// Declares a kernel module that exposes a single auxiliary driver. +#[macro_export] +macro_rules! module_auxiliary_driver { + ($($f:tt)*) => { + $crate::module_driver!(<T>, $crate::auxiliary::Adapter<T>, { $($f)* }); + }; +} + +/// Abstraction for `bindings::auxiliary_device_id`. +#[repr(transparent)] +#[derive(Clone, Copy)] +pub struct DeviceId(bindings::auxiliary_device_id); + +impl DeviceId { + /// Create a new [`DeviceId`] from name. + pub const fn new(modname: &'static CStr, name: &'static CStr) -> Self { + let name = name.as_bytes_with_nul(); + let modname = modname.as_bytes_with_nul(); + + // TODO: Replace with `bindings::auxiliary_device_id::default()` once stabilized for + // `const`. + // + // SAFETY: FFI type is valid to be zero-initialized. + let mut id: bindings::auxiliary_device_id = unsafe { core::mem::zeroed() }; + + let mut i = 0; + while i < modname.len() { + id.name[i] = modname[i]; + i += 1; + } + + // Reuse the space of the NULL terminator. + id.name[i - 1] = b'.'; + + let mut j = 0; + while j < name.len() { + id.name[i] = name[j]; + i += 1; + j += 1; + } + + Self(id) + } +} + +// SAFETY: +// * `DeviceId` is a `#[repr(transparent)`] wrapper of `auxiliary_device_id` and does not add +// additional invariants, so it's safe to transmute to `RawType`. +// * `DRIVER_DATA_OFFSET` is the offset to the `driver_data` field. +unsafe impl RawDeviceId for DeviceId { + type RawType = bindings::auxiliary_device_id; + + const DRIVER_DATA_OFFSET: usize = + core::mem::offset_of!(bindings::auxiliary_device_id, driver_data); + + fn index(&self) -> usize { + self.0.driver_data + } +} + +/// IdTable type for auxiliary drivers. +pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>; + +/// Create a auxiliary `IdTable` with its alias for modpost. +#[macro_export] +macro_rules! auxiliary_device_table { + ($table_name:ident, $module_table_name:ident, $id_info_type: ty, $table_data: expr) => { + const $table_name: $crate::device_id::IdArray< + $crate::auxiliary::DeviceId, + $id_info_type, + { $table_data.len() }, + > = $crate::device_id::IdArray::new($table_data); + + $crate::module_device_table!("auxiliary", $module_table_name, $table_name); + }; +} + +/// The auxiliary driver trait. +/// +/// Drivers must implement this trait in order to get an auxiliary driver registered. +pub trait Driver { + /// The type holding information about each device id supported by the driver. + /// + /// TODO: Use associated_type_defaults once stabilized: + /// + /// type IdInfo: 'static = (); + type IdInfo: 'static; + + /// The table of device ids supported by the driver. + const ID_TABLE: IdTable<Self::IdInfo>; + + /// Auxiliary driver probe. + /// + /// Called when an auxiliary device is matches a corresponding driver. + fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> Result<Pin<KBox<Self>>>; +} + +/// The auxiliary device representation. +/// +/// This structure represents the Rust abstraction for a C `struct auxiliary_device`. The +/// implementation abstracts the usage of an already existing C `struct auxiliary_device` within +/// Rust code that we get passed from the C side. +/// +/// # Invariants +/// +/// A [`Device`] instance represents a valid `struct auxiliary_device` created by the C portion of +/// the kernel. +#[repr(transparent)] +pub struct Device<Ctx: device::DeviceContext = device::Normal>( + Opaque<bindings::auxiliary_device>, + PhantomData<Ctx>, +); + +impl<Ctx: device::DeviceContext> Device<Ctx> { + fn as_raw(&self) -> *mut bindings::auxiliary_device { + self.0.get() + } + + /// Returns the auxiliary device' id. + pub fn id(&self) -> u32 { + // SAFETY: By the type invariant `self.as_raw()` is a valid pointer to a + // `struct auxiliary_device`. + unsafe { (*self.as_raw()).id } + } + + /// Returns a reference to the parent [`device::Device`], if any. + pub fn parent(&self) -> Option<&device::Device> { + let ptr: *const Self = self; + // CAST: `Device<Ctx: DeviceContext>` types are transparent to each other. + let ptr: *const Device = ptr.cast(); + // SAFETY: `ptr` was derived from `&self`. + let this = unsafe { &*ptr }; + + this.as_ref().parent() + } +} + +impl Device { + extern "C" fn release(dev: *mut bindings::device) { + // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device` + // embedded in `struct auxiliary_device`. + let adev = unsafe { container_of!(dev, bindings::auxiliary_device, dev) }.cast_mut(); + + // SAFETY: `adev` points to the memory that has been allocated in `Registration::new`, via + // `KBox::new(Opaque::<bindings::auxiliary_device>::zeroed(), GFP_KERNEL)`. + let _ = unsafe { KBox::<Opaque<bindings::auxiliary_device>>::from_raw(adev.cast()) }; + } +} + +// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic +// argument. +kernel::impl_device_context_deref!(unsafe { Device }); +kernel::impl_device_context_into_aref!(Device); + +// SAFETY: Instances of `Device` are always reference-counted. +unsafe impl crate::types::AlwaysRefCounted for Device { + fn inc_ref(&self) { + // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. + unsafe { bindings::get_device(self.as_ref().as_raw()) }; + } + + unsafe fn dec_ref(obj: NonNull<Self>) { + // CAST: `Self` a transparent wrapper of `bindings::auxiliary_device`. + let adev: *mut bindings::auxiliary_device = obj.cast().as_ptr(); + + // SAFETY: By the type invariant of `Self`, `adev` is a pointer to a valid + // `struct auxiliary_device`. + let dev = unsafe { addr_of_mut!((*adev).dev) }; + + // SAFETY: The safety requirements guarantee that the refcount is non-zero. + unsafe { bindings::put_device(dev) } + } +} + +impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> { + fn as_ref(&self) -> &device::Device<Ctx> { + // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid + // `struct auxiliary_device`. + let dev = unsafe { addr_of_mut!((*self.as_raw()).dev) }; + + // SAFETY: `dev` points to a valid `struct device`. + unsafe { device::Device::as_ref(dev) } + } +} + +// SAFETY: A `Device` is always reference-counted and can be released from any thread. +unsafe impl Send for Device {} + +// SAFETY: `Device` can be shared among threads because all methods of `Device` +// (i.e. `Device<Normal>) are thread safe. +unsafe impl Sync for Device {} + +/// The registration of an auxiliary device. +/// +/// This type represents the registration of a [`struct auxiliary_device`]. When an instance of this +/// type is dropped, its respective auxiliary device will be unregistered from the system. +/// +/// # Invariants +/// +/// `self.0` always holds a valid pointer to an initialized and registered +/// [`struct auxiliary_device`]. +pub struct Registration(NonNull<bindings::auxiliary_device>); + +impl Registration { + /// Create and register a new auxiliary device. + pub fn new(parent: &device::Device, name: &CStr, id: u32, modname: &CStr) -> Result<Self> { + let boxed = KBox::new(Opaque::<bindings::auxiliary_device>::zeroed(), GFP_KERNEL)?; + let adev = boxed.get(); + + // SAFETY: It's safe to set the fields of `struct auxiliary_device` on initialization. + unsafe { + (*adev).dev.parent = parent.as_raw(); + (*adev).dev.release = Some(Device::release); + (*adev).name = name.as_char_ptr(); + (*adev).id = id; + } + + // SAFETY: `adev` is guaranteed to be a valid pointer to a `struct auxiliary_device`, + // which has not been initialized yet. + unsafe { bindings::auxiliary_device_init(adev) }; + + // Now that `adev` is initialized, leak the `Box`; the corresponding memory will be freed + // by `Device::release` when the last reference to the `struct auxiliary_device` is dropped. + let _ = KBox::into_raw(boxed); + + // SAFETY: + // - `adev` is guaranteed to be a valid pointer to a `struct auxiliary_device`, which has + // been initialialized, + // - `modname.as_char_ptr()` is a NULL terminated string. + let ret = unsafe { bindings::__auxiliary_device_add(adev, modname.as_char_ptr()) }; + if ret != 0 { + // SAFETY: `adev` is guaranteed to be a valid pointer to a `struct auxiliary_device`, + // which has been initialialized. + unsafe { bindings::auxiliary_device_uninit(adev) }; + + return Err(Error::from_errno(ret)); + } + + // SAFETY: `adev` is guaranteed to be non-null, since the `KBox` was allocated successfully. + // + // INVARIANT: The device will remain registered until `auxiliary_device_delete()` is called, + // which happens in `Self::drop()`. + Ok(Self(unsafe { NonNull::new_unchecked(adev) })) + } +} + +impl Drop for Registration { + fn drop(&mut self) { + // SAFETY: By the type invariant of `Self`, `self.0.as_ptr()` is a valid registered + // `struct auxiliary_device`. + unsafe { bindings::auxiliary_device_delete(self.0.as_ptr()) }; + + // This drops the reference we acquired through `auxiliary_device_init()`. + // + // SAFETY: By the type invariant of `Self`, `self.0.as_ptr()` is a valid registered + // `struct auxiliary_device`. + unsafe { bindings::auxiliary_device_uninit(self.0.as_ptr()) }; + } +} + +// SAFETY: A `Registration` of a `struct auxiliary_device` can be released from any thread. +unsafe impl Send for Registration {} + +// SAFETY: `Registration` does not expose any methods or fields that need synchronization. +unsafe impl Sync for Registration {} diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index 21b343a1dc4d..f08583fa39c9 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -9,7 +9,7 @@ use crate::{ str::CStr, types::{ARef, Opaque}, }; -use core::{fmt, ptr}; +use core::{fmt, marker::PhantomData, ptr}; #[cfg(CONFIG_PRINTK)] use crate::c_str; @@ -42,7 +42,7 @@ use crate::c_str; /// `bindings::device::release` is valid to be called from any thread, hence `ARef<Device>` can be /// dropped from any thread. #[repr(transparent)] -pub struct Device(Opaque<bindings::device>); +pub struct Device<Ctx: DeviceContext = Normal>(Opaque<bindings::device>, PhantomData<Ctx>); impl Device { /// Creates a new reference-counted abstraction instance of an existing `struct device` pointer. @@ -59,12 +59,33 @@ impl Device { // SAFETY: By the safety requirements ptr is valid unsafe { Self::as_ref(ptr) }.into() } +} +impl<Ctx: DeviceContext> Device<Ctx> { /// Obtain the raw `struct device *`. pub(crate) fn as_raw(&self) -> *mut bindings::device { self.0.get() } + /// Returns a reference to the parent device, if any. + #[cfg_attr(not(CONFIG_AUXILIARY_BUS), expect(dead_code))] + pub(crate) fn parent(&self) -> Option<&Self> { + // SAFETY: + // - By the type invariant `self.as_raw()` is always valid. + // - The parent device is only ever set at device creation. + let parent = unsafe { (*self.as_raw()).parent }; + + if parent.is_null() { + None + } else { + // SAFETY: + // - Since `parent` is not NULL, it must be a valid pointer to a `struct device`. + // - `parent` is valid for the lifetime of `self`, since a `struct device` holds a + // reference count of its parent. + Some(unsafe { Self::as_ref(parent) }) + } + } + /// Convert a raw C `struct device` pointer to a `&'a Device`. /// /// # Safety @@ -189,6 +210,11 @@ impl Device { } } +// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic +// argument. +kernel::impl_device_context_deref!(unsafe { Device }); +kernel::impl_device_context_into_aref!(Device); + // SAFETY: Instances of `Device` are always reference-counted. unsafe impl crate::types::AlwaysRefCounted for Device { fn inc_ref(&self) { @@ -225,16 +251,95 @@ pub struct Normal; /// any of the bus callbacks, such as `probe()`. pub struct Core; +/// The [`Bound`] context is the context of a bus specific device reference when it is guaranteed to +/// be bound for the duration of its lifetime. +pub struct Bound; + mod private { pub trait Sealed {} + impl Sealed for super::Bound {} impl Sealed for super::Core {} impl Sealed for super::Normal {} } +impl DeviceContext for Bound {} impl DeviceContext for Core {} impl DeviceContext for Normal {} +/// # Safety +/// +/// The type given as `$device` must be a transparent wrapper of a type that doesn't depend on the +/// generic argument of `$device`. +#[doc(hidden)] +#[macro_export] +macro_rules! __impl_device_context_deref { + (unsafe { $device:ident, $src:ty => $dst:ty }) => { + impl ::core::ops::Deref for $device<$src> { + type Target = $device<$dst>; + + fn deref(&self) -> &Self::Target { + let ptr: *const Self = self; + + // CAST: `$device<$src>` and `$device<$dst>` transparently wrap the same type by the + // safety requirement of the macro. + let ptr = ptr.cast::<Self::Target>(); + + // SAFETY: `ptr` was derived from `&self`. + unsafe { &*ptr } + } + } + }; +} + +/// Implement [`core::ops::Deref`] traits for allowed [`DeviceContext`] conversions of a (bus +/// specific) device. +/// +/// # Safety +/// +/// The type given as `$device` must be a transparent wrapper of a type that doesn't depend on the +/// generic argument of `$device`. +#[macro_export] +macro_rules! impl_device_context_deref { + (unsafe { $device:ident }) => { + // SAFETY: This macro has the exact same safety requirement as + // `__impl_device_context_deref!`. + ::kernel::__impl_device_context_deref!(unsafe { + $device, + $crate::device::Core => $crate::device::Bound + }); + + // SAFETY: This macro has the exact same safety requirement as + // `__impl_device_context_deref!`. + ::kernel::__impl_device_context_deref!(unsafe { + $device, + $crate::device::Bound => $crate::device::Normal + }); + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __impl_device_context_into_aref { + ($src:ty, $device:tt) => { + impl ::core::convert::From<&$device<$src>> for $crate::types::ARef<$device> { + fn from(dev: &$device<$src>) -> Self { + (&**dev).into() + } + } + }; +} + +/// Implement [`core::convert::From`], such that all `&Device<Ctx>` can be converted to an +/// `ARef<Device>`. +#[macro_export] +macro_rules! impl_device_context_into_aref { + ($device:tt) => { + ::kernel::__impl_device_context_into_aref!($crate::device::Core, $device); + ::kernel::__impl_device_context_into_aref!($crate::device::Bound, $device); + }; +} + #[doc(hidden)] #[macro_export] macro_rules! dev_printk { diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs index ddb1ce4a78d9..0f79a2ec9474 100644 --- a/rust/kernel/devres.rs +++ b/rust/kernel/devres.rs @@ -8,7 +8,7 @@ use crate::{ alloc::Flags, bindings, - device::Device, + device::{Bound, Device}, error::{Error, Result}, ffi::c_void, prelude::*, @@ -45,7 +45,7 @@ struct DevresInner<T> { /// # Example /// /// ```no_run -/// # use kernel::{bindings, c_str, device::Device, devres::Devres, io::{Io, IoRaw}}; +/// # use kernel::{bindings, c_str, device::{Bound, Device}, devres::Devres, io::{Io, IoRaw}}; /// # use core::ops::Deref; /// /// // See also [`pci::Bar`] for a real example. @@ -83,13 +83,10 @@ struct DevresInner<T> { /// unsafe { Io::from_raw(&self.0) } /// } /// } -/// # fn no_run() -> Result<(), Error> { -/// # // SAFETY: Invalid usage; just for the example to get an `ARef<Device>` instance. -/// # let dev = unsafe { Device::get_device(core::ptr::null_mut()) }; -/// +/// # fn no_run(dev: &Device<Bound>) -> Result<(), Error> { /// // SAFETY: Invalid usage for example purposes. /// let iomem = unsafe { IoMem::<{ core::mem::size_of::<u32>() }>::new(0xBAAAAAAD)? }; -/// let devres = Devres::new(&dev, iomem, GFP_KERNEL)?; +/// let devres = Devres::new(dev, iomem, GFP_KERNEL)?; /// /// let res = devres.try_access().ok_or(ENXIO)?; /// res.write8(0x42, 0x0); @@ -99,7 +96,7 @@ struct DevresInner<T> { pub struct Devres<T>(Arc<DevresInner<T>>); impl<T> DevresInner<T> { - fn new(dev: &Device, data: T, flags: Flags) -> Result<Arc<DevresInner<T>>> { + fn new(dev: &Device<Bound>, data: T, flags: Flags) -> Result<Arc<DevresInner<T>>> { let inner = Arc::pin_init( pin_init!( DevresInner { dev: dev.into(), @@ -171,7 +168,7 @@ impl<T> DevresInner<T> { impl<T> Devres<T> { /// Creates a new [`Devres`] instance of the given `data`. The `data` encapsulated within the /// returned `Devres` instance' `data` will be revoked once the device is detached. - pub fn new(dev: &Device, data: T, flags: Flags) -> Result<Self> { + pub fn new(dev: &Device<Bound>, data: T, flags: Flags) -> Result<Self> { let inner = DevresInner::new(dev, data, flags)?; Ok(Devres(inner)) @@ -179,11 +176,50 @@ impl<T> Devres<T> { /// Same as [`Devres::new`], but does not return a `Devres` instance. Instead the given `data` /// is owned by devres and will be revoked / dropped, once the device is detached. - pub fn new_foreign_owned(dev: &Device, data: T, flags: Flags) -> Result { + pub fn new_foreign_owned(dev: &Device<Bound>, data: T, flags: Flags) -> Result { let _ = DevresInner::new(dev, data, flags)?; Ok(()) } + + /// Obtain `&'a T`, bypassing the [`Revocable`]. + /// + /// This method allows to directly obtain a `&'a T`, bypassing the [`Revocable`], by presenting + /// a `&'a Device<Bound>` of the same [`Device`] this [`Devres`] instance has been created with. + /// + /// # Errors + /// + /// An error is returned if `dev` does not match the same [`Device`] this [`Devres`] instance + /// has been created with. + /// + /// # Example + /// + /// ```no_run + /// # #![cfg(CONFIG_PCI)] + /// # use kernel::{device::Core, devres::Devres, pci}; + /// + /// fn from_core(dev: &pci::Device<Core>, devres: Devres<pci::Bar<0x4>>) -> Result { + /// let bar = devres.access(dev.as_ref())?; + /// + /// let _ = bar.read32(0x0); + /// + /// // might_sleep() + /// + /// bar.write32(0x42, 0x0); + /// + /// Ok(()) + /// } + /// ``` + pub fn access<'a>(&'a self, dev: &'a Device<Bound>) -> Result<&'a T> { + if self.0.dev.as_raw() != dev.as_raw() { + return Err(EINVAL); + } + + // SAFETY: `dev` being the same device as the device this `Devres` has been created for + // proves that `self.0.data` hasn't been revoked and is guaranteed to not be revoked as + // long as `dev` lives; `dev` lives at least as long as `self`. + Ok(unsafe { self.deref().access() }) + } } impl<T> Deref for Devres<T> { diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs index 8cdc76043ee7..605e01e35715 100644 --- a/rust/kernel/dma.rs +++ b/rust/kernel/dma.rs @@ -6,7 +6,7 @@ use crate::{ bindings, build_assert, - device::Device, + device::{Bound, Device}, error::code::*, error::Result, transmute::{AsBytes, FromBytes}, @@ -22,10 +22,10 @@ use crate::{ /// # Examples /// /// ``` -/// use kernel::device::Device; +/// # use kernel::device::{Bound, Device}; /// use kernel::dma::{attrs::*, CoherentAllocation}; /// -/// # fn test(dev: &Device) -> Result { +/// # fn test(dev: &Device<Bound>) -> Result { /// let attribs = DMA_ATTR_FORCE_CONTIGUOUS | DMA_ATTR_NO_WARN; /// let c: CoherentAllocation<u64> = /// CoherentAllocation::alloc_attrs(dev, 4, GFP_KERNEL, attribs)?; @@ -143,16 +143,16 @@ impl<T: AsBytes + FromBytes> CoherentAllocation<T> { /// # Examples /// /// ``` - /// use kernel::device::Device; + /// # use kernel::device::{Bound, Device}; /// use kernel::dma::{attrs::*, CoherentAllocation}; /// - /// # fn test(dev: &Device) -> Result { + /// # fn test(dev: &Device<Bound>) -> Result { /// let c: CoherentAllocation<u64> = /// CoherentAllocation::alloc_attrs(dev, 4, GFP_KERNEL, DMA_ATTR_NO_WARN)?; /// # Ok::<(), Error>(()) } /// ``` pub fn alloc_attrs( - dev: &Device, + dev: &Device<Bound>, count: usize, gfp_flags: kernel::alloc::Flags, dma_attrs: Attrs, @@ -194,7 +194,7 @@ impl<T: AsBytes + FromBytes> CoherentAllocation<T> { /// Performs the same functionality as [`CoherentAllocation::alloc_attrs`], except the /// `dma_attrs` is 0 by default. pub fn alloc_coherent( - dev: &Device, + dev: &Device<Bound>, count: usize, gfp_flags: kernel::alloc::Flags, ) -> Result<CoherentAllocation<T>> { diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs new file mode 100644 index 000000000000..74c9a3dd719e --- /dev/null +++ b/rust/kernel/drm/device.rs @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +//! DRM device. +//! +//! C header: [`include/linux/drm/drm_device.h`](srctree/include/linux/drm/drm_device.h) + +use crate::{ + bindings, device, drm, + drm::driver::AllocImpl, + error::from_err_ptr, + error::Result, + prelude::*, + types::{ARef, AlwaysRefCounted, Opaque}, +}; +use core::{mem, ops::Deref, ptr, ptr::NonNull}; + +#[cfg(CONFIG_DRM_LEGACY)] +macro_rules! drm_legacy_fields { + ( $($field:ident: $val:expr),* $(,)? ) => { + bindings::drm_driver { + $( $field: $val ),*, + firstopen: None, + preclose: None, + dma_ioctl: None, + dma_quiescent: None, + context_dtor: None, + irq_handler: None, + irq_preinstall: None, + irq_postinstall: None, + irq_uninstall: None, + get_vblank_counter: None, + enable_vblank: None, + disable_vblank: None, + dev_priv_size: 0, + } + } +} + +#[cfg(not(CONFIG_DRM_LEGACY))] +macro_rules! drm_legacy_fields { + ( $($field:ident: $val:expr),* $(,)? ) => { + bindings::drm_driver { + $( $field: $val ),* + } + } +} + +/// A typed DRM device with a specific `drm::Driver` implementation. +/// +/// The device is always reference-counted. +/// +/// # Invariants +/// +/// `self.dev` is a valid instance of a `struct device`. +#[repr(C)] +#[pin_data] +pub struct Device<T: drm::Driver> { + dev: Opaque<bindings::drm_device>, + #[pin] + data: T::Data, +} + +impl<T: drm::Driver> Device<T> { + const VTABLE: bindings::drm_driver = drm_legacy_fields! { + load: None, + open: Some(drm::File::<T::File>::open_callback), + postclose: Some(drm::File::<T::File>::postclose_callback), + unload: None, + release: None, + master_set: None, + master_drop: None, + debugfs_init: None, + gem_create_object: T::Object::ALLOC_OPS.gem_create_object, + prime_handle_to_fd: T::Object::ALLOC_OPS.prime_handle_to_fd, + prime_fd_to_handle: T::Object::ALLOC_OPS.prime_fd_to_handle, + gem_prime_import: T::Object::ALLOC_OPS.gem_prime_import, + gem_prime_import_sg_table: T::Object::ALLOC_OPS.gem_prime_import_sg_table, + dumb_create: T::Object::ALLOC_OPS.dumb_create, + dumb_map_offset: T::Object::ALLOC_OPS.dumb_map_offset, + show_fdinfo: None, + fbdev_probe: None, + + major: T::INFO.major, + minor: T::INFO.minor, + patchlevel: T::INFO.patchlevel, + name: T::INFO.name.as_char_ptr() as *mut _, + desc: T::INFO.desc.as_char_ptr() as *mut _, + + driver_features: drm::driver::FEAT_GEM, + ioctls: T::IOCTLS.as_ptr(), + num_ioctls: T::IOCTLS.len() as i32, + fops: &Self::GEM_FOPS as _, + }; + + const GEM_FOPS: bindings::file_operations = drm::gem::create_fops(); + + /// Create a new `drm::Device` for a `drm::Driver`. + pub fn new(dev: &device::Device, data: impl PinInit<T::Data, Error>) -> Result<ARef<Self>> { + // SAFETY: + // - `VTABLE`, as a `const` is pinned to the read-only section of the compilation, + // - `dev` is valid by its type invarants, + let raw_drm: *mut Self = unsafe { + bindings::__drm_dev_alloc( + dev.as_raw(), + &Self::VTABLE, + mem::size_of::<Self>(), + mem::offset_of!(Self, dev), + ) + } + .cast(); + let raw_drm = NonNull::new(from_err_ptr(raw_drm)?).ok_or(ENOMEM)?; + + // SAFETY: `raw_drm` is a valid pointer to `Self`. + let raw_data = unsafe { ptr::addr_of_mut!((*raw_drm.as_ptr()).data) }; + + // SAFETY: + // - `raw_data` is a valid pointer to uninitialized memory. + // - `raw_data` will not move until it is dropped. + unsafe { data.__pinned_init(raw_data) }.inspect_err(|_| { + // SAFETY: `__drm_dev_alloc()` was successful, hence `raw_drm` must be valid and the + // refcount must be non-zero. + unsafe { bindings::drm_dev_put(ptr::addr_of_mut!((*raw_drm.as_ptr()).dev).cast()) }; + })?; + + // SAFETY: The reference count is one, and now we take ownership of that reference as a + // `drm::Device`. + Ok(unsafe { ARef::from_raw(raw_drm) }) + } + + pub(crate) fn as_raw(&self) -> *mut bindings::drm_device { + self.dev.get() + } + + /// # Safety + /// + /// `ptr` must be a valid pointer to a `struct device` embedded in `Self`. + unsafe fn from_drm_device(ptr: *const bindings::drm_device) -> *mut Self { + // SAFETY: By the safety requirements of this function `ptr` is a valid pointer to a + // `struct drm_device` embedded in `Self`. + unsafe { crate::container_of!(ptr, Self, dev) }.cast_mut() + } + + /// Not intended to be called externally, except via declare_drm_ioctls!() + /// + /// # Safety + /// + /// Callers must ensure that `ptr` is valid, non-null, and has a non-zero reference count, + /// i.e. it must be ensured that the reference count of the C `struct drm_device` `ptr` points + /// to can't drop to zero, for the duration of this function call and the entire duration when + /// the returned reference exists. + /// + /// Additionally, callers must ensure that the `struct device`, `ptr` is pointing to, is + /// embedded in `Self`. + #[doc(hidden)] + pub unsafe fn as_ref<'a>(ptr: *const bindings::drm_device) -> &'a Self { + // SAFETY: By the safety requirements of this function `ptr` is a valid pointer to a + // `struct drm_device` embedded in `Self`. + let ptr = unsafe { Self::from_drm_device(ptr) }; + + // SAFETY: `ptr` is valid by the safety requirements of this function. + unsafe { &*ptr.cast() } + } +} + +impl<T: drm::Driver> Deref for Device<T> { + type Target = T::Data; + + fn deref(&self) -> &Self::Target { + &self.data + } +} + +// SAFETY: DRM device objects are always reference counted and the get/put functions +// satisfy the requirements. +unsafe impl<T: drm::Driver> AlwaysRefCounted for Device<T> { + fn inc_ref(&self) { + // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. + unsafe { bindings::drm_dev_get(self.as_raw()) }; + } + + unsafe fn dec_ref(obj: NonNull<Self>) { + // SAFETY: The safety requirements guarantee that the refcount is non-zero. + unsafe { bindings::drm_dev_put(obj.cast().as_ptr()) }; + } +} + +impl<T: drm::Driver> AsRef<device::Device> for Device<T> { + fn as_ref(&self) -> &device::Device { + // SAFETY: `bindings::drm_device::dev` is valid as long as the DRM device itself is valid, + // which is guaranteed by the type invariant. + unsafe { device::Device::as_ref((*self.as_raw()).dev) } + } +} + +// SAFETY: A `drm::Device` can be released from any thread. +unsafe impl<T: drm::Driver> Send for Device<T> {} + +// SAFETY: A `drm::Device` can be shared among threads because all immutable methods are protected +// by the synchronization in `struct drm_device`. +unsafe impl<T: drm::Driver> Sync for Device<T> {} diff --git a/rust/kernel/drm/driver.rs b/rust/kernel/drm/driver.rs new file mode 100644 index 000000000000..acb638086131 --- /dev/null +++ b/rust/kernel/drm/driver.rs @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +//! DRM driver core. +//! +//! C header: [`include/linux/drm/drm_drv.h`](srctree/include/linux/drm/drm_drv.h) + +use crate::{ + bindings, device, + devres::Devres, + drm, + error::{to_result, Result}, + prelude::*, + str::CStr, + types::ARef, +}; +use macros::vtable; + +/// Driver use the GEM memory manager. This should be set for all modern drivers. +pub(crate) const FEAT_GEM: u32 = bindings::drm_driver_feature_DRIVER_GEM; + +/// Information data for a DRM Driver. +pub struct DriverInfo { + /// Driver major version. + pub major: i32, + /// Driver minor version. + pub minor: i32, + /// Driver patchlevel version. + pub patchlevel: i32, + /// Driver name. + pub name: &'static CStr, + /// Driver description. + pub desc: &'static CStr, +} + +/// Internal memory management operation set, normally created by memory managers (e.g. GEM). +pub struct AllocOps { + pub(crate) gem_create_object: Option< + unsafe extern "C" fn( + dev: *mut bindings::drm_device, + size: usize, + ) -> *mut bindings::drm_gem_object, + >, + pub(crate) prime_handle_to_fd: Option< + unsafe extern "C" fn( + dev: *mut bindings::drm_device, + file_priv: *mut bindings::drm_file, + handle: u32, + flags: u32, + prime_fd: *mut core::ffi::c_int, + ) -> core::ffi::c_int, + >, + pub(crate) prime_fd_to_handle: Option< + unsafe extern "C" fn( + dev: *mut bindings::drm_device, + file_priv: *mut bindings::drm_file, + prime_fd: core::ffi::c_int, + handle: *mut u32, + ) -> core::ffi::c_int, + >, + pub(crate) gem_prime_import: Option< + unsafe extern "C" fn( + dev: *mut bindings::drm_device, + dma_buf: *mut bindings::dma_buf, + ) -> *mut bindings::drm_gem_object, + >, + pub(crate) gem_prime_import_sg_table: Option< + unsafe extern "C" fn( + dev: *mut bindings::drm_device, + attach: *mut bindings::dma_buf_attachment, + sgt: *mut bindings::sg_table, + ) -> *mut bindings::drm_gem_object, + >, + pub(crate) dumb_create: Option< + unsafe extern "C" fn( + file_priv: *mut bindings::drm_file, + dev: *mut bindings::drm_device, + args: *mut bindings::drm_mode_create_dumb, + ) -> core::ffi::c_int, + >, + pub(crate) dumb_map_offset: Option< + unsafe extern "C" fn( + file_priv: *mut bindings::drm_file, + dev: *mut bindings::drm_device, + handle: u32, + offset: *mut u64, + ) -> core::ffi::c_int, + >, +} + +/// Trait for memory manager implementations. Implemented internally. +pub trait AllocImpl: super::private::Sealed + drm::gem::IntoGEMObject { + /// The C callback operations for this memory manager. + const ALLOC_OPS: AllocOps; +} + +/// The DRM `Driver` trait. +/// +/// This trait must be implemented by drivers in order to create a `struct drm_device` and `struct +/// drm_driver` to be registered in the DRM subsystem. +#[vtable] +pub trait Driver { + /// Context data associated with the DRM driver + type Data: Sync + Send; + + /// The type used to manage memory for this driver. + type Object: AllocImpl; + + /// The type used to represent a DRM File (client) + type File: drm::file::DriverFile; + + /// Driver metadata + const INFO: DriverInfo; + + /// IOCTL list. See `kernel::drm::ioctl::declare_drm_ioctls!{}`. + const IOCTLS: &'static [drm::ioctl::DrmIoctlDescriptor]; +} + +/// The registration type of a `drm::Device`. +/// +/// Once the `Registration` structure is dropped, the device is unregistered. +pub struct Registration<T: Driver>(ARef<drm::Device<T>>); + +impl<T: Driver> Registration<T> { + /// Creates a new [`Registration`] and registers it. + fn new(drm: &drm::Device<T>, flags: usize) -> Result<Self> { + // SAFETY: `drm.as_raw()` is valid by the invariants of `drm::Device`. + to_result(unsafe { bindings::drm_dev_register(drm.as_raw(), flags) })?; + + Ok(Self(drm.into())) + } + + /// Same as [`Registration::new`}, but transfers ownership of the [`Registration`] to + /// [`Devres`]. + pub fn new_foreign_owned( + drm: &drm::Device<T>, + dev: &device::Device<device::Bound>, + flags: usize, + ) -> Result { + if drm.as_ref().as_raw() != dev.as_raw() { + return Err(EINVAL); + } + + let reg = Registration::<T>::new(drm, flags)?; + Devres::new_foreign_owned(dev, reg, GFP_KERNEL) + } + + /// Returns a reference to the `Device` instance for this registration. + pub fn device(&self) -> &drm::Device<T> { + &self.0 + } +} + +// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between +// threads, hence it's safe to share it. +unsafe impl<T: Driver> Sync for Registration<T> {} + +// SAFETY: Registration with and unregistration from the DRM subsystem can happen from any thread. +unsafe impl<T: Driver> Send for Registration<T> {} + +impl<T: Driver> Drop for Registration<T> { + fn drop(&mut self) { + // SAFETY: Safe by the invariant of `ARef<drm::Device<T>>`. The existence of this + // `Registration` also guarantees the this `drm::Device` is actually registered. + unsafe { bindings::drm_dev_unregister(self.0.as_raw()) }; + } +} diff --git a/rust/kernel/drm/file.rs b/rust/kernel/drm/file.rs new file mode 100644 index 000000000000..b9527705e551 --- /dev/null +++ b/rust/kernel/drm/file.rs @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +//! DRM File objects. +//! +//! C header: [`include/linux/drm/drm_file.h`](srctree/include/linux/drm/drm_file.h) + +use crate::{bindings, drm, error::Result, prelude::*, types::Opaque}; +use core::marker::PhantomData; +use core::pin::Pin; + +/// Trait that must be implemented by DRM drivers to represent a DRM File (a client instance). +pub trait DriverFile { + /// The parent `Driver` implementation for this `DriverFile`. + type Driver: drm::Driver; + + /// Open a new file (called when a client opens the DRM device). + fn open(device: &drm::Device<Self::Driver>) -> Result<Pin<KBox<Self>>>; +} + +/// An open DRM File. +/// +/// # Invariants +/// +/// `self.0` is a valid instance of a `struct drm_file`. +#[repr(transparent)] +pub struct File<T: DriverFile>(Opaque<bindings::drm_file>, PhantomData<T>); + +impl<T: DriverFile> File<T> { + #[doc(hidden)] + /// Not intended to be called externally, except via declare_drm_ioctls!() + /// + /// # Safety + /// + /// `raw_file` must be a valid pointer to an open `struct drm_file`, opened through `T::open`. + pub unsafe fn as_ref<'a>(ptr: *mut bindings::drm_file) -> &'a File<T> { + // SAFETY: `raw_file` is valid by the safety requirements of this function. + unsafe { &*ptr.cast() } + } + + pub(super) fn as_raw(&self) -> *mut bindings::drm_file { + self.0.get() + } + + fn driver_priv(&self) -> *mut T { + // SAFETY: By the type invariants of `Self`, `self.as_raw()` is always valid. + unsafe { (*self.as_raw()).driver_priv }.cast() + } + + /// Return a pinned reference to the driver file structure. + pub fn inner(&self) -> Pin<&T> { + // SAFETY: By the type invariant the pointer `self.as_raw()` points to a valid and opened + // `struct drm_file`, hence `driver_priv` has been properly initialized by `open_callback`. + unsafe { Pin::new_unchecked(&*(self.driver_priv())) } + } + + /// The open callback of a `struct drm_file`. + pub(crate) extern "C" fn open_callback( + raw_dev: *mut bindings::drm_device, + raw_file: *mut bindings::drm_file, + ) -> core::ffi::c_int { + // SAFETY: A callback from `struct drm_driver::open` guarantees that + // - `raw_dev` is valid pointer to a `struct drm_device`, + // - the corresponding `struct drm_device` has been registered. + let drm = unsafe { drm::Device::as_ref(raw_dev) }; + + // SAFETY: `raw_file` is a valid pointer to a `struct drm_file`. + let file = unsafe { File::<T>::as_ref(raw_file) }; + + let inner = match T::open(drm) { + Err(e) => { + return e.to_errno(); + } + Ok(i) => i, + }; + + // SAFETY: This pointer is treated as pinned, and the Drop guarantee is upheld in + // `postclose_callback()`. + let driver_priv = KBox::into_raw(unsafe { Pin::into_inner_unchecked(inner) }); + + // SAFETY: By the type invariants of `Self`, `self.as_raw()` is always valid. + unsafe { (*file.as_raw()).driver_priv = driver_priv.cast() }; + + 0 + } + + /// The postclose callback of a `struct drm_file`. + pub(crate) extern "C" fn postclose_callback( + _raw_dev: *mut bindings::drm_device, + raw_file: *mut bindings::drm_file, + ) { + // SAFETY: This reference won't escape this function + let file = unsafe { File::<T>::as_ref(raw_file) }; + + // SAFETY: `file.driver_priv` has been created in `open_callback` through `KBox::into_raw`. + let _ = unsafe { KBox::from_raw(file.driver_priv()) }; + } +} + +impl<T: DriverFile> super::private::Sealed for File<T> {} diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs new file mode 100644 index 000000000000..d8765e61c6c2 --- /dev/null +++ b/rust/kernel/drm/gem/mod.rs @@ -0,0 +1,328 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +//! DRM GEM API +//! +//! C header: [`include/linux/drm/drm_gem.h`](srctree/include/linux/drm/drm_gem.h) + +use crate::{ + alloc::flags::*, + bindings, drm, + drm::driver::{AllocImpl, AllocOps}, + error::{to_result, Result}, + prelude::*, + types::{ARef, AlwaysRefCounted, Opaque}, +}; +use core::{mem, ops::Deref, ptr::NonNull}; + +/// GEM object functions, which must be implemented by drivers. +pub trait BaseDriverObject<T: BaseObject>: Sync + Send + Sized { + /// Create a new driver data object for a GEM object of a given size. + fn new(dev: &drm::Device<T::Driver>, size: usize) -> impl PinInit<Self, Error>; + + /// Open a new handle to an existing object, associated with a File. + fn open( + _obj: &<<T as IntoGEMObject>::Driver as drm::Driver>::Object, + _file: &drm::File<<<T as IntoGEMObject>::Driver as drm::Driver>::File>, + ) -> Result { + Ok(()) + } + + /// Close a handle to an existing object, associated with a File. + fn close( + _obj: &<<T as IntoGEMObject>::Driver as drm::Driver>::Object, + _file: &drm::File<<<T as IntoGEMObject>::Driver as drm::Driver>::File>, + ) { + } +} + +/// Trait that represents a GEM object subtype +pub trait IntoGEMObject: Sized + super::private::Sealed + AlwaysRefCounted { + /// Owning driver for this type + type Driver: drm::Driver; + + /// Returns a reference to the raw `drm_gem_object` structure, which must be valid as long as + /// this owning object is valid. + fn as_raw(&self) -> *mut bindings::drm_gem_object; + + /// Converts a pointer to a `struct drm_gem_object` into a reference to `Self`. + /// + /// # Safety + /// + /// - `self_ptr` must be a valid pointer to `Self`. + /// - The caller promises that holding the immutable reference returned by this function does + /// not violate rust's data aliasing rules and remains valid throughout the lifetime of `'a`. + unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a Self; +} + +// SAFETY: All gem objects are refcounted. +unsafe impl<T: IntoGEMObject> AlwaysRefCounted for T { + fn inc_ref(&self) { + // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. + unsafe { bindings::drm_gem_object_get(self.as_raw()) }; + } + + unsafe fn dec_ref(obj: NonNull<Self>) { + // SAFETY: We either hold the only refcount on `obj`, or one of many - meaning that no one + // else could possibly hold a mutable reference to `obj` and thus this immutable reference + // is safe. + let obj = unsafe { obj.as_ref() }.as_raw(); + + // SAFETY: + // - The safety requirements guarantee that the refcount is non-zero. + // - We hold no references to `obj` now, making it safe for us to potentially deallocate it. + unsafe { bindings::drm_gem_object_put(obj) }; + } +} + +/// Trait which must be implemented by drivers using base GEM objects. +pub trait DriverObject: BaseDriverObject<Object<Self>> { + /// Parent `Driver` for this object. + type Driver: drm::Driver; +} + +extern "C" fn open_callback<T: BaseDriverObject<U>, U: BaseObject>( + raw_obj: *mut bindings::drm_gem_object, + raw_file: *mut bindings::drm_file, +) -> core::ffi::c_int { + // SAFETY: `open_callback` is only ever called with a valid pointer to a `struct drm_file`. + let file = unsafe { + drm::File::<<<U as IntoGEMObject>::Driver as drm::Driver>::File>::as_ref(raw_file) + }; + // SAFETY: `open_callback` is specified in the AllocOps structure for `Object<T>`, ensuring that + // `raw_obj` is indeed contained within a `Object<T>`. + let obj = unsafe { + <<<U as IntoGEMObject>::Driver as drm::Driver>::Object as IntoGEMObject>::as_ref(raw_obj) + }; + + match T::open(obj, file) { + Err(e) => e.to_errno(), + Ok(()) => 0, + } +} + +extern "C" fn close_callback<T: BaseDriverObject<U>, U: BaseObject>( + raw_obj: *mut bindings::drm_gem_object, + raw_file: *mut bindings::drm_file, +) { + // SAFETY: `open_callback` is only ever called with a valid pointer to a `struct drm_file`. + let file = unsafe { + drm::File::<<<U as IntoGEMObject>::Driver as drm::Driver>::File>::as_ref(raw_file) + }; + // SAFETY: `close_callback` is specified in the AllocOps structure for `Object<T>`, ensuring + // that `raw_obj` is indeed contained within a `Object<T>`. + let obj = unsafe { + <<<U as IntoGEMObject>::Driver as drm::Driver>::Object as IntoGEMObject>::as_ref(raw_obj) + }; + + T::close(obj, file); +} + +impl<T: DriverObject> IntoGEMObject for Object<T> { + type Driver = T::Driver; + + fn as_raw(&self) -> *mut bindings::drm_gem_object { + self.obj.get() + } + + unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a Self { + // SAFETY: `obj` is guaranteed to be in an `Object<T>` via the safety contract of this + // function + unsafe { &*crate::container_of!(self_ptr, Object<T>, obj) } + } +} + +/// Base operations shared by all GEM object classes +pub trait BaseObject: IntoGEMObject { + /// Returns the size of the object in bytes. + fn size(&self) -> usize { + // SAFETY: `self.as_raw()` is guaranteed to be a pointer to a valid `struct drm_gem_object`. + unsafe { (*self.as_raw()).size } + } + + /// Creates a new handle for the object associated with a given `File` + /// (or returns an existing one). + fn create_handle( + &self, + file: &drm::File<<<Self as IntoGEMObject>::Driver as drm::Driver>::File>, + ) -> Result<u32> { + let mut handle: u32 = 0; + // SAFETY: The arguments are all valid per the type invariants. + to_result(unsafe { + bindings::drm_gem_handle_create(file.as_raw().cast(), self.as_raw(), &mut handle) + })?; + Ok(handle) + } + + /// Looks up an object by its handle for a given `File`. + fn lookup_handle( + file: &drm::File<<<Self as IntoGEMObject>::Driver as drm::Driver>::File>, + handle: u32, + ) -> Result<ARef<Self>> { + // SAFETY: The arguments are all valid per the type invariants. + let ptr = unsafe { bindings::drm_gem_object_lookup(file.as_raw().cast(), handle) }; + if ptr.is_null() { + return Err(ENOENT); + } + + // SAFETY: + // - A `drm::Driver` can only have a single `File` implementation. + // - `file` uses the same `drm::Driver` as `Self`. + // - Therefore, we're guaranteed that `ptr` must be a gem object embedded within `Self`. + // - And we check if the pointer is null befoe calling as_ref(), ensuring that `ptr` is a + // valid pointer to an initialized `Self`. + let obj = unsafe { Self::as_ref(ptr) }; + + // SAFETY: + // - We take ownership of the reference of `drm_gem_object_lookup()`. + // - Our `NonNull` comes from an immutable reference, thus ensuring it is a valid pointer to + // `Self`. + Ok(unsafe { ARef::from_raw(obj.into()) }) + } + + /// Creates an mmap offset to map the object from userspace. + fn create_mmap_offset(&self) -> Result<u64> { + // SAFETY: The arguments are valid per the type invariant. + to_result(unsafe { bindings::drm_gem_create_mmap_offset(self.as_raw()) })?; + + // SAFETY: The arguments are valid per the type invariant. + Ok(unsafe { bindings::drm_vma_node_offset_addr(&raw mut (*self.as_raw()).vma_node) }) + } +} + +impl<T: IntoGEMObject> BaseObject for T {} + +/// A base GEM object. +/// +/// Invariants +/// +/// - `self.obj` is a valid instance of a `struct drm_gem_object`. +/// - `self.dev` is always a valid pointer to a `struct drm_device`. +#[repr(C)] +#[pin_data] +pub struct Object<T: DriverObject + Send + Sync> { + obj: Opaque<bindings::drm_gem_object>, + dev: NonNull<drm::Device<T::Driver>>, + #[pin] + data: T, +} + +impl<T: DriverObject> Object<T> { + /// The size of this object's structure. + pub const SIZE: usize = mem::size_of::<Self>(); + + const OBJECT_FUNCS: bindings::drm_gem_object_funcs = bindings::drm_gem_object_funcs { + free: Some(Self::free_callback), + open: Some(open_callback::<T, Object<T>>), + close: Some(close_callback::<T, Object<T>>), + print_info: None, + export: None, + pin: None, + unpin: None, + get_sg_table: None, + vmap: None, + vunmap: None, + mmap: None, + status: None, + vm_ops: core::ptr::null_mut(), + evict: None, + rss: None, + }; + + /// Create a new GEM object. + pub fn new(dev: &drm::Device<T::Driver>, size: usize) -> Result<ARef<Self>> { + let obj: Pin<KBox<Self>> = KBox::pin_init( + try_pin_init!(Self { + obj: Opaque::new(bindings::drm_gem_object::default()), + data <- T::new(dev, size), + // INVARIANT: The drm subsystem guarantees that the `struct drm_device` will live + // as long as the GEM object lives. + dev: dev.into(), + }), + GFP_KERNEL, + )?; + + // SAFETY: `obj.as_raw()` is guaranteed to be valid by the initialization above. + unsafe { (*obj.as_raw()).funcs = &Self::OBJECT_FUNCS }; + + // SAFETY: The arguments are all valid per the type invariants. + to_result(unsafe { bindings::drm_gem_object_init(dev.as_raw(), obj.obj.get(), size) })?; + + // SAFETY: We never move out of `Self`. + let ptr = KBox::into_raw(unsafe { Pin::into_inner_unchecked(obj) }); + + // SAFETY: `ptr` comes from `KBox::into_raw` and hence can't be NULL. + let ptr = unsafe { NonNull::new_unchecked(ptr) }; + + // SAFETY: We take over the initial reference count from `drm_gem_object_init()`. + Ok(unsafe { ARef::from_raw(ptr) }) + } + + /// Returns the `Device` that owns this GEM object. + pub fn dev(&self) -> &drm::Device<T::Driver> { + // SAFETY: The DRM subsystem guarantees that the `struct drm_device` will live as long as + // the GEM object lives, hence the pointer must be valid. + unsafe { self.dev.as_ref() } + } + + fn as_raw(&self) -> *mut bindings::drm_gem_object { + self.obj.get() + } + + extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) { + // SAFETY: All of our objects are of type `Object<T>`. + let this = unsafe { crate::container_of!(obj, Self, obj) }.cast_mut(); + + // SAFETY: The C code only ever calls this callback with a valid pointer to a `struct + // drm_gem_object`. + unsafe { bindings::drm_gem_object_release(obj) }; + + // SAFETY: All of our objects are allocated via `KBox`, and we're in the + // free callback which guarantees this object has zero remaining references, + // so we can drop it. + let _ = unsafe { KBox::from_raw(this) }; + } +} + +impl<T: DriverObject> super::private::Sealed for Object<T> {} + +impl<T: DriverObject> Deref for Object<T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.data + } +} + +impl<T: DriverObject> AllocImpl for Object<T> { + const ALLOC_OPS: AllocOps = AllocOps { + gem_create_object: None, + prime_handle_to_fd: None, + prime_fd_to_handle: None, + gem_prime_import: None, + gem_prime_import_sg_table: None, + dumb_create: None, + dumb_map_offset: None, + }; +} + +pub(super) const fn create_fops() -> bindings::file_operations { + // SAFETY: As by the type invariant, it is safe to initialize `bindings::file_operations` + // zeroed. + let mut fops: bindings::file_operations = unsafe { core::mem::zeroed() }; + + fops.owner = core::ptr::null_mut(); + fops.open = Some(bindings::drm_open); + fops.release = Some(bindings::drm_release); + fops.unlocked_ioctl = Some(bindings::drm_ioctl); + #[cfg(CONFIG_COMPAT)] + { + fops.compat_ioctl = Some(bindings::drm_compat_ioctl); + } + fops.poll = Some(bindings::drm_poll); + fops.read = Some(bindings::drm_read); + fops.llseek = Some(bindings::noop_llseek); + fops.mmap = Some(bindings::drm_gem_mmap); + fops.fop_flags = bindings::FOP_UNSIGNED_OFFSET; + + fops +} diff --git a/rust/kernel/drm/ioctl.rs b/rust/kernel/drm/ioctl.rs new file mode 100644 index 000000000000..445639404fb7 --- /dev/null +++ b/rust/kernel/drm/ioctl.rs @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +//! DRM IOCTL definitions. +//! +//! C header: [`include/linux/drm/drm_ioctl.h`](srctree/include/linux/drm/drm_ioctl.h) + +use crate::ioctl; + +const BASE: u32 = uapi::DRM_IOCTL_BASE as u32; + +/// Construct a DRM ioctl number with no argument. +#[allow(non_snake_case)] +#[inline(always)] +pub const fn IO(nr: u32) -> u32 { + ioctl::_IO(BASE, nr) +} + +/// Construct a DRM ioctl number with a read-only argument. +#[allow(non_snake_case)] +#[inline(always)] +pub const fn IOR<T>(nr: u32) -> u32 { + ioctl::_IOR::<T>(BASE, nr) +} + +/// Construct a DRM ioctl number with a write-only argument. +#[allow(non_snake_case)] +#[inline(always)] +pub const fn IOW<T>(nr: u32) -> u32 { + ioctl::_IOW::<T>(BASE, nr) +} + +/// Construct a DRM ioctl number with a read-write argument. +#[allow(non_snake_case)] +#[inline(always)] +pub const fn IOWR<T>(nr: u32) -> u32 { + ioctl::_IOWR::<T>(BASE, nr) +} + +/// Descriptor type for DRM ioctls. Use the `declare_drm_ioctls!{}` macro to construct them. +pub type DrmIoctlDescriptor = bindings::drm_ioctl_desc; + +/// This is for ioctl which are used for rendering, and require that the file descriptor is either +/// for a render node, or if it’s a legacy/primary node, then it must be authenticated. +pub const AUTH: u32 = bindings::drm_ioctl_flags_DRM_AUTH; + +/// This must be set for any ioctl which can change the modeset or display state. Userspace must +/// call the ioctl through a primary node, while it is the active master. +/// +/// Note that read-only modeset ioctl can also be called by unauthenticated clients, or when a +/// master is not the currently active one. +pub const MASTER: u32 = bindings::drm_ioctl_flags_DRM_MASTER; + +/// Anything that could potentially wreak a master file descriptor needs to have this flag set. +/// +/// Current that’s only for the SETMASTER and DROPMASTER ioctl, which e.g. logind can call to +/// force a non-behaving master (display compositor) into compliance. +/// +/// This is equivalent to callers with the SYSADMIN capability. +pub const ROOT_ONLY: u32 = bindings::drm_ioctl_flags_DRM_ROOT_ONLY; + +/// This is used for all ioctl needed for rendering only, for drivers which support render nodes. +/// This should be all new render drivers, and hence it should be always set for any ioctl with +/// `AUTH` set. Note though that read-only query ioctl might have this set, but have not set +/// DRM_AUTH because they do not require authentication. +pub const RENDER_ALLOW: u32 = bindings::drm_ioctl_flags_DRM_RENDER_ALLOW; + +/// Internal structures used by the `declare_drm_ioctls!{}` macro. Do not use directly. +#[doc(hidden)] +pub mod internal { + pub use bindings::drm_device; + pub use bindings::drm_file; + pub use bindings::drm_ioctl_desc; +} + +/// Declare the DRM ioctls for a driver. +/// +/// Each entry in the list should have the form: +/// +/// `(ioctl_number, argument_type, flags, user_callback),` +/// +/// `argument_type` is the type name within the `bindings` crate. +/// `user_callback` should have the following prototype: +/// +/// ```ignore +/// fn foo(device: &kernel::drm::Device<Self>, +/// data: &Opaque<uapi::argument_type>, +/// file: &kernel::drm::File<Self::File>, +/// ) -> Result<u32> +/// ``` +/// where `Self` is the drm::drv::Driver implementation these ioctls are being declared within. +/// +/// # Examples +/// +/// ```ignore +/// kernel::declare_drm_ioctls! { +/// (FOO_GET_PARAM, drm_foo_get_param, ioctl::RENDER_ALLOW, my_get_param_handler), +/// } +/// ``` +/// +#[macro_export] +macro_rules! declare_drm_ioctls { + ( $(($cmd:ident, $struct:ident, $flags:expr, $func:expr)),* $(,)? ) => { + const IOCTLS: &'static [$crate::drm::ioctl::DrmIoctlDescriptor] = { + use $crate::uapi::*; + const _:() = { + let i: u32 = $crate::uapi::DRM_COMMAND_BASE; + // Assert that all the IOCTLs are in the right order and there are no gaps, + // and that the size of the specified type is correct. + $( + let cmd: u32 = $crate::macros::concat_idents!(DRM_IOCTL_, $cmd); + ::core::assert!(i == $crate::ioctl::_IOC_NR(cmd)); + ::core::assert!(core::mem::size_of::<$crate::uapi::$struct>() == + $crate::ioctl::_IOC_SIZE(cmd)); + let i: u32 = i + 1; + )* + }; + + let ioctls = &[$( + $crate::drm::ioctl::internal::drm_ioctl_desc { + cmd: $crate::macros::concat_idents!(DRM_IOCTL_, $cmd) as u32, + func: { + #[allow(non_snake_case)] + unsafe extern "C" fn $cmd( + raw_dev: *mut $crate::drm::ioctl::internal::drm_device, + raw_data: *mut ::core::ffi::c_void, + raw_file: *mut $crate::drm::ioctl::internal::drm_file, + ) -> core::ffi::c_int { + // SAFETY: + // - The DRM core ensures the device lives while callbacks are being + // called. + // - The DRM device must have been registered when we're called through + // an IOCTL. + // + // FIXME: Currently there is nothing enforcing that the types of the + // dev/file match the current driver these ioctls are being declared + // for, and it's not clear how to enforce this within the type system. + let dev = $crate::drm::device::Device::as_ref(raw_dev); + // SAFETY: The ioctl argument has size `_IOC_SIZE(cmd)`, which we + // asserted above matches the size of this type, and all bit patterns of + // UAPI structs must be valid. + let data = unsafe { + &*(raw_data as *const $crate::types::Opaque<$crate::uapi::$struct>) + }; + // SAFETY: This is just the DRM file structure + let file = unsafe { $crate::drm::File::as_ref(raw_file) }; + + match $func(dev, data, file) { + Err(e) => e.to_errno(), + Ok(i) => i.try_into() + .unwrap_or($crate::error::code::ERANGE.to_errno()), + } + } + Some($cmd) + }, + flags: $flags, + name: $crate::c_str!(::core::stringify!($cmd)).as_char_ptr(), + } + ),*]; + ioctls + }; + }; +} diff --git a/rust/kernel/drm/mod.rs b/rust/kernel/drm/mod.rs new file mode 100644 index 000000000000..1b82b6945edf --- /dev/null +++ b/rust/kernel/drm/mod.rs @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +//! DRM subsystem abstractions. + +pub mod device; +pub mod driver; +pub mod file; +pub mod gem; +pub mod ioctl; + +pub use self::device::Device; +pub use self::driver::Driver; +pub use self::driver::DriverInfo; +pub use self::driver::Registration; +pub use self::file::File; + +pub(crate) mod private { + pub trait Sealed {} +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index de07aadd1ff5..ab0286857061 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -38,6 +38,8 @@ extern crate self as kernel; pub use ffi; pub mod alloc; +#[cfg(CONFIG_AUXILIARY_BUS)] +pub mod auxiliary; #[cfg(CONFIG_BLOCK)] pub mod block; #[doc(hidden)] @@ -48,6 +50,8 @@ pub mod device_id; pub mod devres; pub mod dma; pub mod driver; +#[cfg(CONFIG_DRM = "y")] +pub mod drm; pub mod error; pub mod faux; #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)] diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs index c97d6d470b28..38fc8d5ffbf9 100644 --- a/rust/kernel/pci.rs +++ b/rust/kernel/pci.rs @@ -6,7 +6,7 @@ use crate::{ alloc::flags::*, - bindings, device, + bindings, container_of, device, device_id::RawDeviceId, devres::Devres, driver, @@ -360,11 +360,13 @@ impl<const SIZE: usize> Deref for Bar<SIZE> { } } -impl Device { +impl<Ctx: device::DeviceContext> Device<Ctx> { fn as_raw(&self) -> *mut bindings::pci_dev { self.0.get() } +} +impl Device { /// Returns the PCI vendor ID. pub fn vendor_id(&self) -> u16 { // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`. @@ -388,7 +390,9 @@ impl Device { // - by its type invariant `self.as_raw` is always a valid pointer to a `struct pci_dev`. Ok(unsafe { bindings::pci_resource_len(self.as_raw(), bar.try_into()?) }) } +} +impl Device<device::Bound> { /// Mapps an entire PCI-BAR after performing a region-request on it. I/O operation bound checks /// can be performed on compile time for offsets (plus the requested type size) < SIZE. pub fn iomap_region_sized<const SIZE: usize>( @@ -422,25 +426,10 @@ impl Device<device::Core> { } } -impl Deref for Device<device::Core> { - type Target = Device; - - fn deref(&self) -> &Self::Target { - let ptr: *const Self = self; - - // CAST: `Device<Ctx>` is a transparent wrapper of `Opaque<bindings::pci_dev>`. - let ptr = ptr.cast::<Device>(); - - // SAFETY: `ptr` was derived from `&self`. - unsafe { &*ptr } - } -} - -impl From<&Device<device::Core>> for ARef<Device> { - fn from(dev: &Device<device::Core>) -> Self { - (&**dev).into() - } -} +// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic +// argument. +kernel::impl_device_context_deref!(unsafe { Device }); +kernel::impl_device_context_into_aref!(Device); // SAFETY: Instances of `Device` are always reference-counted. unsafe impl crate::types::AlwaysRefCounted for Device { @@ -455,8 +444,8 @@ unsafe impl crate::types::AlwaysRefCounted for Device { } } -impl AsRef<device::Device> for Device { - fn as_ref(&self) -> &device::Device { +impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> { + fn as_ref(&self) -> &device::Device<Ctx> { // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid // `struct pci_dev`. let dev = unsafe { addr_of_mut!((*self.as_raw()).dev) }; @@ -466,6 +455,26 @@ impl AsRef<device::Device> for Device { } } +impl<Ctx: device::DeviceContext> TryFrom<&device::Device<Ctx>> for &Device<Ctx> { + type Error = kernel::error::Error; + + fn try_from(dev: &device::Device<Ctx>) -> Result<Self, Self::Error> { + // SAFETY: By the type invariant of `Device`, `dev.as_raw()` is a valid pointer to a + // `struct device`. + if !unsafe { bindings::dev_is_pci(dev.as_raw()) } { + return Err(EINVAL); + } + + // SAFETY: We've just verified that the bus type of `dev` equals `bindings::pci_bus_type`, + // hence `dev` must be embedded in a valid `struct pci_dev` as guaranteed by the + // corresponding C code. + let pdev = unsafe { container_of!(dev.as_raw(), bindings::pci_dev, dev) }; + + // SAFETY: `pdev` is a valid pointer to a `struct pci_dev`. + Ok(unsafe { &*pdev.cast() }) + } +} + // SAFETY: A `Device` is always reference-counted and can be released from any thread. unsafe impl Send for Device {} diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs index 4917cb34e2fe..08849d92c074 100644 --- a/rust/kernel/platform.rs +++ b/rust/kernel/platform.rs @@ -5,18 +5,17 @@ //! C header: [`include/linux/platform_device.h`](srctree/include/linux/platform_device.h) use crate::{ - bindings, device, driver, + bindings, container_of, device, driver, error::{to_result, Result}, of, prelude::*, str::CStr, - types::{ARef, ForeignOwnable, Opaque}, + types::{ForeignOwnable, Opaque}, ThisModule, }; use core::{ marker::PhantomData, - ops::Deref, ptr::{addr_of_mut, NonNull}, }; @@ -184,31 +183,16 @@ pub struct Device<Ctx: device::DeviceContext = device::Normal>( PhantomData<Ctx>, ); -impl Device { +impl<Ctx: device::DeviceContext> Device<Ctx> { fn as_raw(&self) -> *mut bindings::platform_device { self.0.get() } } -impl Deref for Device<device::Core> { - type Target = Device; - - fn deref(&self) -> &Self::Target { - let ptr: *const Self = self; - - // CAST: `Device<Ctx>` is a transparent wrapper of `Opaque<bindings::platform_device>`. - let ptr = ptr.cast::<Device>(); - - // SAFETY: `ptr` was derived from `&self`. - unsafe { &*ptr } - } -} - -impl From<&Device<device::Core>> for ARef<Device> { - fn from(dev: &Device<device::Core>) -> Self { - (&**dev).into() - } -} +// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic +// argument. +kernel::impl_device_context_deref!(unsafe { Device }); +kernel::impl_device_context_into_aref!(Device); // SAFETY: Instances of `Device` are always reference-counted. unsafe impl crate::types::AlwaysRefCounted for Device { @@ -223,8 +207,8 @@ unsafe impl crate::types::AlwaysRefCounted for Device { } } -impl AsRef<device::Device> for Device { - fn as_ref(&self) -> &device::Device { +impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> { + fn as_ref(&self) -> &device::Device<Ctx> { // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid // `struct platform_device`. let dev = unsafe { addr_of_mut!((*self.as_raw()).dev) }; @@ -234,6 +218,26 @@ impl AsRef<device::Device> for Device { } } +impl<Ctx: device::DeviceContext> TryFrom<&device::Device<Ctx>> for &Device<Ctx> { + type Error = kernel::error::Error; + + fn try_from(dev: &device::Device<Ctx>) -> Result<Self, Self::Error> { + // SAFETY: By the type invariant of `Device`, `dev.as_raw()` is a valid pointer to a + // `struct device`. + if !unsafe { bindings::dev_is_platform(dev.as_raw()) } { + return Err(EINVAL); + } + + // SAFETY: We've just verified that the bus type of `dev` equals + // `bindings::platform_bus_type`, hence `dev` must be embedded in a valid + // `struct platform_device` as guaranteed by the corresponding C code. + let pdev = unsafe { container_of!(dev.as_raw(), bindings::platform_device, dev) }; + + // SAFETY: `pdev` is a valid pointer to a `struct platform_device`. + Ok(unsafe { &*pdev.cast() }) + } +} + // SAFETY: A `Device` is always reference-counted and can be released from any thread. unsafe impl Send for Device {} diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs index 1e5a9d25c21b..db4aa46bb121 100644 --- a/rust/kernel/revocable.rs +++ b/rust/kernel/revocable.rs @@ -123,6 +123,34 @@ impl<T> Revocable<T> { } } + /// Tries to access the wrapped object and run a closure on it while the guard is held. + /// + /// This is a convenience method to run short non-sleepable code blocks while ensuring the + /// guard is dropped afterwards. [`Self::try_access`] carries the risk that the caller will + /// forget to explicitly drop that returned guard before calling sleepable code; this method + /// adds an extra safety to make sure it doesn't happen. + /// + /// Returns [`None`] if the object has been revoked and is therefore no longer accessible, or + /// the result of the closure wrapped in [`Some`]. If the closure returns a [`Result`] then the + /// return type becomes `Option<Result<>>`, which can be inconvenient. Users are encouraged to + /// define their own macro that turns the [`Option`] into a proper error code and flattens the + /// inner result into it if it makes sense within their subsystem. + pub fn try_access_with<R, F: FnOnce(&T) -> R>(&self, f: F) -> Option<R> { + self.try_access().map(|t| f(&*t)) + } + + /// Directly access the revocable wrapped object. + /// + /// # Safety + /// + /// The caller must ensure this [`Revocable`] instance hasn't been revoked and won't be revoked + /// as long as the returned `&T` lives. + pub unsafe fn access(&self) -> &T { + // SAFETY: By the safety requirement of this function it is guaranteed that + // `self.data.get()` is a valid pointer to an instance of `T`. + unsafe { &*self.data.get() } + } + /// # Safety /// /// Callers must ensure that there are no more concurrent users of the revocable object. diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 9d0471afc964..eee387727d1a 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -329,6 +329,14 @@ impl<T> Opaque<T> { } } + /// Creates a new zeroed opaque value. + pub const fn zeroed() -> Self { + Self { + value: UnsafeCell::new(MaybeUninit::zeroed()), + _pin: PhantomPinned, + } + } + /// Create an opaque pin-initializer from the given pin-initializer. pub fn pin_init(slot: impl PinInit<T>) -> impl PinInit<Self> { Self::ffi_init(|ptr: *mut T| { diff --git a/rust/uapi/uapi_helper.h b/rust/uapi/uapi_helper.h index 76d3f103e764..1409441359f5 100644 --- a/rust/uapi/uapi_helper.h +++ b/rust/uapi/uapi_helper.h @@ -7,6 +7,8 @@ */ #include <uapi/asm-generic/ioctl.h> +#include <uapi/drm/drm.h> +#include <uapi/drm/nova_drm.h> #include <uapi/linux/mdio.h> #include <uapi/linux/mii.h> #include <uapi/linux/ethtool.h> diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig index cad52b7120b5..b1006ab4bc3c 100644 --- a/samples/rust/Kconfig +++ b/samples/rust/Kconfig @@ -82,6 +82,18 @@ config SAMPLE_RUST_DRIVER_FAUX If unsure, say N. +config SAMPLE_RUST_DRIVER_AUXILIARY + tristate "Auxiliary Driver" + depends on PCI + select AUXILIARY_BUS + help + This option builds the Rust auxiliary driver sample. + + To compile this as a module, choose M here: + the module will be called rust_driver_auxiliary. + + If unsure, say N. + config SAMPLE_RUST_HOSTPROGS bool "Host programs" help diff --git a/samples/rust/Makefile b/samples/rust/Makefile index c6a2479f7d9c..6a466afd2a21 100644 --- a/samples/rust/Makefile +++ b/samples/rust/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_SAMPLE_RUST_DMA) += rust_dma.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_PCI) += rust_driver_pci.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX) += rust_driver_faux.o +obj-$(CONFIG_SAMPLE_RUST_DRIVER_AUXILIARY) += rust_driver_auxiliary.o rust_print-y := rust_print_main.o rust_print_events.o diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs new file mode 100644 index 000000000000..3e15e6d002bb --- /dev/null +++ b/samples/rust/rust_driver_auxiliary.rs @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Rust auxiliary driver sample (based on a PCI driver for QEMU's `pci-testdev`). +//! +//! To make this driver probe, QEMU must be run with `-device pci-testdev`. + +use kernel::{ + auxiliary, bindings, c_str, device::Core, driver, error::Error, pci, prelude::*, str::CStr, + InPlaceModule, +}; + +use pin_init::PinInit; + +const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME; +const AUXILIARY_NAME: &CStr = c_str!("auxiliary"); + +struct AuxiliaryDriver; + +kernel::auxiliary_device_table!( + AUX_TABLE, + MODULE_AUX_TABLE, + <AuxiliaryDriver as auxiliary::Driver>::IdInfo, + [(auxiliary::DeviceId::new(MODULE_NAME, AUXILIARY_NAME), ())] +); + +impl auxiliary::Driver for AuxiliaryDriver { + type IdInfo = (); + + const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE; + + fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> { + dev_info!( + adev.as_ref(), + "Probing auxiliary driver for auxiliary device with id={}\n", + adev.id() + ); + + ParentDriver::connect(adev)?; + + let this = KBox::new(Self, GFP_KERNEL)?; + + Ok(this.into()) + } +} + +struct ParentDriver { + _reg: [auxiliary::Registration; 2], +} + +kernel::pci_device_table!( + PCI_TABLE, + MODULE_PCI_TABLE, + <ParentDriver as pci::Driver>::IdInfo, + [( + pci::DeviceId::from_id(bindings::PCI_VENDOR_ID_REDHAT, 0x5), + () + )] +); + +impl pci::Driver for ParentDriver { + type IdInfo = (); + + const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE; + + fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> { + let this = KBox::new( + Self { + _reg: [ + auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 0, MODULE_NAME)?, + auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 1, MODULE_NAME)?, + ], + }, + GFP_KERNEL, + )?; + + Ok(this.into()) + } +} + +impl ParentDriver { + fn connect(adev: &auxiliary::Device) -> Result<()> { + let parent = adev.parent().ok_or(EINVAL)?; + let pdev: &pci::Device = parent.try_into()?; + + dev_info!( + adev.as_ref(), + "Connect auxiliary {} with parent: VendorID={:#x}, DeviceID={:#x}\n", + adev.id(), + pdev.vendor_id(), + pdev.device_id() + ); + + Ok(()) + } +} + +#[pin_data] +struct SampleModule { + #[pin] + _pci_driver: driver::Registration<pci::Adapter<ParentDriver>>, + #[pin] + _aux_driver: driver::Registration<auxiliary::Adapter<AuxiliaryDriver>>, +} + +impl InPlaceModule for SampleModule { + fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> { + try_pin_init!(Self { + _pci_driver <- driver::Registration::new(MODULE_NAME, module), + _aux_driver <- driver::Registration::new(MODULE_NAME, module), + }) + } +} + +module! { + type: SampleModule, + name: "rust_driver_auxiliary", + author: "Danilo Krummrich", + description: "Rust auxiliary driver", + license: "GPL v2", +} diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs index 2bb260aebc9e..15147e4401b2 100644 --- a/samples/rust/rust_driver_pci.rs +++ b/samples/rust/rust_driver_pci.rs @@ -83,12 +83,11 @@ impl pci::Driver for SampleDriver { GFP_KERNEL, )?; - let bar = drvdata.bar.try_access().ok_or(ENXIO)?; - + let bar = drvdata.bar.access(pdev.as_ref())?; dev_info!( pdev.as_ref(), "pci-testdev data-match count: {}\n", - Self::testdev(info, &bar)? + Self::testdev(info, bar)? ); Ok(drvdata.into()) |