diff options
260 files changed, 6774 insertions, 4064 deletions
diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml index acfc327f70a7..a51baf8a4c76 100644 --- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml +++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml @@ -28,6 +28,7 @@ properties: - renesas,r8a7793-lvds # for R-Car M2-N compatible LVDS encoders - renesas,r8a7795-lvds # for R-Car H3 compatible LVDS encoders - renesas,r8a7796-lvds # for R-Car M3-W compatible LVDS encoders + - renesas,r8a77961-lvds # for R-Car M3-W+ compatible LVDS encoders - renesas,r8a77965-lvds # for R-Car M3-N compatible LVDS encoders - renesas,r8a77970-lvds # for R-Car V3M compatible LVDS encoders - renesas,r8a77980-lvds # for R-Car V3H compatible LVDS encoders diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml index 5457612ab136..cd05cfd76536 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -21,6 +21,7 @@ properties: - qcom,sc7280-edp - qcom,sc8180x-dp - qcom,sc8180x-edp + - qcom,sm8350-dp reg: items: diff --git a/Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml b/Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml new file mode 100644 index 000000000000..2df64afb76e6 --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml @@ -0,0 +1,219 @@ +# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/msm/dpu-msm8998.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Display DPU dt properties for MSM8998 target + +maintainers: + - AngeloGioacchino Del Regno <[email protected]> + +description: | + Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates + sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree + bindings of MDSS and DPU are mentioned for MSM8998 target. + +properties: + compatible: + items: + - const: qcom,msm8998-mdss + + reg: + maxItems: 1 + + reg-names: + const: mdss + + power-domains: + maxItems: 1 + + clocks: + items: + - description: Display AHB clock + - description: Display AXI clock + - description: Display core clock + + clock-names: + items: + - const: iface + - const: bus + - const: core + + interrupts: + maxItems: 1 + + interrupt-controller: true + + "#address-cells": true + + "#size-cells": true + + "#interrupt-cells": + const: 1 + + iommus: + items: + - description: Phandle to apps_smmu node with SID mask for Hard-Fail port0 + + ranges: true + +patternProperties: + "^display-controller@[0-9a-f]+$": + type: object + description: Node containing the properties of DPU. + + properties: + compatible: + items: + - const: qcom,msm8998-dpu + + reg: + items: + - description: Address offset and size for mdp register set + - description: Address offset and size for regdma register set + - description: Address offset and size for vbif register set + - description: Address offset and size for non-realtime vbif register set + + reg-names: + items: + - const: mdp + - const: regdma + - const: vbif + - const: vbif_nrt + + clocks: + items: + - description: Display ahb clock + - description: Display axi clock + - description: Display mem-noc clock + - description: Display core clock + - description: Display vsync clock + + clock-names: + items: + - const: iface + - const: bus + - const: mnoc + - const: core + - const: vsync + + interrupts: + maxItems: 1 + + power-domains: + maxItems: 1 + + operating-points-v2: true + ports: + $ref: /schemas/graph.yaml#/properties/ports + description: | + Contains the list of output ports from DPU device. These ports + connect to interfaces that are external to the DPU hardware, + such as DSI, DP etc. Each output port contains an endpoint that + describes how it is connected to an external interface. + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: DPU_INTF1 (DSI1) + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: DPU_INTF2 (DSI2) + + required: + - port@0 + - port@1 + + required: + - compatible + - reg + - reg-names + - clocks + - interrupts + - power-domains + - operating-points-v2 + - ports + +required: + - compatible + - reg + - reg-names + - power-domains + - clocks + - interrupts + - interrupt-controller + - iommus + - ranges + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/qcom,mmcc-msm8998.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/power/qcom-rpmpd.h> + + mdss: display-subsystem@c900000 { + compatible = "qcom,msm8998-mdss"; + reg = <0x0c900000 0x1000>; + reg-names = "mdss"; + + clocks = <&mmcc MDSS_AHB_CLK>, + <&mmcc MDSS_AXI_CLK>, + <&mmcc MDSS_MDP_CLK>; + clock-names = "iface", "bus", "core"; + + #address-cells = <1>; + #interrupt-cells = <1>; + #size-cells = <1>; + + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + iommus = <&mmss_smmu 0>; + + power-domains = <&mmcc MDSS_GDSC>; + ranges; + + display-controller@c901000 { + compatible = "qcom,msm8998-dpu"; + reg = <0x0c901000 0x8f000>, + <0x0c9a8e00 0xf0>, + <0x0c9b0000 0x2008>, + <0x0c9b8000 0x1040>; + reg-names = "mdp", "regdma", "vbif", "vbif_nrt"; + + clocks = <&mmcc MDSS_AHB_CLK>, + <&mmcc MDSS_AXI_CLK>, + <&mmcc MNOC_AHB_CLK>, + <&mmcc MDSS_MDP_CLK>, + <&mmcc MDSS_VSYNC_CLK>; + clock-names = "iface", "bus", "mnoc", "core", "vsync"; + + interrupt-parent = <&mdss>; + interrupts = <0>; + operating-points-v2 = <&mdp_opp_table>; + power-domains = <&rpmpd MSM8998_VDDMX>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dpu_intf1_out: endpoint { + remote-endpoint = <&dsi0_in>; + }; + }; + + port@1 { + reg = <1>; + dpu_intf2_out: endpoint { + remote-endpoint = <&dsi1_in>; + }; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml b/Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml new file mode 100644 index 000000000000..d31483a78eab --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/dpu-qcm2290.yaml @@ -0,0 +1,215 @@ +# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/msm/dpu-qcm2290.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Display DPU dt properties for QCM2290 target + +maintainers: + - Loic Poulain <[email protected]> + +description: | + Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates + sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS + and DPU are mentioned for QCM2290 target. + +properties: + compatible: + items: + - const: qcom,qcm2290-mdss + + reg: + maxItems: 1 + + reg-names: + const: mdss + + power-domains: + maxItems: 1 + + clocks: + items: + - description: Display AHB clock from gcc + - description: Display AXI clock + - description: Display core clock + + clock-names: + items: + - const: iface + - const: bus + - const: core + + interrupts: + maxItems: 1 + + interrupt-controller: true + + "#address-cells": true + + "#size-cells": true + + "#interrupt-cells": + const: 1 + + iommus: + items: + - description: Phandle to apps_smmu node with SID mask for Hard-Fail port0 + - description: Phandle to apps_smmu node with SID mask for Hard-Fail port1 + + ranges: true + + interconnects: + items: + - description: Interconnect path specifying the port ids for data bus + + interconnect-names: + const: mdp0-mem + +patternProperties: + "^display-controller@[0-9a-f]+$": + type: object + description: Node containing the properties of DPU. + + properties: + compatible: + items: + - const: qcom,qcm2290-dpu + + reg: + items: + - description: Address offset and size for mdp register set + - description: Address offset and size for vbif register set + + reg-names: + items: + - const: mdp + - const: vbif + + clocks: + items: + - description: Display AXI clock from gcc + - description: Display AHB clock from dispcc + - description: Display core clock from dispcc + - description: Display lut clock from dispcc + - description: Display vsync clock from dispcc + + clock-names: + items: + - const: bus + - const: iface + - const: core + - const: lut + - const: vsync + + interrupts: + maxItems: 1 + + power-domains: + maxItems: 1 + + operating-points-v2: true + + ports: + $ref: /schemas/graph.yaml#/properties/ports + description: | + Contains the list of output ports from DPU device. These ports + connect to interfaces that are external to the DPU hardware, + such as DSI. Each output port contains an endpoint that + describes how it is connected to an external interface. + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: DPU_INTF1 (DSI1) + + required: + - port@0 + + required: + - compatible + - reg + - reg-names + - clocks + - interrupts + - power-domains + - operating-points-v2 + - ports + +required: + - compatible + - reg + - reg-names + - power-domains + - clocks + - interrupts + - interrupt-controller + - iommus + - ranges + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/qcom,dispcc-qcm2290.h> + #include <dt-bindings/clock/qcom,gcc-qcm2290.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interconnect/qcom,qcm2290.h> + #include <dt-bindings/power/qcom-rpmpd.h> + + mdss: mdss@5e00000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "qcom,qcm2290-mdss", "qcom,mdss"; + reg = <0x05e00000 0x1000>; + reg-names = "mdss"; + power-domains = <&dispcc MDSS_GDSC>; + clocks = <&gcc GCC_DISP_AHB_CLK>, + <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>; + clock-names = "iface", "bus", "core"; + + interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <1>; + + interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>; + interconnect-names = "mdp0-mem"; + + iommus = <&apps_smmu 0x420 0x2>, + <&apps_smmu 0x421 0x0>; + ranges; + + mdss_mdp: mdp@5e01000 { + compatible = "qcom,qcm2290-dpu"; + reg = <0x05e01000 0x8f000>, + <0x05eb0000 0x2008>; + reg-names = "mdp", "vbif"; + + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_AHB_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>, + <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>, + <&dispcc DISP_CC_MDSS_VSYNC_CLK>; + clock-names = "bus", "iface", "core", "lut", "vsync"; + + operating-points-v2 = <&mdp_opp_table>; + power-domains = <&rpmpd QCM2290_VDDCX>; + + interrupt-parent = <&mdss>; + interrupts = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dpu_intf1_out: endpoint { + remote-endpoint = <&dsi0_in>; + }; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml index 35426fde8610..7095ec3c890d 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml @@ -14,8 +14,9 @@ allOf: properties: compatible: - items: - - const: qcom,mdss-dsi-ctrl + enum: + - qcom,mdss-dsi-ctrl + - qcom,dsi-ctrl-6g-qcm2290 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml index 4399715953e1..2d5a766d028f 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml @@ -35,6 +35,38 @@ properties: Connected to DSI0_MIPI_DSI_PLL_VDDA0P9 pin for sc7180 target and connected to VDDA_MIPI_DSI_0_PLL_0P9 pin for sdm845 target + qcom,phy-rescode-offset-top: + $ref: /schemas/types.yaml#/definitions/int8-array + minItems: 5 + maxItems: 5 + description: + Integer array of offset for pull-up legs rescode for all five lanes. + To offset the drive strength from the calibrated value in an increasing + manner, -32 is the weakest and +31 is the strongest. + items: + minimum: -32 + maximum: 31 + + qcom,phy-rescode-offset-bot: + $ref: /schemas/types.yaml#/definitions/int8-array + minItems: 5 + maxItems: 5 + description: + Integer array of offset for pull-down legs rescode for all five lanes. + To offset the drive strength from the calibrated value in a decreasing + manner, -32 is the weakest and +31 is the strongest. + items: + minimum: -32 + maximum: 31 + + qcom,phy-drive-ldo-level: + $ref: "/schemas/types.yaml#/definitions/uint32" + description: + The PHY LDO has an amplitude tuning feature to adjust the LDO output + for the HSTX drive. Use supported levels (mV) to offset the drive level + from the default value. + enum: [ 375, 400, 425, 450, 475, 500 ] + required: - compatible - reg @@ -64,5 +96,9 @@ examples: clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, <&rpmhcc RPMH_CXO_CLK>; clock-names = "iface", "ref"; + + qcom,phy-rescode-offset-top = /bits/ 8 <0 0 0 0 0>; + qcom,phy-rescode-offset-bot = /bits/ 8 <0 0 0 0 0>; + qcom,phy-drive-ldo-level = <400>; }; ... diff --git a/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml new file mode 100644 index 000000000000..f29789994b18 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml @@ -0,0 +1,126 @@ +# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/panel-mipi-dbi-spi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MIPI DBI SPI Panel + +maintainers: + - Noralf Trønnes <[email protected]> + +description: | + This binding is for display panels using a MIPI DBI compatible controller + in SPI mode. + + The MIPI Alliance Standard for Display Bus Interface defines the electrical + and logical interfaces for display controllers historically used in mobile + phones. The standard defines 4 display architecture types and this binding is + for type 1 which has full frame memory. There are 3 interface types in the + standard and type C is the serial interface. + + The standard defines the following interface signals for type C: + - Power: + - Vdd: Power supply for display module + - Vddi: Logic level supply for interface signals + Combined into one in this binding called: power-supply + - Interface: + - CSx: Chip select + - SCL: Serial clock + - Dout: Serial out + - Din: Serial in + - SDA: Bidrectional in/out + - D/CX: Data/command selection, high=data, low=command + Called dc-gpios in this binding. + - RESX: Reset when low + Called reset-gpios in this binding. + + The type C interface has 3 options: + + - Option 1: 9-bit mode and D/CX as the 9th bit + | Command | the next command or following data | + |<0><D7><D6><D5><D4><D3><D2><D1><D0>|<D/CX><D7><D6><D5><D4><D3><D2><D1><D0>| + + - Option 2: 16-bit mode and D/CX as a 9th bit + | Command or data | + |<X><X><X><X><X><X><X><D/CX><D7><D6><D5><D4><D3><D2><D1><D0>| + + - Option 3: 8-bit mode and D/CX as a separate interface line + | Command or data | + |<D7><D6><D5><D4><D3><D2><D1><D0>| + + The panel resolution is specified using the panel-timing node properties + hactive (width) and vactive (height). The other mandatory panel-timing + properties should be set to zero except clock-frequency which can be + optionally set to inform about the actual pixel clock frequency. + + If the panel is wired to the controller at an offset specify this using + hback-porch (x-offset) and vback-porch (y-offset). + +allOf: + - $ref: panel-common.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + items: + - enum: + - sainsmart18 + - const: panel-mipi-dbi-spi + + write-only: + type: boolean + description: + Controller is not readable (ie. Din (MISO on the SPI interface) is not + wired up). + + dc-gpios: + maxItems: 1 + description: | + Controller data/command selection (D/CX) in 4-line SPI mode. + If not set, the controller is in 3-line SPI mode. + +required: + - compatible + - reg + - panel-timing + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + spi { + #address-cells = <1>; + #size-cells = <0>; + + display@0{ + compatible = "sainsmart18", "panel-mipi-dbi-spi"; + reg = <0>; + spi-max-frequency = <40000000>; + + dc-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; + write-only; + + backlight = <&backlight>; + + width-mm = <35>; + height-mm = <28>; + + panel-timing { + hactive = <160>; + vactive = <128>; + hback-porch = <0>; + vback-porch = <0>; + clock-frequency = <0>; + hfront-porch = <0>; + hsync-len = <0>; + vfront-porch = <0>; + vsync-len = <0>; + }; + }; + }; + +... diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 7bf7f2111696..127e76ee0b2d 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -241,6 +241,28 @@ Contact: Thomas Zimmermann <[email protected]>, Daniel Vetter Level: Advanced +Benchmark and optimize blitting and format-conversion function +-------------------------------------------------------------- + +Drawing to dispay memory quickly is crucial for many applications' +performance. + +On at least x86-64, sys_imageblit() is significantly slower than +cfb_imageblit(), even though both use the same blitting algorithm and +the latter is written for I/O memory. It turns out that cfb_imageblit() +uses movl instructions, while sys_imageblit apparently does not. This +seems to be a problem with gcc's optimizer. DRM's format-conversion +helpers might be subject to similar issues. + +Benchmark and optimize fbdev's sys_() helpers and DRM's format-conversion +helpers. In cases that can be further optimized, maybe implement a different +algorithm. For micro-optimizations, use movl/movq instructions explicitly. +That might possibly require architecture-specific helpers (e.g., storel() +storeq()). + +Contact: Thomas Zimmermann <[email protected]> + +Level: Intermediate drm_framebuffer_funcs and drm_mode_config_funcs.fb_create cleanup ----------------------------------------------------------------- @@ -475,8 +497,12 @@ This is a really varied tasks with lots of little bits and pieces: achieved by using an IPI to the local processor. * There's a massive confusion of different panic handlers. DRM fbdev emulation - helpers have one, but on top of that the fbcon code itself also has one. We - need to make sure that they stop fighting over each another. + helpers had their own (long removed), but on top of that the fbcon code itself + also has one. We need to make sure that they stop fighting over each other. + This is worked around by checking ``oops_in_progress`` at various entry points + into the DRM fbdev emulation helpers. A much cleaner approach here would be to + switch fbcon to the `threaded printk support + <https://lwn.net/Articles/800946/>`_. * ``drm_can_sleep()`` is a mess. It hides real bugs in normal operations and isn't a full solution for panic paths. We need to make sure that it only @@ -488,16 +514,15 @@ This is a really varied tasks with lots of little bits and pieces: even spinlocks (because NMI and hardirq can panic too). We need to either make sure to not call such paths, or trylock everything. Really tricky. -* For the above locking troubles reasons it's pretty much impossible to - attempt a synchronous modeset from panic handlers. The only thing we could - try to achive is an atomic ``set_base`` of the primary plane, and hope that - it shows up. Everything else probably needs to be delayed to some worker or - something else which happens later on. Otherwise it just kills the box - harder, prevent the panic from going out on e.g. netconsole. +* A clean solution would be an entirely separate panic output support in KMS, + bypassing the current fbcon support. See `[PATCH v2 0/3] drm: Add panic handling + <https://lore.kernel.org/dri-devel/[email protected]/>`_. -* There's also proposal for a simplied DRM console instead of the full-blown - fbcon and DRM fbdev emulation. Any kind of panic handling tricks should - obviously work for both console, in case we ever get kmslog merged. +* Encoding the actual oops and preceding dmesg in a QR might help with the + dread "important stuff scrolled away" problem. See `[RFC][PATCH] Oops messages + transfer using QR codes + <https://lore.kernel.org/lkml/[email protected]/>`_ + for some example code that could be reused. Contact: Daniel Vetter diff --git a/MAINTAINERS b/MAINTAINERS index e0ad1bc5b9d4..18d799bb66ec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6112,6 +6112,14 @@ T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt F: drivers/gpu/drm/tiny/mi0283qt.c +DRM DRIVER FOR MIPI DBI compatible panels +M: Noralf Trønnes <[email protected]> +S: Maintained +W: https://github.com/notro/panel-mipi-dbi/wiki +T: git git://anongit.freedesktop.org/drm/drm-misc +F: Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml +F: drivers/gpu/drm/tiny/panel-mipi-dbi.c + DRM DRIVER FOR MSM ADRENO GPU M: Rob Clark <[email protected]> M: Sean Paul <[email protected]> diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx.h b/drivers/gpu/drm/aspeed/aspeed_gfx.h index 96501152bafa..4e6a442c3886 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx.h +++ b/drivers/gpu/drm/aspeed/aspeed_gfx.h @@ -12,6 +12,7 @@ struct aspeed_gfx { struct regmap *scu; u32 dac_reg; + u32 int_clr_reg; u32 vga_scratch_reg; u32 throd_val; u32 scan_line_max; diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c index 13f496473b9e..7780b72de9e8 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c @@ -61,6 +61,7 @@ struct aspeed_gfx_config { u32 dac_reg; /* DAC register in SCU */ + u32 int_clear_reg; /* Interrupt clear register */ u32 vga_scratch_reg; /* VGA scratch register in SCU */ u32 throd_val; /* Default Threshold Seting */ u32 scan_line_max; /* Max memory size of one scan line */ @@ -68,6 +69,7 @@ struct aspeed_gfx_config { static const struct aspeed_gfx_config ast2400_config = { .dac_reg = 0x2c, + .int_clear_reg = 0x60, .vga_scratch_reg = 0x50, .throd_val = CRT_THROD_LOW(0x1e) | CRT_THROD_HIGH(0x12), .scan_line_max = 64, @@ -75,14 +77,24 @@ static const struct aspeed_gfx_config ast2400_config = { static const struct aspeed_gfx_config ast2500_config = { .dac_reg = 0x2c, + .int_clear_reg = 0x60, .vga_scratch_reg = 0x50, .throd_val = CRT_THROD_LOW(0x24) | CRT_THROD_HIGH(0x3c), .scan_line_max = 128, }; +static const struct aspeed_gfx_config ast2600_config = { + .dac_reg = 0xc0, + .int_clear_reg = 0x68, + .vga_scratch_reg = 0x50, + .throd_val = CRT_THROD_LOW(0x50) | CRT_THROD_HIGH(0x70), + .scan_line_max = 128, +}; + static const struct of_device_id aspeed_gfx_match[] = { { .compatible = "aspeed,ast2400-gfx", .data = &ast2400_config }, { .compatible = "aspeed,ast2500-gfx", .data = &ast2500_config }, + { .compatible = "aspeed,ast2600-gfx", .data = &ast2600_config }, { }, }; MODULE_DEVICE_TABLE(of, aspeed_gfx_match); @@ -120,7 +132,7 @@ static irqreturn_t aspeed_gfx_irq_handler(int irq, void *data) if (reg & CRT_CTRL_VERTICAL_INTR_STS) { drm_crtc_handle_vblank(&priv->pipe.crtc); - writel(reg, priv->base + CRT_CTRL1); + writel(reg, priv->base + priv->int_clr_reg); return IRQ_HANDLED; } @@ -148,6 +160,7 @@ static int aspeed_gfx_load(struct drm_device *drm) config = match->data; priv->dac_reg = config->dac_reg; + priv->int_clr_reg = config->int_clear_reg; priv->vga_scratch_reg = config->vga_scratch_reg; priv->throd_val = config->throd_val; priv->scan_line_max = config->scan_line_max; diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 633618bafd75..31ecf5626f1d 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -253,6 +253,8 @@ static int anx7625_aux_trans(struct anx7625_data *ctx, u8 op, u32 address, addrm = (address >> 8) & 0xFF; addrh = (address >> 16) & 0xFF; + if (!is_write) + op &= ~DP_AUX_I2C_MOT; cmd = DPCD_CMD(len, op); /* Set command and length */ @@ -2736,8 +2738,8 @@ static int anx7625_i2c_remove(struct i2c_client *client) if (platform->hdcp_workqueue) { cancel_delayed_work(&platform->hdcp_work); - flush_workqueue(platform->workqueue); - destroy_workqueue(platform->workqueue); + flush_workqueue(platform->hdcp_workqueue); + destroy_workqueue(platform->hdcp_workqueue); } if (!platform->pdata.low_power_mode) diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c index d8a15c459b42..829e1a144656 100644 --- a/drivers/gpu/drm/bridge/cdns-dsi.c +++ b/drivers/gpu/drm/bridge/cdns-dsi.c @@ -1284,6 +1284,7 @@ static const struct of_device_id cdns_dsi_of_match[] = { { .compatible = "cdns,dsi" }, { }, }; +MODULE_DEVICE_TABLE(of, cdns_dsi_of_match); static struct platform_driver cdns_dsi_platform_driver = { .probe = cdns_dsi_drm_probe, diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index e8f36dca56b3..d9b7f48b99fb 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -191,7 +191,6 @@ static const struct drm_bridge_funcs chipone_bridge_funcs = { static int chipone_parse_dt(struct chipone *icn) { struct device *dev = icn->dev; - struct drm_panel *panel; int ret; icn->vdd1 = devm_regulator_get_optional(dev, "vdd1"); @@ -227,11 +226,7 @@ static int chipone_parse_dt(struct chipone *icn) return PTR_ERR(icn->enable_gpio); } - ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL); - if (ret) - return ret; - - icn->panel_bridge = devm_drm_panel_bridge_add(dev, panel); + icn->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); if (IS_ERR(icn->panel_bridge)) return PTR_ERR(icn->panel_bridge); diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index fb16a176822d..f2f101220ade 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -289,7 +289,7 @@ #define WORD_LENGTH_20BIT 2 #define WORD_LENGTH_24BIT 3 #define DEBUGFS_DIR_NAME "it6505-debugfs" -#define READ_BUFFER_SIZE 200 +#define READ_BUFFER_SIZE 400 /* Vendor option */ #define HDCP_DESIRED 1 @@ -3074,7 +3074,7 @@ static ssize_t receive_timing_debugfs_show(struct file *file, char __user *buf, struct it6505 *it6505 = file->private_data; struct drm_display_mode *vid = &it6505->video_info; u8 read_buf[READ_BUFFER_SIZE]; - u8 *str = read_buf, *end = read_buf + PAGE_SIZE; + u8 *str = read_buf, *end = read_buf + READ_BUFFER_SIZE; ssize_t ret, count; if (!it6505) diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 963a6794735f..d5945501a5ee 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -332,17 +332,13 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi) static int nwl_dsi_init_interrupts(struct nwl_dsi *dsi) { - u32 irq_enable; - - nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, 0xffffffff); - nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7); - - irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK | - NWL_DSI_RX_PKT_HDR_RCVD_MASK | - NWL_DSI_TX_FIFO_OVFLW_MASK | - NWL_DSI_HS_TX_TIMEOUT_MASK); + u32 irq_enable = ~(u32)(NWL_DSI_TX_PKT_DONE_MASK | + NWL_DSI_RX_PKT_HDR_RCVD_MASK | + NWL_DSI_TX_FIFO_OVFLW_MASK | + NWL_DSI_HS_TX_TIMEOUT_MASK); nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK, irq_enable); + nwl_dsi_write(dsi, NWL_DSI_IRQ_MASK2, 0x7); return nwl_dsi_clear_error(dsi); } diff --git a/drivers/gpu/drm/dp/drm_dp.c b/drivers/gpu/drm/dp/drm_dp.c index e159b81800d4..703972ae14c6 100644 --- a/drivers/gpu/drm/dp/drm_dp.c +++ b/drivers/gpu/drm/dp/drm_dp.c @@ -208,16 +208,6 @@ bool drm_dp_128b132b_link_training_failed(const u8 link_status[DP_LINK_STATUS_SI } EXPORT_SYMBOL(drm_dp_128b132b_link_training_failed); -u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZE], - unsigned int lane) -{ - unsigned int offset = DP_ADJUST_REQUEST_POST_CURSOR2; - u8 value = dp_link_status(link_status, offset); - - return (value >> (lane << 1)) & 0x3; -} -EXPORT_SYMBOL(drm_dp_get_adjust_request_post_cursor); - static int __8b10b_clock_recovery_delay_us(const struct drm_dp_aux *aux, u8 rd_interval) { if (rd_interval > 4) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index ddcf5c2c8e6a..3b6d3bdbd099 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -243,11 +243,36 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state, struct drm_plane *plane) { + u64 val; + plane_state->plane = plane; plane_state->rotation = DRM_MODE_ROTATE_0; plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE; plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; + + if (plane->color_encoding_property) { + if (!drm_object_property_get_default_value(&plane->base, + plane->color_encoding_property, + &val)) + plane_state->color_encoding = val; + } + + if (plane->color_range_property) { + if (!drm_object_property_get_default_value(&plane->base, + plane->color_range_property, + &val)) + plane_state->color_range = val; + } + + if (plane->zpos_property) { + if (!drm_object_property_get_default_value(&plane->base, + plane->zpos_property, + &val)) { + plane_state->zpos = val; + plane_state->normalized_zpos = val; + } + } } EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset); diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index 86d9e907c0b2..ba1608effc0f 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -297,11 +297,26 @@ int drm_object_property_set_value(struct drm_mode_object *obj, } EXPORT_SYMBOL(drm_object_property_set_value); +static int __drm_object_property_get_prop_value(struct drm_mode_object *obj, + struct drm_property *property, + uint64_t *val) +{ + int i; + + for (i = 0; i < obj->properties->count; i++) { + if (obj->properties->properties[i] == property) { + *val = obj->properties->values[i]; + return 0; + } + } + + return -EINVAL; +} + static int __drm_object_property_get_value(struct drm_mode_object *obj, struct drm_property *property, uint64_t *val) { - int i; /* read-only properties bypass atomic mechanism and still store * their value in obj->properties->values[].. mostly to avoid @@ -311,15 +326,7 @@ static int __drm_object_property_get_value(struct drm_mode_object *obj, !(property->flags & DRM_MODE_PROP_IMMUTABLE)) return drm_atomic_get_property(obj, property, val); - for (i = 0; i < obj->properties->count; i++) { - if (obj->properties->properties[i] == property) { - *val = obj->properties->values[i]; - return 0; - } - - } - - return -EINVAL; + return __drm_object_property_get_prop_value(obj, property, val); } /** @@ -348,6 +355,32 @@ int drm_object_property_get_value(struct drm_mode_object *obj, } EXPORT_SYMBOL(drm_object_property_get_value); +/** + * drm_object_property_get_default_value - retrieve the default value of a + * property when in atomic mode. + * @obj: drm mode object to get property value from + * @property: property to retrieve + * @val: storage for the property value + * + * This function retrieves the default state of the given property as passed in + * to drm_object_attach_property + * + * Only atomic drivers should call this function directly, as for non-atomic + * drivers it will return the current value. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_object_property_get_default_value(struct drm_mode_object *obj, + struct drm_property *property, + uint64_t *val) +{ + WARN_ON(!drm_drv_uses_atomic_modeset(property->dev)); + + return __drm_object_property_get_prop_value(obj, property, val); +} +EXPORT_SYMBOL(drm_object_property_get_default_value); + /* helper for getconnector and getproperties ioctls */ int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, uint32_t __user *prop_ptr, diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 96b13e36293c..3f819c7a021b 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -35,6 +35,7 @@ #include <linux/list_sort.h> #include <linux/export.h> +#include <video/of_display_timing.h> #include <video/of_videomode.h> #include <video/videomode.h> @@ -127,7 +128,7 @@ EXPORT_SYMBOL(drm_mode_probed_add); * according to the hdisplay, vdisplay, vrefresh. * It is based from the VESA(TM) Coordinated Video Timing Generator by * Graham Loveridge April 9, 2003 available at - * http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls + * http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls * * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c. * What I have done is to translate it by using integer calculation. @@ -727,6 +728,54 @@ int of_get_drm_display_mode(struct device_node *np, return 0; } EXPORT_SYMBOL_GPL(of_get_drm_display_mode); + +/** + * of_get_drm_panel_display_mode - get a panel-timing drm_display_mode from devicetree + * @np: device_node with the panel-timing specification + * @dmode: will be set to the return value + * @bus_flags: information about pixelclk, sync and DE polarity + * + * The Device Tree properties width-mm and height-mm will be read and set on + * the display mode if they are present. + * + * Returns: + * Zero on success, negative error code on failure. + */ +int of_get_drm_panel_display_mode(struct device_node *np, + struct drm_display_mode *dmode, u32 *bus_flags) +{ + u32 width_mm = 0, height_mm = 0; + struct display_timing timing; + struct videomode vm; + int ret; + + ret = of_get_display_timing(np, "panel-timing", &timing); + if (ret) + return ret; + + videomode_from_timing(&timing, &vm); + + memset(dmode, 0, sizeof(*dmode)); + drm_display_mode_from_videomode(&vm, dmode); + if (bus_flags) + drm_bus_flags_from_videomode(&vm, bus_flags); + + ret = of_property_read_u32(np, "width-mm", &width_mm); + if (ret && ret != -EINVAL) + return ret; + + ret = of_property_read_u32(np, "height-mm", &height_mm); + if (ret && ret != -EINVAL) + return ret; + + dmode->width_mm = width_mm; + dmode->height_mm = height_mm; + + drm_mode_debug_printmodeline(dmode); + + return 0; +} +EXPORT_SYMBOL_GPL(of_get_drm_panel_display_mode); #endif /* CONFIG_OF */ #endif /* CONFIG_VIDEOMODE_HELPERS */ diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 59d368ea006b..9d90cd75c457 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -249,6 +249,21 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, if (panel) *panel = NULL; + /** + * Devices can also be child nodes when we also control that device + * through the upstream device (ie, MIPI-DCS for a MIPI-DSI device). + * + * Lookup for a child node of the given parent that isn't either port + * or ports. + */ + for_each_available_child_of_node(np, remote) { + if (of_node_name_eq(remote, "port") || + of_node_name_eq(remote, "ports")) + continue; + + goto of_find_panel_or_bridge; + } + /* * of_graph_get_remote_node() produces a noisy error message if port * node isn't found and the absence of the port is a legit case here, @@ -259,6 +274,8 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, return -ENODEV; remote = of_graph_get_remote_node(np, port, endpoint); + +of_find_panel_or_bridge: if (!remote) return -ENODEV; diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 12571ac45540..c04264f70ad1 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -678,7 +678,6 @@ static int decon_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct decon_context *ctx; struct device_node *i80_if_timings; - struct resource *res; int ret; if (!dev->of_node) @@ -728,16 +727,11 @@ static int decon_probe(struct platform_device *pdev) goto err_iounmap; } - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, - ctx->i80_if ? "lcd_sys" : "vsync"); - if (!res) { - dev_err(dev, "irq request failed.\n"); - ret = -ENXIO; + ret = platform_get_irq_byname(pdev, ctx->i80_if ? "lcd_sys" : "vsync"); + if (ret < 0) goto err_iounmap; - } - ret = devm_request_irq(dev, res->start, decon_irq_handler, - 0, "drm_decon", ctx); + ret = devm_request_irq(dev, ret, decon_irq_handler, 0, "drm_decon", ctx); if (ret) { dev_err(dev, "irq request failed.\n"); goto err_iounmap; diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index b7d0a4aead0a..334862d422e2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1335,8 +1335,10 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi, int ret; int te_gpio_irq; - dsi->te_gpio = devm_gpiod_get_optional(dsi->dev, "te", GPIOD_IN); - if (IS_ERR(dsi->te_gpio)) { + dsi->te_gpio = gpiod_get_optional(panel, "te", GPIOD_IN); + if (!dsi->te_gpio) { + return 0; + } else if (IS_ERR(dsi->te_gpio)) { dev_err(dsi->dev, "gpio request failed with %ld\n", PTR_ERR(dsi->te_gpio)); return PTR_ERR(dsi->te_gpio); diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 023f54ee61a8..0ee32e4b1e43 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -1267,7 +1267,6 @@ static int fimc_probe(struct platform_device *pdev) struct exynos_drm_ipp_formats *formats; struct device *dev = &pdev->dev; struct fimc_context *ctx; - struct resource *res; int ret; int i, j, num_limits, num_formats; @@ -1330,14 +1329,12 @@ static int fimc_probe(struct platform_device *pdev) return PTR_ERR(ctx->regs); /* resource irq */ - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "failed to request irq resource.\n"); - return -ENOENT; - } + ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; - ret = devm_request_irq(dev, res->start, fimc_irq_handler, - 0, dev_name(dev), ctx); + ret = devm_request_irq(dev, ret, fimc_irq_handler, + 0, dev_name(dev), ctx); if (ret < 0) { dev_err(dev, "failed to request irq.\n"); return ret; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index c735e53939d8..d5720fab510c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -109,6 +109,7 @@ struct fimd_driver_data { unsigned int has_dp_clk:1; unsigned int has_hw_trigger:1; unsigned int has_trigger_per_te:1; + unsigned int has_bgr_support:1; }; static struct fimd_driver_data s3c64xx_fimd_driver_data = { @@ -138,6 +139,7 @@ static struct fimd_driver_data exynos4_fimd_driver_data = { .lcdblk_bypass_shift = 1, .has_shadowcon = 1, .has_vtsel = 1, + .has_bgr_support = 1, }; static struct fimd_driver_data exynos5_fimd_driver_data = { @@ -149,6 +151,7 @@ static struct fimd_driver_data exynos5_fimd_driver_data = { .has_vidoutcon = 1, .has_vtsel = 1, .has_dp_clk = 1, + .has_bgr_support = 1, }; static struct fimd_driver_data exynos5420_fimd_driver_data = { @@ -162,6 +165,7 @@ static struct fimd_driver_data exynos5420_fimd_driver_data = { .has_vtsel = 1, .has_mic_bypass = 1, .has_dp_clk = 1, + .has_bgr_support = 1, }; struct fimd_context { @@ -226,6 +230,18 @@ static const uint32_t fimd_formats[] = { DRM_FORMAT_ARGB8888, }; +static const uint32_t fimd_extended_formats[] = { + DRM_FORMAT_C8, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_XBGR1555, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_ABGR8888, +}; + static const unsigned int capabilities[WINDOWS_NR] = { 0, EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND, @@ -673,21 +689,25 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, val |= WINCONx_BYTSWP; break; case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XBGR1555: val |= WINCON0_BPPMODE_16BPP_1555; val |= WINCONx_HAWSWP; val |= WINCONx_BURSTLEN_16WORD; break; case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: val |= WINCON0_BPPMODE_16BPP_565; val |= WINCONx_HAWSWP; val |= WINCONx_BURSTLEN_16WORD; break; case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: val |= WINCON0_BPPMODE_24BPP_888; val |= WINCONx_WSWP; val |= WINCONx_BURSTLEN_16WORD; break; case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: default: val |= WINCON1_BPPMODE_25BPP_A1888; val |= WINCONx_WSWP; @@ -695,6 +715,18 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, break; } + switch (pixel_format) { + case DRM_FORMAT_XBGR1555: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_BGR565: + writel(WIN_RGB_ORDER_REVERSE, ctx->regs + WIN_RGB_ORDER(win)); + break; + default: + writel(WIN_RGB_ORDER_FORWARD, ctx->regs + WIN_RGB_ORDER(win)); + break; + } + /* * Setting dma-burst to 16Word causes permanent tearing for very small * buffers, e.g. cursor buffer. Burst Mode switching which based on @@ -1074,8 +1106,14 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) ctx->drm_dev = drm_dev; for (i = 0; i < WINDOWS_NR; i++) { - ctx->configs[i].pixel_formats = fimd_formats; - ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats); + if (ctx->driver_data->has_bgr_support) { + ctx->configs[i].pixel_formats = fimd_extended_formats; + ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_extended_formats); + } else { + ctx->configs[i].pixel_formats = fimd_formats; + ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats); + } + ctx->configs[i].zpos = i; ctx->configs[i].type = fimd_win_types[i]; ctx->configs[i].capabilities = capabilities[i]; @@ -1133,7 +1171,6 @@ static int fimd_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct fimd_context *ctx; struct device_node *i80_if_timings; - struct resource *res; int ret; if (!dev->of_node) @@ -1206,15 +1243,11 @@ static int fimd_probe(struct platform_device *pdev) if (IS_ERR(ctx->regs)) return PTR_ERR(ctx->regs); - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, - ctx->i80_if ? "lcd_sys" : "vsync"); - if (!res) { - dev_err(dev, "irq request failed.\n"); - return -ENXIO; - } + ret = platform_get_irq_byname(pdev, ctx->i80_if ? "lcd_sys" : "vsync"); + if (ret < 0) + return ret; - ret = devm_request_irq(dev, res->start, fimd_irq_handler, - 0, "drm_fimd", ctx); + ret = devm_request_irq(dev, ret, fimd_irq_handler, 0, "drm_fimd", ctx); if (ret) { dev_err(dev, "irq request failed.\n"); return ret; diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 166a80262896..964dceb28c1e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -1220,7 +1220,6 @@ static int gsc_probe(struct platform_device *pdev) struct gsc_driverdata *driver_data; struct exynos_drm_ipp_formats *formats; struct gsc_context *ctx; - struct resource *res; int num_formats, ret, i, j; ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); @@ -1275,13 +1274,10 @@ static int gsc_probe(struct platform_device *pdev) return PTR_ERR(ctx->regs); /* resource irq */ - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "failed to request irq resource.\n"); - return -ENOENT; - } + ctx->irq = platform_get_irq(pdev, 0); + if (ctx->irq < 0) + return ctx->irq; - ctx->irq = res->start; ret = devm_request_irq(dev, ctx->irq, gsc_irq_handler, 0, dev_name(dev), ctx); if (ret < 0) { diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 41c54f1f60bc..e5204be86093 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -809,19 +809,17 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx) return -ENXIO; } - res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0); - if (res == NULL) { - dev_err(dev, "get interrupt resource failed.\n"); - return -ENXIO; - } + ret = platform_get_irq(mixer_ctx->pdev, 0); + if (ret < 0) + return ret; + mixer_ctx->irq = ret; - ret = devm_request_irq(dev, res->start, mixer_irq_handler, - 0, "drm_mixer", mixer_ctx); + ret = devm_request_irq(dev, mixer_ctx->irq, mixer_irq_handler, + 0, "drm_mixer", mixer_ctx); if (ret) { dev_err(dev, "request interrupt failed.\n"); return ret; } - mixer_ctx->irq = res->start; return 0; } diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 42b5400f0fef..98c5450b8eac 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -3,6 +3,7 @@ config DRM_I915 tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics" depends on DRM depends on X86 && PCI + depends on !PREEMPT_RT select INTEL_GTT select INTERVAL_TREE # we need shmfs for the swappable backing store, and in particular diff --git a/drivers/gpu/drm/i915/Kconfig.unstable b/drivers/gpu/drm/i915/Kconfig.unstable index 0c2276155c2b..cf151a297ed7 100644 --- a/drivers/gpu/drm/i915/Kconfig.unstable +++ b/drivers/gpu/drm/i915/Kconfig.unstable @@ -19,11 +19,3 @@ config DRM_I915_UNSTABLE Recommended for driver developers _only_. If in the slightest bit of doubt, say "N". - -config DRM_I915_UNSTABLE_FAKE_LMEM - bool "Enable the experimental fake lmem" - depends on DRM_I915_UNSTABLE - default n - help - Convert some system memory into a fake local memory region for - testing. diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c index 0c32210bf503..934a9f9e7dab 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c @@ -1321,7 +1321,7 @@ tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); if (crtc_state->port_clock > 270000) { - if (IS_TGL_U(dev_priv) || IS_TGL_Y(dev_priv)) { + if (IS_TGL_UY(dev_priv)) { return intel_get_buf_trans(&tgl_uy_combo_phy_trans_dp_hbr2, n_entries); } else { diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index fd5bc7acf08d..2cd62a187df3 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -265,7 +265,7 @@ static int intelfb_create(struct drm_fb_helper *helper, struct intel_memory_region *mem = obj->mm.region; info->apertures->ranges[0].base = mem->io_start; - info->apertures->ranges[0].size = mem->total; + info->apertures->ranges[0].size = mem->io_size; /* Use fbdev's framebuffer from lmem for discrete */ info->fix.smem_start = diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index bc6d59df064d..9ae294eb7fb4 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -670,6 +670,16 @@ set_proto_ctx_engines_parallel_submit(struct i915_user_extension __user *base, goto out_err; } + /* + * We don't support breadcrumb handshake on these + * classes + */ + if (siblings[n]->class == RENDER_CLASS || + siblings[n]->class == COMPUTE_CLASS) { + err = -EINVAL; + goto out_err; + } + if (n) { if (prev_engine.engine_class != ci.engine_class) { diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index 2d593d573ef1..372bc220faeb 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -272,12 +272,6 @@ void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj) if (!list_empty(&obj->vma.list)) { struct i915_vma *vma; - /* - * Note that the vma keeps an object reference while - * it is active, so it *should* not sleep while we - * destroy it. Our debug code errs insits it *might*. - * For the moment, play along. - */ spin_lock(&obj->vma.lock); while ((vma = list_first_entry_or_null(&obj->vma.list, struct i915_vma, @@ -285,13 +279,7 @@ void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj) GEM_BUG_ON(vma->obj != obj); spin_unlock(&obj->vma.lock); - /* Verify that the vma is unbound under the vm mutex. */ - mutex_lock(&vma->vm->mutex); - atomic_and(~I915_VMA_PIN_MASK, &vma->flags); - __i915_vma_unbind(vma); - mutex_unlock(&vma->vm->mutex); - - __i915_vma_put(vma); + i915_vma_destroy(vma); spin_lock(&obj->vma.lock); } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index 0098a32490f0..fd54eb8f4826 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -319,16 +319,23 @@ struct drm_i915_gem_object { #define I915_BO_ALLOC_PM_VOLATILE BIT(4) /* Object needs to be restored early using memcpy during resume */ #define I915_BO_ALLOC_PM_EARLY BIT(5) +/* + * Object is likely never accessed by the CPU. This will prioritise the BO to be + * allocated in the non-mappable portion of lmem. This is merely a hint, and if + * dealing with userspace objects the CPU fault handler is free to ignore this. + */ +#define I915_BO_ALLOC_GPU_ONLY BIT(6) #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \ I915_BO_ALLOC_VOLATILE | \ I915_BO_ALLOC_CPU_CLEAR | \ I915_BO_ALLOC_USER | \ I915_BO_ALLOC_PM_VOLATILE | \ - I915_BO_ALLOC_PM_EARLY) -#define I915_BO_READONLY BIT(6) -#define I915_TILING_QUIRK_BIT 7 /* unknown swizzling; do not release! */ -#define I915_BO_PROTECTED BIT(8) -#define I915_BO_WAS_BOUND_BIT 9 + I915_BO_ALLOC_PM_EARLY | \ + I915_BO_ALLOC_GPU_ONLY) +#define I915_BO_READONLY BIT(7) +#define I915_TILING_QUIRK_BIT 8 /* unknown swizzling; do not release! */ +#define I915_BO_PROTECTED BIT(9) +#define I915_BO_WAS_BOUND_BIT 10 /** * @mem_flags - Mutable placement-related flags * diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 183b861620b8..97c820eee115 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -358,6 +358,9 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, !i915_gem_object_has_iomem(obj)) return ERR_PTR(-ENXIO); + if (WARN_ON_ONCE(obj->flags & I915_BO_ALLOC_GPU_ONLY)) + return ERR_PTR(-EINVAL); + assert_object_held(obj); pinned = !(type & I915_MAP_OVERRIDE); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c index a4350227e9ae..6cf94469d5a8 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_region.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c @@ -45,6 +45,11 @@ i915_gem_object_create_region(struct intel_memory_region *mem, GEM_BUG_ON(flags & ~I915_BO_ALLOC_FLAGS); + if (WARN_ON_ONCE(flags & I915_BO_ALLOC_GPU_ONLY && + (flags & I915_BO_ALLOC_CPU_CLEAR || + flags & I915_BO_ALLOC_PM_EARLY))) + return ERR_PTR(-EINVAL); + if (!mem) return ERR_PTR(-ENODEV); @@ -67,6 +72,17 @@ i915_gem_object_create_region(struct intel_memory_region *mem, if (!obj) return ERR_PTR(-ENOMEM); + /* + * Anything smaller than the min_page_size can't be freely inserted into + * the GTT, due to alignemnt restrictions. For such special objects, + * make sure we force memcpy based suspend-resume. In the future we can + * revisit this, either by allowing special mis-aligned objects in the + * migration path, or by mapping all of LMEM upfront using cheap 1G + * GTT entries. + */ + if (default_page_size < mem->min_page_size) + flags |= I915_BO_ALLOC_PM_EARLY; + err = mem->ops->init_object(mem, obj, size, page_size, flags); if (err) goto err_object_free; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index 4efa821f3cb1..3a1c782ed791 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -699,7 +699,7 @@ struct intel_memory_region *i915_gem_shmem_setup(struct drm_i915_private *i915, { return intel_memory_region_create(i915, 0, totalram_pages() << PAGE_SHIFT, - PAGE_SIZE, 0, + PAGE_SIZE, 0, 0, type, instance, &shmem_region_ops); } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index b9c3196b91ca..0bf8f61134af 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -492,18 +492,22 @@ static int i915_gem_init_stolen(struct intel_memory_region *mem) /* Exclude the reserved region from driver use */ mem->region.end = reserved_base - 1; + mem->io_size = resource_size(&mem->region); /* It is possible for the reserved area to end before the end of stolen * memory, so just consider the start. */ reserved_total = stolen_top - reserved_base; + i915->stolen_usable_size = + resource_size(&i915->dsm) - reserved_total; + drm_dbg(&i915->drm, "Memory reserved for graphics device: %lluK, usable: %lluK\n", (u64)resource_size(&i915->dsm) >> 10, - ((u64)resource_size(&i915->dsm) - reserved_total) >> 10); + (u64)i915->stolen_usable_size >> 10); - i915->stolen_usable_size = - resource_size(&i915->dsm) - reserved_total; + if (i915->stolen_usable_size == 0) + return 0; /* Basic memrange allocator for stolen space. */ drm_mm_init(&i915->mm.stolen, 0, i915->stolen_usable_size); @@ -748,7 +752,7 @@ static int init_stolen_lmem(struct intel_memory_region *mem) if (!io_mapping_init_wc(&mem->iomap, mem->io_start, - resource_size(&mem->region))) + mem->io_size)) return -EIO; /* @@ -803,7 +807,8 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type, I915_GTT_PAGE_SIZE_4K; mem = intel_memory_region_create(i915, lmem_base, lmem_size, - min_page_size, io_start, + min_page_size, + io_start, lmem_size, type, instance, &i915_region_stolen_lmem_ops); if (IS_ERR(mem)) @@ -834,7 +839,7 @@ i915_gem_stolen_smem_setup(struct drm_i915_private *i915, u16 type, mem = intel_memory_region_create(i915, intel_graphics_stolen_res.start, resource_size(&intel_graphics_stolen_res), - PAGE_SIZE, 0, type, instance, + PAGE_SIZE, 0, 0, type, instance, &i915_region_stolen_smem_ops); if (IS_ERR(mem)) return mem; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 8419096d4056..45cc5837ce00 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -7,8 +7,10 @@ #include <drm/ttm/ttm_bo_driver.h> #include <drm/ttm/ttm_placement.h> +#include <drm/drm_buddy.h> #include "i915_drv.h" +#include "i915_ttm_buddy_manager.h" #include "intel_memory_region.h" #include "intel_region_ttm.h" @@ -22,6 +24,7 @@ #define I915_TTM_PRIO_PURGE 0 #define I915_TTM_PRIO_NO_PAGES 1 #define I915_TTM_PRIO_HAS_PAGES 2 +#define I915_TTM_PRIO_NEEDS_CPU_ACCESS 3 /* * Size of struct ttm_place vector in on-stack struct ttm_placement allocs @@ -129,7 +132,15 @@ i915_ttm_place_from_region(const struct intel_memory_region *mr, place->mem_type = intel_region_to_ttm_type(mr); if (flags & I915_BO_ALLOC_CONTIGUOUS) - place->flags = TTM_PL_FLAG_CONTIGUOUS; + place->flags |= TTM_PL_FLAG_CONTIGUOUS; + if (mr->io_size && mr->io_size < mr->total) { + if (flags & I915_BO_ALLOC_GPU_ONLY) { + place->flags |= TTM_PL_FLAG_TOPDOWN; + } else { + place->fpfn = 0; + place->lpfn = mr->io_size >> PAGE_SHIFT; + } + } } static void @@ -331,6 +342,7 @@ static bool i915_ttm_eviction_valuable(struct ttm_buffer_object *bo, const struct ttm_place *place) { struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); + struct ttm_resource *res = bo->resource; if (!obj) return false; @@ -344,7 +356,48 @@ static bool i915_ttm_eviction_valuable(struct ttm_buffer_object *bo, return false; /* Will do for now. Our pinned objects are still on TTM's LRU lists */ - return i915_gem_object_evictable(obj); + if (!i915_gem_object_evictable(obj)) + return false; + + switch (res->mem_type) { + case I915_PL_LMEM0: { + struct ttm_resource_manager *man = + ttm_manager_type(bo->bdev, res->mem_type); + struct i915_ttm_buddy_resource *bman_res = + to_ttm_buddy_resource(res); + struct drm_buddy *mm = bman_res->mm; + struct drm_buddy_block *block; + + if (!place->fpfn && !place->lpfn) + return true; + + GEM_BUG_ON(!place->lpfn); + + /* + * If we just want something mappable then we can quickly check + * if the current victim resource is using any of the CPU + * visible portion. + */ + if (!place->fpfn && + place->lpfn == i915_ttm_buddy_man_visible_size(man)) + return bman_res->used_visible_size > 0; + + /* Real range allocation */ + list_for_each_entry(block, &bman_res->blocks, link) { + unsigned long fpfn = + drm_buddy_block_offset(block) >> PAGE_SHIFT; + unsigned long lpfn = fpfn + + (drm_buddy_block_size(mm, block) >> PAGE_SHIFT); + + if (place->fpfn < lpfn && place->lpfn > fpfn) + return true; + } + return false; + } default: + break; + } + + return true; } static void i915_ttm_evict_flags(struct ttm_buffer_object *bo, @@ -585,11 +638,24 @@ static void i915_ttm_swap_notify(struct ttm_buffer_object *bo) i915_ttm_purge(obj); } +static bool i915_ttm_resource_mappable(struct ttm_resource *res) +{ + struct i915_ttm_buddy_resource *bman_res = to_ttm_buddy_resource(res); + + if (!i915_ttm_cpu_maps_iomem(res)) + return true; + + return bman_res->used_visible_size == bman_res->base.num_pages; +} + static int i915_ttm_io_mem_reserve(struct ttm_device *bdev, struct ttm_resource *mem) { if (!i915_ttm_cpu_maps_iomem(mem)) return 0; + if (!i915_ttm_resource_mappable(mem)) + return -EINVAL; + mem->bus.caching = ttm_write_combined; mem->bus.is_iomem = true; @@ -728,14 +794,15 @@ static int i915_ttm_get_pages(struct drm_i915_gem_object *obj) * Gem forced migration using the i915_ttm_migrate() op, is allowed even * to regions that are not in the object's list of allowable placements. */ -static int i915_ttm_migrate(struct drm_i915_gem_object *obj, - struct intel_memory_region *mr) +static int __i915_ttm_migrate(struct drm_i915_gem_object *obj, + struct intel_memory_region *mr, + unsigned int flags) { struct ttm_place requested; struct ttm_placement placement; int ret; - i915_ttm_place_from_region(mr, &requested, obj->flags); + i915_ttm_place_from_region(mr, &requested, flags); placement.num_placement = 1; placement.num_busy_placement = 1; placement.placement = &requested; @@ -758,6 +825,12 @@ static int i915_ttm_migrate(struct drm_i915_gem_object *obj, return 0; } +static int i915_ttm_migrate(struct drm_i915_gem_object *obj, + struct intel_memory_region *mr) +{ + return __i915_ttm_migrate(obj, mr, obj->flags); +} + static void i915_ttm_put_pages(struct drm_i915_gem_object *obj, struct sg_table *st) { @@ -844,7 +917,23 @@ void i915_ttm_adjust_lru(struct drm_i915_gem_object *obj) } else if (!i915_gem_object_has_pages(obj)) { bo->priority = I915_TTM_PRIO_NO_PAGES; } else { - bo->priority = I915_TTM_PRIO_HAS_PAGES; + struct ttm_resource_manager *man = + ttm_manager_type(bo->bdev, bo->resource->mem_type); + + /* + * If we need to place an LMEM resource which doesn't need CPU + * access then we should try not to victimize mappable objects + * first, since we likely end up stealing more of the mappable + * portion. And likewise when we try to find space for a mappble + * object, we know not to ever victimize objects that don't + * occupy any mappable pages. + */ + if (i915_ttm_cpu_maps_iomem(bo->resource) && + i915_ttm_buddy_man_visible_size(man) < man->size && + !(obj->flags & I915_BO_ALLOC_GPU_ONLY)) + bo->priority = I915_TTM_PRIO_NEEDS_CPU_ACCESS; + else + bo->priority = I915_TTM_PRIO_HAS_PAGES; } ttm_bo_move_to_lru_tail(bo, bo->resource, NULL); @@ -900,6 +989,31 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf) return VM_FAULT_SIGBUS; } + if (!i915_ttm_resource_mappable(bo->resource)) { + int err = -ENODEV; + int i; + + for (i = 0; i < obj->mm.n_placements; i++) { + struct intel_memory_region *mr = obj->mm.placements[i]; + unsigned int flags; + + if (!mr->io_size && mr->type != INTEL_MEMORY_SYSTEM) + continue; + + flags = obj->flags; + flags &= ~I915_BO_ALLOC_GPU_ONLY; + err = __i915_ttm_migrate(obj, mr, flags); + if (!err) + break; + } + + if (err) { + drm_dbg(dev, "Unable to make resource CPU accessible\n"); + dma_resv_unlock(bo->base.resv); + return VM_FAULT_SIGBUS; + } + } + if (drm_dev_enter(dev, &idx)) { ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, TTM_BO_VM_NUM_PREFAULT); @@ -1103,7 +1217,7 @@ i915_gem_ttm_system_setup(struct drm_i915_private *i915, mr = intel_memory_region_create(i915, 0, totalram_pages() << PAGE_SHIFT, - PAGE_SIZE, 0, + PAGE_SIZE, 0, 0, type, instance, &ttm_system_region_ops); if (IS_ERR(mr)) diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 8424ee8c5eb8..7a84fa68a99c 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -500,7 +500,7 @@ static int igt_mock_memory_region_huge_pages(void *arg) int bit; int err = 0; - mem = mock_region_create(i915, 0, SZ_2G, I915_GTT_PAGE_SIZE_4K, 0); + mem = mock_region_create(i915, 0, SZ_2G, I915_GTT_PAGE_SIZE_4K, 0, 0); if (IS_ERR(mem)) { pr_err("%s failed to create memory region\n", __func__); return PTR_ERR(mem); @@ -1345,7 +1345,7 @@ try_again: err = i915_gem_object_pin_pages_unlocked(obj); if (err) { - if (err == -ENXIO || err == -E2BIG) { + if (err == -ENXIO || err == -E2BIG || err == -ENOMEM) { i915_gem_object_put(obj); size >>= 1; goto try_again; @@ -1479,6 +1479,65 @@ out: return err; } +static int igt_ppgtt_compact(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct drm_i915_gem_object *obj; + int err; + + /* + * Simple test to catch issues with compact 64K pages -- since the pt is + * compacted to 256B that gives us 32 entries per pt, however since the + * backing page for the pt is 4K, any extra entries we might incorrectly + * write out should be ignored by the HW. If ever hit such a case this + * test should catch it since some of our writes would land in scratch. + */ + + if (!HAS_64K_PAGES(i915)) { + pr_info("device lacks compact 64K page support, skipping\n"); + return 0; + } + + if (!HAS_LMEM(i915)) { + pr_info("device lacks LMEM support, skipping\n"); + return 0; + } + + /* We want the range to cover multiple page-table boundaries. */ + obj = i915_gem_object_create_lmem(i915, SZ_4M, 0); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + err = i915_gem_object_pin_pages_unlocked(obj); + if (err) + goto out_put; + + if (obj->mm.page_sizes.phys < I915_GTT_PAGE_SIZE_64K) { + pr_info("LMEM compact unable to allocate huge-page(s)\n"); + goto out_unpin; + } + + /* + * Disable 2M GTT pages by forcing the page-size to 64K for the GTT + * insertion. + */ + obj->mm.page_sizes.sg = I915_GTT_PAGE_SIZE_64K; + + err = igt_write_huge(i915, obj); + if (err) + pr_err("LMEM compact write-huge failed\n"); + +out_unpin: + i915_gem_object_unpin_pages(obj); +out_put: + i915_gem_object_put(obj); + + if (err == -ENOMEM) + err = 0; + + return err; +} + static int igt_tmpfs_fallback(void *arg) { struct drm_i915_private *i915 = arg; @@ -1736,6 +1795,7 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915) SUBTEST(igt_tmpfs_fallback), SUBTEST(igt_ppgtt_smoke_huge), SUBTEST(igt_ppgtt_sanity_check), + SUBTEST(igt_ppgtt_compact), }; if (!HAS_PPGTT(i915)) { diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c index 8f28e46e8ee5..ddd0772fd828 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c @@ -40,6 +40,7 @@ struct tiled_blits { struct blit_buffer scratch; struct i915_vma *batch; u64 hole; + u64 align; u32 width; u32 height; }; @@ -411,14 +412,19 @@ tiled_blits_create(struct intel_engine_cs *engine, struct rnd_state *prng) goto err_free; } - hole_size = 2 * PAGE_ALIGN(WIDTH * HEIGHT * 4); + t->align = i915_vm_min_alignment(t->ce->vm, INTEL_MEMORY_LOCAL); + t->align = max(t->align, + i915_vm_min_alignment(t->ce->vm, INTEL_MEMORY_SYSTEM)); + + hole_size = 2 * round_up(WIDTH * HEIGHT * 4, t->align); hole_size *= 2; /* room to maneuver */ - hole_size += 2 * I915_GTT_MIN_ALIGNMENT; + hole_size += 2 * t->align; /* padding on either side */ mutex_lock(&t->ce->vm->mutex); memset(&hole, 0, sizeof(hole)); err = drm_mm_insert_node_in_range(&t->ce->vm->mm, &hole, - hole_size, 0, I915_COLOR_UNEVICTABLE, + hole_size, t->align, + I915_COLOR_UNEVICTABLE, 0, U64_MAX, DRM_MM_INSERT_BEST); if (!err) @@ -429,7 +435,7 @@ tiled_blits_create(struct intel_engine_cs *engine, struct rnd_state *prng) goto err_put; } - t->hole = hole.start + I915_GTT_MIN_ALIGNMENT; + t->hole = hole.start + t->align; pr_info("Using hole at %llx\n", t->hole); err = tiled_blits_create_buffers(t, WIDTH, HEIGHT, prng); @@ -456,7 +462,7 @@ static void tiled_blits_destroy(struct tiled_blits *t) static int tiled_blits_prepare(struct tiled_blits *t, struct rnd_state *prng) { - u64 offset = PAGE_ALIGN(t->width * t->height * 4); + u64 offset = round_up(t->width * t->height * 4, t->align); u32 *map; int err; int i; @@ -487,8 +493,7 @@ static int tiled_blits_prepare(struct tiled_blits *t, static int tiled_blits_bounce(struct tiled_blits *t, struct rnd_state *prng) { - u64 offset = - round_up(t->width * t->height * 4, 2 * I915_GTT_MIN_ALIGNMENT); + u64 offset = round_up(t->width * t->height * 4, 2 * t->align); int err; /* We want to check position invariant tiling across GTT eviction */ @@ -501,7 +506,7 @@ static int tiled_blits_bounce(struct tiled_blits *t, struct rnd_state *prng) /* Reposition so that we overlap the old addresses, and slightly off */ err = tiled_blit(t, - &t->buffers[2], t->hole + I915_GTT_MIN_ALIGNMENT, + &t->buffers[2], t->hole + t->align, &t->buffers[1], t->hole + 3 * offset / 2); if (err) return err; diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c index bd60d42238fb..7609db87df05 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c @@ -885,7 +885,9 @@ out_file: return err; } -static int rpcs_query_batch(struct drm_i915_gem_object *rpcs, struct i915_vma *vma) +static int rpcs_query_batch(struct drm_i915_gem_object *rpcs, + struct i915_vma *vma, + struct intel_engine_cs *engine) { u32 *cmd; @@ -896,7 +898,7 @@ static int rpcs_query_batch(struct drm_i915_gem_object *rpcs, struct i915_vma *v return PTR_ERR(cmd); *cmd++ = MI_STORE_REGISTER_MEM_GEN8; - *cmd++ = i915_mmio_reg_offset(GEN8_R_PWR_CLK_STATE(RENDER_RING_BASE)); + *cmd++ = i915_mmio_reg_offset(GEN8_R_PWR_CLK_STATE(engine->mmio_base)); *cmd++ = lower_32_bits(vma->node.start); *cmd++ = upper_32_bits(vma->node.start); *cmd = MI_BATCH_BUFFER_END; @@ -957,7 +959,7 @@ retry: if (err) goto err_vma; - err = rpcs_query_batch(rpcs, vma); + err = rpcs_query_batch(rpcs, vma, ce->engine); if (err) goto err_batch; diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c index 8ae1a1530bd8..a132e241c3ee 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -8,10 +8,13 @@ #include "gem/i915_gem_internal.h" #include "gem/i915_gem_region.h" +#include "gem/i915_gem_ttm.h" #include "gt/intel_engine_pm.h" #include "gt/intel_gpu_commands.h" #include "gt/intel_gt.h" #include "gt/intel_gt_pm.h" +#include "gt/intel_migrate.h" +#include "i915_ttm_buddy_manager.h" #include "huge_gem_object.h" #include "i915_selftest.h" @@ -169,7 +172,7 @@ static int check_partial_mapping(struct drm_i915_gem_object *obj, out: i915_gem_object_lock(obj, NULL); - __i915_vma_put(vma); + i915_vma_destroy(vma); i915_gem_object_unlock(obj); return err; } @@ -266,7 +269,7 @@ static int check_partial_mappings(struct drm_i915_gem_object *obj, return err; i915_gem_object_lock(obj, NULL); - __i915_vma_put(vma); + i915_vma_destroy(vma); i915_gem_object_unlock(obj); if (igt_timeout(end_time, @@ -1001,6 +1004,331 @@ static int igt_mmap(void *arg) return 0; } +static void igt_close_objects(struct drm_i915_private *i915, + struct list_head *objects) +{ + struct drm_i915_gem_object *obj, *on; + + list_for_each_entry_safe(obj, on, objects, st_link) { + i915_gem_object_lock(obj, NULL); + if (i915_gem_object_has_pinned_pages(obj)) + i915_gem_object_unpin_pages(obj); + /* No polluting the memory region between tests */ + __i915_gem_object_put_pages(obj); + i915_gem_object_unlock(obj); + list_del(&obj->st_link); + i915_gem_object_put(obj); + } + + cond_resched(); + + i915_gem_drain_freed_objects(i915); +} + +static void igt_make_evictable(struct list_head *objects) +{ + struct drm_i915_gem_object *obj; + + list_for_each_entry(obj, objects, st_link) { + i915_gem_object_lock(obj, NULL); + if (i915_gem_object_has_pinned_pages(obj)) + i915_gem_object_unpin_pages(obj); + i915_gem_object_unlock(obj); + } + + cond_resched(); +} + +static int igt_fill_mappable(struct intel_memory_region *mr, + struct list_head *objects) +{ + u64 size, total; + int err; + + total = 0; + size = mr->io_size; + do { + struct drm_i915_gem_object *obj; + + obj = i915_gem_object_create_region(mr, size, 0, 0); + if (IS_ERR(obj)) { + err = PTR_ERR(obj); + goto err_close; + } + + list_add(&obj->st_link, objects); + + err = i915_gem_object_pin_pages_unlocked(obj); + if (err) { + if (err != -ENXIO && err != -ENOMEM) + goto err_close; + + if (size == mr->min_page_size) { + err = 0; + break; + } + + size >>= 1; + continue; + } + + total += obj->base.size; + } while (1); + + pr_info("%s filled=%lluMiB\n", __func__, total >> 20); + return 0; + +err_close: + igt_close_objects(mr->i915, objects); + return err; +} + +static int ___igt_mmap_migrate(struct drm_i915_private *i915, + struct drm_i915_gem_object *obj, + unsigned long addr, + bool unfaultable) +{ + struct vm_area_struct *area; + int err = 0, i; + + pr_info("igt_mmap(%s, %d) @ %lx\n", + obj->mm.region->name, I915_MMAP_TYPE_FIXED, addr); + + mmap_read_lock(current->mm); + area = vma_lookup(current->mm, addr); + mmap_read_unlock(current->mm); + if (!area) { + pr_err("%s: Did not create a vm_area_struct for the mmap\n", + obj->mm.region->name); + err = -EINVAL; + goto out_unmap; + } + + for (i = 0; i < obj->base.size / sizeof(u32); i++) { + u32 __user *ux = u64_to_user_ptr((u64)(addr + i * sizeof(*ux))); + u32 x; + + if (get_user(x, ux)) { + err = -EFAULT; + if (!unfaultable) { + pr_err("%s: Unable to read from mmap, offset:%zd\n", + obj->mm.region->name, i * sizeof(x)); + goto out_unmap; + } + + continue; + } + + if (unfaultable) { + pr_err("%s: Faulted unmappable memory\n", + obj->mm.region->name); + err = -EINVAL; + goto out_unmap; + } + + if (x != expand32(POISON_INUSE)) { + pr_err("%s: Read incorrect value from mmap, offset:%zd, found:%x, expected:%x\n", + obj->mm.region->name, + i * sizeof(x), x, expand32(POISON_INUSE)); + err = -EINVAL; + goto out_unmap; + } + + x = expand32(POISON_FREE); + if (put_user(x, ux)) { + pr_err("%s: Unable to write to mmap, offset:%zd\n", + obj->mm.region->name, i * sizeof(x)); + err = -EFAULT; + goto out_unmap; + } + } + + if (unfaultable) { + if (err == -EFAULT) + err = 0; + } else { + obj->flags &= ~I915_BO_ALLOC_GPU_ONLY; + err = wc_check(obj); + } +out_unmap: + vm_munmap(addr, obj->base.size); + return err; +} + +#define IGT_MMAP_MIGRATE_TOPDOWN (1 << 0) +#define IGT_MMAP_MIGRATE_FILL (1 << 1) +#define IGT_MMAP_MIGRATE_EVICTABLE (1 << 2) +#define IGT_MMAP_MIGRATE_UNFAULTABLE (1 << 3) +static int __igt_mmap_migrate(struct intel_memory_region **placements, + int n_placements, + struct intel_memory_region *expected_mr, + unsigned int flags) +{ + struct drm_i915_private *i915 = placements[0]->i915; + struct drm_i915_gem_object *obj; + struct i915_request *rq = NULL; + unsigned long addr; + LIST_HEAD(objects); + u64 offset; + int err; + + obj = __i915_gem_object_create_user(i915, PAGE_SIZE, + placements, + n_placements); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + if (flags & IGT_MMAP_MIGRATE_TOPDOWN) + obj->flags |= I915_BO_ALLOC_GPU_ONLY; + + err = __assign_mmap_offset(obj, I915_MMAP_TYPE_FIXED, &offset, NULL); + if (err) + goto out_put; + + /* + * This will eventually create a GEM context, due to opening dummy drm + * file, which needs a tiny amount of mappable device memory for the top + * level paging structures(and perhaps scratch), so make sure we + * allocate early, to avoid tears. + */ + addr = igt_mmap_offset(i915, offset, obj->base.size, + PROT_WRITE, MAP_SHARED); + if (IS_ERR_VALUE(addr)) { + err = addr; + goto out_put; + } + + if (flags & IGT_MMAP_MIGRATE_FILL) { + err = igt_fill_mappable(placements[0], &objects); + if (err) + goto out_put; + } + + err = i915_gem_object_lock(obj, NULL); + if (err) + goto out_put; + + err = i915_gem_object_pin_pages(obj); + if (err) { + i915_gem_object_unlock(obj); + goto out_put; + } + + err = intel_context_migrate_clear(to_gt(i915)->migrate.context, NULL, + obj->mm.pages->sgl, obj->cache_level, + i915_gem_object_is_lmem(obj), + expand32(POISON_INUSE), &rq); + i915_gem_object_unpin_pages(obj); + if (rq) { + dma_resv_add_excl_fence(obj->base.resv, &rq->fence); + i915_gem_object_set_moving_fence(obj, &rq->fence); + i915_request_put(rq); + } + i915_gem_object_unlock(obj); + if (err) + goto out_put; + + if (flags & IGT_MMAP_MIGRATE_EVICTABLE) + igt_make_evictable(&objects); + + err = ___igt_mmap_migrate(i915, obj, addr, + flags & IGT_MMAP_MIGRATE_UNFAULTABLE); + if (!err && obj->mm.region != expected_mr) { + pr_err("%s region mismatch %s\n", __func__, expected_mr->name); + err = -EINVAL; + } + +out_put: + i915_gem_object_put(obj); + igt_close_objects(i915, &objects); + return err; +} + +static int igt_mmap_migrate(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct intel_memory_region *system = i915->mm.regions[INTEL_REGION_SMEM]; + struct intel_memory_region *mr; + enum intel_region_id id; + + for_each_memory_region(mr, i915, id) { + struct intel_memory_region *mixed[] = { mr, system }; + struct intel_memory_region *single[] = { mr }; + struct ttm_resource_manager *man = mr->region_private; + resource_size_t saved_io_size; + int err; + + if (mr->private) + continue; + + if (!mr->io_size) + continue; + + /* + * For testing purposes let's force small BAR, if not already + * present. + */ + saved_io_size = mr->io_size; + if (mr->io_size == mr->total) { + resource_size_t io_size = mr->io_size; + + io_size = rounddown_pow_of_two(io_size >> 1); + if (io_size < PAGE_SIZE) + continue; + + mr->io_size = io_size; + i915_ttm_buddy_man_force_visible_size(man, + io_size >> PAGE_SHIFT); + } + + /* + * Allocate in the mappable portion, should be no suprises here. + */ + err = __igt_mmap_migrate(mixed, ARRAY_SIZE(mixed), mr, 0); + if (err) + goto out_io_size; + + /* + * Allocate in the non-mappable portion, but force migrating to + * the mappable portion on fault (LMEM -> LMEM) + */ + err = __igt_mmap_migrate(single, ARRAY_SIZE(single), mr, + IGT_MMAP_MIGRATE_TOPDOWN | + IGT_MMAP_MIGRATE_FILL | + IGT_MMAP_MIGRATE_EVICTABLE); + if (err) + goto out_io_size; + + /* + * Allocate in the non-mappable portion, but force spilling into + * system memory on fault (LMEM -> SMEM) + */ + err = __igt_mmap_migrate(mixed, ARRAY_SIZE(mixed), system, + IGT_MMAP_MIGRATE_TOPDOWN | + IGT_MMAP_MIGRATE_FILL); + if (err) + goto out_io_size; + + /* + * Allocate in the non-mappable portion, but since the mappable + * portion is already full, and we can't spill to system memory, + * then we should expect the fault to fail. + */ + err = __igt_mmap_migrate(single, ARRAY_SIZE(single), mr, + IGT_MMAP_MIGRATE_TOPDOWN | + IGT_MMAP_MIGRATE_FILL | + IGT_MMAP_MIGRATE_UNFAULTABLE); +out_io_size: + mr->io_size = saved_io_size; + i915_ttm_buddy_man_force_visible_size(man, + mr->io_size >> PAGE_SHIFT); + if (err) + return err; + } + + return 0; +} + static const char *repr_mmap_type(enum i915_mmap_type type) { switch (type) { @@ -1426,6 +1754,7 @@ int i915_gem_mman_live_selftests(struct drm_i915_private *i915) SUBTEST(igt_smoke_tiling), SUBTEST(igt_mmap_offset_exhaustion), SUBTEST(igt_mmap), + SUBTEST(igt_mmap_migrate), SUBTEST(igt_mmap_access), SUBTEST(igt_mmap_revoke), SUBTEST(igt_mmap_gpu), diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c index 1f8cf4f790b2..b1b9c3fd7bf9 100644 --- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c @@ -201,6 +201,8 @@ static u32 *gen12_emit_aux_table_inv(const i915_reg_t inv_reg, u32 *cs) int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) { + struct intel_engine_cs *engine = rq->engine; + if (mode & EMIT_FLUSH) { u32 flags = 0; u32 *cs; @@ -219,6 +221,9 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) flags |= PIPE_CONTROL_CS_STALL; + if (engine->class == COMPUTE_CLASS) + flags &= ~PIPE_CONTROL_3D_FLAGS; + cs = intel_ring_begin(rq, 6); if (IS_ERR(cs)) return PTR_ERR(cs); @@ -246,6 +251,9 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) flags |= PIPE_CONTROL_CS_STALL; + if (engine->class == COMPUTE_CLASS) + flags &= ~PIPE_CONTROL_3D_FLAGS; + cs = intel_ring_begin(rq, 8 + 4); if (IS_ERR(cs)) return PTR_ERR(cs); @@ -618,19 +626,27 @@ u32 *gen12_emit_fini_breadcrumb_xcs(struct i915_request *rq, u32 *cs) u32 *gen12_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs) { + struct drm_i915_private *i915 = rq->engine->i915; + u32 flags = (PIPE_CONTROL_CS_STALL | + PIPE_CONTROL_TILE_CACHE_FLUSH | + PIPE_CONTROL_FLUSH_L3 | + PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH | + PIPE_CONTROL_DEPTH_CACHE_FLUSH | + PIPE_CONTROL_DC_FLUSH_ENABLE | + PIPE_CONTROL_FLUSH_ENABLE); + + if (GRAPHICS_VER(i915) == 12 && GRAPHICS_VER_FULL(i915) < IP_VER(12, 50)) + /* Wa_1409600907 */ + flags |= PIPE_CONTROL_DEPTH_STALL; + + if (rq->engine->class == COMPUTE_CLASS) + flags &= ~PIPE_CONTROL_3D_FLAGS; + cs = gen12_emit_ggtt_write_rcs(cs, rq->fence.seqno, hwsp_offset(rq), PIPE_CONTROL0_HDC_PIPELINE_FLUSH, - PIPE_CONTROL_CS_STALL | - PIPE_CONTROL_TILE_CACHE_FLUSH | - PIPE_CONTROL_FLUSH_L3 | - PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH | - PIPE_CONTROL_DEPTH_CACHE_FLUSH | - /* Wa_1409600907:tgl */ - PIPE_CONTROL_DEPTH_STALL | - PIPE_CONTROL_DC_FLUSH_ENABLE | - PIPE_CONTROL_FLUSH_ENABLE); + flags); return gen12_emit_fini_breadcrumb_tail(rq, cs); } diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c index c43e724afa9f..f574da00eff1 100644 --- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c +++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c @@ -233,6 +233,8 @@ static u64 __gen8_ppgtt_clear(struct i915_address_space * const vm, start, end, lvl); } else { unsigned int count; + unsigned int pte = gen8_pd_index(start, 0); + unsigned int num_ptes; u64 *vaddr; count = gen8_pt_count(start, end); @@ -242,10 +244,18 @@ static u64 __gen8_ppgtt_clear(struct i915_address_space * const vm, atomic_read(&pt->used)); GEM_BUG_ON(!count || count >= atomic_read(&pt->used)); + num_ptes = count; + if (pt->is_compact) { + GEM_BUG_ON(num_ptes % 16); + GEM_BUG_ON(pte % 16); + num_ptes /= 16; + pte /= 16; + } + vaddr = px_vaddr(pt); - memset64(vaddr + gen8_pd_index(start, 0), + memset64(vaddr + pte, vm->scratch[0]->encode, - count); + num_ptes); atomic_sub(count, &pt->used); start += count; @@ -453,6 +463,95 @@ gen8_ppgtt_insert_pte(struct i915_ppgtt *ppgtt, return idx; } +static void +xehpsdv_ppgtt_insert_huge(struct i915_address_space *vm, + struct i915_vma_resource *vma_res, + struct sgt_dma *iter, + enum i915_cache_level cache_level, + u32 flags) +{ + const gen8_pte_t pte_encode = vm->pte_encode(0, cache_level, flags); + unsigned int rem = sg_dma_len(iter->sg); + u64 start = vma_res->start; + + GEM_BUG_ON(!i915_vm_is_4lvl(vm)); + + do { + struct i915_page_directory * const pdp = + gen8_pdp_for_page_address(vm, start); + struct i915_page_directory * const pd = + i915_pd_entry(pdp, __gen8_pte_index(start, 2)); + struct i915_page_table *pt = + i915_pt_entry(pd, __gen8_pte_index(start, 1)); + gen8_pte_t encode = pte_encode; + unsigned int page_size; + gen8_pte_t *vaddr; + u16 index, max; + + max = I915_PDES; + + if (vma_res->bi.page_sizes.sg & I915_GTT_PAGE_SIZE_2M && + IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_2M) && + rem >= I915_GTT_PAGE_SIZE_2M && + !__gen8_pte_index(start, 0)) { + index = __gen8_pte_index(start, 1); + encode |= GEN8_PDE_PS_2M; + page_size = I915_GTT_PAGE_SIZE_2M; + + vaddr = px_vaddr(pd); + } else { + if (encode & GEN12_PPGTT_PTE_LM) { + GEM_BUG_ON(__gen8_pte_index(start, 0) % 16); + GEM_BUG_ON(rem < I915_GTT_PAGE_SIZE_64K); + GEM_BUG_ON(!IS_ALIGNED(iter->dma, + I915_GTT_PAGE_SIZE_64K)); + + index = __gen8_pte_index(start, 0) / 16; + page_size = I915_GTT_PAGE_SIZE_64K; + + max /= 16; + + vaddr = px_vaddr(pd); + vaddr[__gen8_pte_index(start, 1)] |= GEN12_PDE_64K; + + pt->is_compact = true; + } else { + GEM_BUG_ON(pt->is_compact); + index = __gen8_pte_index(start, 0); + page_size = I915_GTT_PAGE_SIZE; + } + + vaddr = px_vaddr(pt); + } + + do { + GEM_BUG_ON(rem < page_size); + vaddr[index++] = encode | iter->dma; + + start += page_size; + iter->dma += page_size; + rem -= page_size; + if (iter->dma >= iter->max) { + iter->sg = __sg_next(iter->sg); + if (!iter->sg) + break; + + rem = sg_dma_len(iter->sg); + if (!rem) + break; + + iter->dma = sg_dma_address(iter->sg); + iter->max = iter->dma + rem; + + if (unlikely(!IS_ALIGNED(iter->dma, page_size))) + break; + } + } while (rem >= page_size && index < max); + + vma_res->page_sizes_gtt |= page_size; + } while (iter->sg && sg_dma_len(iter->sg)); +} + static void gen8_ppgtt_insert_huge(struct i915_address_space *vm, struct i915_vma_resource *vma_res, struct sgt_dma *iter, @@ -586,7 +685,10 @@ static void gen8_ppgtt_insert(struct i915_address_space *vm, struct sgt_dma iter = sgt_dma(vma_res); if (vma_res->bi.page_sizes.sg > I915_GTT_PAGE_SIZE) { - gen8_ppgtt_insert_huge(vm, vma_res, &iter, cache_level, flags); + if (HAS_64K_PAGES(vm->i915)) + xehpsdv_ppgtt_insert_huge(vm, vma_res, &iter, cache_level, flags); + else + gen8_ppgtt_insert_huge(vm, vma_res, &iter, cache_level, flags); } else { u64 idx = vma_res->start >> GEN8_PTE_SHIFT; @@ -613,13 +715,56 @@ static void gen8_ppgtt_insert_entry(struct i915_address_space *vm, gen8_pdp_for_page_index(vm, idx); struct i915_page_directory *pd = i915_pd_entry(pdp, gen8_pd_index(idx, 2)); + struct i915_page_table *pt = i915_pt_entry(pd, gen8_pd_index(idx, 1)); gen8_pte_t *vaddr; - vaddr = px_vaddr(i915_pt_entry(pd, gen8_pd_index(idx, 1))); + GEM_BUG_ON(pt->is_compact); + + vaddr = px_vaddr(pt); vaddr[gen8_pd_index(idx, 0)] = gen8_pte_encode(addr, level, flags); clflush_cache_range(&vaddr[gen8_pd_index(idx, 0)], sizeof(*vaddr)); } +static void __xehpsdv_ppgtt_insert_entry_lm(struct i915_address_space *vm, + dma_addr_t addr, + u64 offset, + enum i915_cache_level level, + u32 flags) +{ + u64 idx = offset >> GEN8_PTE_SHIFT; + struct i915_page_directory * const pdp = + gen8_pdp_for_page_index(vm, idx); + struct i915_page_directory *pd = + i915_pd_entry(pdp, gen8_pd_index(idx, 2)); + struct i915_page_table *pt = i915_pt_entry(pd, gen8_pd_index(idx, 1)); + gen8_pte_t *vaddr; + + GEM_BUG_ON(!IS_ALIGNED(addr, SZ_64K)); + GEM_BUG_ON(!IS_ALIGNED(offset, SZ_64K)); + + if (!pt->is_compact) { + vaddr = px_vaddr(pd); + vaddr[gen8_pd_index(idx, 1)] |= GEN12_PDE_64K; + pt->is_compact = true; + } + + vaddr = px_vaddr(pt); + vaddr[gen8_pd_index(idx, 0) / 16] = gen8_pte_encode(addr, level, flags); +} + +static void xehpsdv_ppgtt_insert_entry(struct i915_address_space *vm, + dma_addr_t addr, + u64 offset, + enum i915_cache_level level, + u32 flags) +{ + if (flags & PTE_LM) + return __xehpsdv_ppgtt_insert_entry_lm(vm, addr, offset, + level, flags); + + return gen8_ppgtt_insert_entry(vm, addr, offset, level, flags); +} + static int gen8_init_scratch(struct i915_address_space *vm) { u32 pte_flags; @@ -819,7 +964,10 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt, ppgtt->vm.bind_async_flags = I915_VMA_LOCAL_BIND; ppgtt->vm.insert_entries = gen8_ppgtt_insert; - ppgtt->vm.insert_page = gen8_ppgtt_insert_entry; + if (HAS_64K_PAGES(gt->i915)) + ppgtt->vm.insert_page = xehpsdv_ppgtt_insert_entry; + else + ppgtt->vm.insert_page = gen8_ppgtt_insert_entry; ppgtt->vm.allocate_va_range = gen8_ppgtt_alloc; ppgtt->vm.clear_range = gen8_ppgtt_clear; ppgtt->vm.foreach = gen8_ppgtt_foreach; diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h index be4b1e65442f..1c0ab05c3c40 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine.h +++ b/drivers/gpu/drm/i915/gt/intel_engine.h @@ -265,6 +265,8 @@ intel_engine_create_pinned_context(struct intel_engine_cs *engine, void intel_engine_destroy_pinned_context(struct intel_context *ce); +void xehp_enable_ccs_engines(struct intel_engine_cs *engine); + #define ENGINE_PHYSICAL 0 #define ENGINE_MOCK 1 #define ENGINE_VIRTUAL 2 diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index e53008b4dd05..e1aa78b20d2d 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -21,6 +21,7 @@ #include "intel_gt.h" #include "intel_gt_requests.h" #include "intel_gt_pm.h" +#include "intel_lrc.h" #include "intel_lrc_reg.h" #include "intel_reset.h" #include "intel_ring.h" @@ -156,6 +157,34 @@ static const struct engine_info intel_engines[] = { { .graphics_ver = 12, .base = XEHP_VEBOX4_RING_BASE } }, }, + [CCS0] = { + .class = COMPUTE_CLASS, + .instance = 0, + .mmio_bases = { + { .graphics_ver = 12, .base = GEN12_COMPUTE0_RING_BASE } + } + }, + [CCS1] = { + .class = COMPUTE_CLASS, + .instance = 1, + .mmio_bases = { + { .graphics_ver = 12, .base = GEN12_COMPUTE1_RING_BASE } + } + }, + [CCS2] = { + .class = COMPUTE_CLASS, + .instance = 2, + .mmio_bases = { + { .graphics_ver = 12, .base = GEN12_COMPUTE2_RING_BASE } + } + }, + [CCS3] = { + .class = COMPUTE_CLASS, + .instance = 3, + .mmio_bases = { + { .graphics_ver = 12, .base = GEN12_COMPUTE3_RING_BASE } + } + }, }; /** @@ -180,6 +209,8 @@ u32 intel_engine_context_size(struct intel_gt *gt, u8 class) BUILD_BUG_ON(I915_GTT_PAGE_SIZE != PAGE_SIZE); switch (class) { + case COMPUTE_CLASS: + fallthrough; case RENDER_CLASS: switch (GRAPHICS_VER(gt->i915)) { default: @@ -293,6 +324,50 @@ static void nop_irq_handler(struct intel_engine_cs *engine, u16 iir) GEM_DEBUG_WARN_ON(iir); } +static u32 get_reset_domain(u8 ver, enum intel_engine_id id) +{ + u32 reset_domain; + + if (ver >= 11) { + static const u32 engine_reset_domains[] = { + [RCS0] = GEN11_GRDOM_RENDER, + [BCS0] = GEN11_GRDOM_BLT, + [VCS0] = GEN11_GRDOM_MEDIA, + [VCS1] = GEN11_GRDOM_MEDIA2, + [VCS2] = GEN11_GRDOM_MEDIA3, + [VCS3] = GEN11_GRDOM_MEDIA4, + [VCS4] = GEN11_GRDOM_MEDIA5, + [VCS5] = GEN11_GRDOM_MEDIA6, + [VCS6] = GEN11_GRDOM_MEDIA7, + [VCS7] = GEN11_GRDOM_MEDIA8, + [VECS0] = GEN11_GRDOM_VECS, + [VECS1] = GEN11_GRDOM_VECS2, + [VECS2] = GEN11_GRDOM_VECS3, + [VECS3] = GEN11_GRDOM_VECS4, + [CCS0] = GEN11_GRDOM_RENDER, + [CCS1] = GEN11_GRDOM_RENDER, + [CCS2] = GEN11_GRDOM_RENDER, + [CCS3] = GEN11_GRDOM_RENDER, + }; + GEM_BUG_ON(id >= ARRAY_SIZE(engine_reset_domains) || + !engine_reset_domains[id]); + reset_domain = engine_reset_domains[id]; + } else { + static const u32 engine_reset_domains[] = { + [RCS0] = GEN6_GRDOM_RENDER, + [BCS0] = GEN6_GRDOM_BLT, + [VCS0] = GEN6_GRDOM_MEDIA, + [VCS1] = GEN8_GRDOM_MEDIA2, + [VECS0] = GEN6_GRDOM_VECS, + }; + GEM_BUG_ON(id >= ARRAY_SIZE(engine_reset_domains) || + !engine_reset_domains[id]); + reset_domain = engine_reset_domains[id]; + } + + return reset_domain; +} + static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, u8 logical_instance) { @@ -328,38 +403,8 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, engine->id = id; engine->legacy_idx = INVALID_ENGINE; engine->mask = BIT(id); - if (GRAPHICS_VER(gt->i915) >= 11) { - static const u32 engine_reset_domains[] = { - [RCS0] = GEN11_GRDOM_RENDER, - [BCS0] = GEN11_GRDOM_BLT, - [VCS0] = GEN11_GRDOM_MEDIA, - [VCS1] = GEN11_GRDOM_MEDIA2, - [VCS2] = GEN11_GRDOM_MEDIA3, - [VCS3] = GEN11_GRDOM_MEDIA4, - [VCS4] = GEN11_GRDOM_MEDIA5, - [VCS5] = GEN11_GRDOM_MEDIA6, - [VCS6] = GEN11_GRDOM_MEDIA7, - [VCS7] = GEN11_GRDOM_MEDIA8, - [VECS0] = GEN11_GRDOM_VECS, - [VECS1] = GEN11_GRDOM_VECS2, - [VECS2] = GEN11_GRDOM_VECS3, - [VECS3] = GEN11_GRDOM_VECS4, - }; - GEM_BUG_ON(id >= ARRAY_SIZE(engine_reset_domains) || - !engine_reset_domains[id]); - engine->reset_domain = engine_reset_domains[id]; - } else { - static const u32 engine_reset_domains[] = { - [RCS0] = GEN6_GRDOM_RENDER, - [BCS0] = GEN6_GRDOM_BLT, - [VCS0] = GEN6_GRDOM_MEDIA, - [VCS1] = GEN8_GRDOM_MEDIA2, - [VECS0] = GEN6_GRDOM_VECS, - }; - GEM_BUG_ON(id >= ARRAY_SIZE(engine_reset_domains) || - !engine_reset_domains[id]); - engine->reset_domain = engine_reset_domains[id]; - } + engine->reset_domain = get_reset_domain(GRAPHICS_VER(gt->i915), + id); engine->i915 = i915; engine->gt = gt; engine->uncore = gt->uncore; @@ -389,6 +434,12 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, if (GRAPHICS_VER(i915) == 12 && engine->class == RENDER_CLASS) engine->props.preempt_timeout_ms = 0; + /* features common between engines sharing EUs */ + if (engine->class == RENDER_CLASS || engine->class == COMPUTE_CLASS) { + engine->flags |= I915_ENGINE_HAS_RCS_REG_STATE; + engine->flags |= I915_ENGINE_HAS_EU_PRIORITY; + } + engine->defaults = engine->props; /* never to change again */ engine->context_size = intel_engine_context_size(gt, engine->class); @@ -541,6 +592,29 @@ bool gen11_vdbox_has_sfc(struct intel_gt *gt, return false; } +static void engine_mask_apply_compute_fuses(struct intel_gt *gt) +{ + struct drm_i915_private *i915 = gt->i915; + struct intel_gt_info *info = >->info; + int ss_per_ccs = info->sseu.max_subslices / I915_MAX_CCS; + unsigned long ccs_mask; + unsigned int i; + + if (GRAPHICS_VER_FULL(i915) < IP_VER(12, 50)) + return; + + ccs_mask = intel_slicemask_from_dssmask(intel_sseu_get_compute_subslices(&info->sseu), + ss_per_ccs); + /* + * If all DSS in a quadrant are fused off, the corresponding CCS + * engine is not available for use. + */ + for_each_clear_bit(i, &ccs_mask, I915_MAX_CCS) { + info->engine_mask &= ~BIT(_CCS(i)); + drm_dbg(&i915->drm, "ccs%u fused off\n", i); + } +} + /* * Determine which engines are fused off in our particular hardware. * Note that we have a catch-22 situation where we need to be able to access @@ -622,6 +696,8 @@ static intel_engine_mask_t init_engine_mask(struct intel_gt *gt) vebox_mask, VEBOX_MASK(gt)); GEM_BUG_ON(vebox_mask != VEBOX_MASK(gt)); + engine_mask_apply_compute_fuses(gt); + return info->engine_mask; } @@ -2019,6 +2095,23 @@ intel_engine_execlist_find_hung_request(struct intel_engine_cs *engine) return active; } +void xehp_enable_ccs_engines(struct intel_engine_cs *engine) +{ + /* + * If there are any non-fused-off CCS engines, we need to enable CCS + * support in the RCU_MODE register. This only needs to be done once, + * so for simplicity we'll take care of this in the RCS engine's + * resume handler; since the RCS and all CCS engines belong to the + * same reset domain and are reset together, this will also take care + * of re-applying the setting after i915-triggered resets. + */ + if (!CCS_MASK(engine->gt)) + return; + + intel_uncore_write(engine->uncore, GEN12_RCU_MODE, + _MASKED_BIT_ENABLE(GEN12_RCU_MODE_CCS_ENABLE)); +} + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "mock_engine.c" #include "selftest_engine.c" diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h index 36365bdbe1ee..19ff8758e34d 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h @@ -33,7 +33,8 @@ #define VIDEO_ENHANCEMENT_CLASS 2 #define COPY_ENGINE_CLASS 3 #define OTHER_CLASS 4 -#define MAX_ENGINE_CLASS 4 +#define COMPUTE_CLASS 5 +#define MAX_ENGINE_CLASS 5 #define MAX_ENGINE_INSTANCE 7 #define I915_MAX_SLICES 3 @@ -95,6 +96,7 @@ struct i915_ctx_workarounds { #define I915_MAX_VCS 8 #define I915_MAX_VECS 4 +#define I915_MAX_CCS 4 /* * Engine IDs definitions. @@ -117,6 +119,11 @@ enum intel_engine_id { VECS2, VECS3, #define _VECS(n) (VECS0 + (n)) + CCS0, + CCS1, + CCS2, + CCS3, +#define _CCS(n) (CCS0 + (n)) I915_NUM_ENGINES #define INVALID_ENGINE ((enum intel_engine_id)-1) }; @@ -517,6 +524,8 @@ struct intel_engine_cs { #define I915_ENGINE_HAS_RELATIVE_MMIO BIT(6) #define I915_ENGINE_REQUIRES_CMD_PARSER BIT(7) #define I915_ENGINE_WANT_FORCED_PREEMPTION BIT(8) +#define I915_ENGINE_HAS_RCS_REG_STATE BIT(9) +#define I915_ENGINE_HAS_EU_PRIORITY BIT(10) unsigned int flags; /* diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c b/drivers/gpu/drm/i915/gt/intel_engine_user.c index 9ce85a845105..b8c9b6b89003 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_user.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c @@ -47,6 +47,7 @@ static const u8 uabi_classes[] = { [COPY_ENGINE_CLASS] = I915_ENGINE_CLASS_COPY, [VIDEO_DECODE_CLASS] = I915_ENGINE_CLASS_VIDEO, [VIDEO_ENHANCEMENT_CLASS] = I915_ENGINE_CLASS_VIDEO_ENHANCE, + /* TODO: Add COMPUTE_CLASS mapping once ABI is available */ }; static int engine_cmp(void *priv, const struct list_head *A, @@ -139,6 +140,7 @@ const char *intel_engine_class_repr(u8 class) [COPY_ENGINE_CLASS] = "bcs", [VIDEO_DECODE_CLASS] = "vcs", [VIDEO_ENHANCEMENT_CLASS] = "vecs", + [COMPUTE_CLASS] = "ccs", }; if (class >= ARRAY_SIZE(uabi_names) || !uabi_names[class]) @@ -162,6 +164,7 @@ static int legacy_ring_idx(const struct legacy_ring *ring) [COPY_ENGINE_CLASS] = { BCS0, 1 }, [VIDEO_DECODE_CLASS] = { VCS0, I915_MAX_VCS }, [VIDEO_ENHANCEMENT_CLASS] = { VECS0, I915_MAX_VECS }, + [COMPUTE_CLASS] = { CCS0, I915_MAX_CCS }, }; if (GEM_DEBUG_WARN_ON(ring->class >= ARRAY_SIZE(map))) @@ -190,7 +193,7 @@ static void add_legacy_ring(struct legacy_ring *ring, void intel_engines_driver_register(struct drm_i915_private *i915) { struct legacy_ring ring = {}; - u8 uabi_instances[4] = {}; + u8 uabi_instances[5] = {}; struct list_head *it, *next; struct rb_node **p, *prev; LIST_HEAD(engines); diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c index 961d795220a3..3e0c81f06bd0 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -665,9 +665,13 @@ static inline void execlists_schedule_out(struct i915_request *rq) static u64 execlists_update_context(struct i915_request *rq) { struct intel_context *ce = rq->context; - u64 desc = ce->lrc.desc; + u64 desc; u32 tail, prev; + desc = ce->lrc.desc; + if (rq->engine->flags & I915_ENGINE_HAS_EU_PRIORITY) + desc |= lrc_desc_priority(rq_prio(rq)); + /* * WaIdleLiteRestore:bdw,skl * @@ -2907,6 +2911,9 @@ static int execlists_resume(struct intel_engine_cs *engine) enable_execlists(engine); + if (engine->class == RENDER_CLASS) + xehp_enable_ccs_engines(engine); + return 0; } @@ -3480,7 +3487,7 @@ int intel_execlists_submission_setup(struct intel_engine_cs *engine) logical_ring_default_vfuncs(engine); logical_ring_default_irqs(engine); - if (engine->class == RENDER_CLASS) + if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) rcs_submission_override(engine); lrc_init_wa_ctx(engine); diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h index f8253012d166..d112ffd56418 100644 --- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h +++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h @@ -228,11 +228,14 @@ #define PIPE_CONTROL_COMMAND_CACHE_INVALIDATE (1<<29) /* gen11+ */ #define PIPE_CONTROL_TILE_CACHE_FLUSH (1<<28) /* gen11+ */ #define PIPE_CONTROL_FLUSH_L3 (1<<27) +#define PIPE_CONTROL_AMFS_FLUSH (1<<25) /* gen12+ */ #define PIPE_CONTROL_GLOBAL_GTT_IVB (1<<24) /* gen7+ */ #define PIPE_CONTROL_MMIO_WRITE (1<<23) #define PIPE_CONTROL_STORE_DATA_INDEX (1<<21) #define PIPE_CONTROL_CS_STALL (1<<20) +#define PIPE_CONTROL_GLOBAL_SNAPSHOT_RESET (1<<19) #define PIPE_CONTROL_TLB_INVALIDATE (1<<18) +#define PIPE_CONTROL_PSD_SYNC (1<<17) /* gen11+ */ #define PIPE_CONTROL_MEDIA_STATE_CLEAR (1<<16) #define PIPE_CONTROL_WRITE_TIMESTAMP (3<<14) #define PIPE_CONTROL_QW_WRITE (1<<14) @@ -254,6 +257,18 @@ #define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0) #define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ +/* 3D-related flags can't be set on compute engine */ +#define PIPE_CONTROL_3D_FLAGS (\ + PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH | \ + PIPE_CONTROL_DEPTH_CACHE_FLUSH | \ + PIPE_CONTROL_TILE_CACHE_FLUSH | \ + PIPE_CONTROL_DEPTH_STALL | \ + PIPE_CONTROL_STALL_AT_SCOREBOARD | \ + PIPE_CONTROL_PSD_SYNC | \ + PIPE_CONTROL_AMFS_FLUSH | \ + PIPE_CONTROL_VF_CACHE_INVALIDATE | \ + PIPE_CONTROL_GLOBAL_SNAPSHOT_RESET) + #define MI_MATH(x) MI_INSTR(0x1a, (x) - 1) #define MI_MATH_INSTR(opcode, op1, op2) ((opcode) << 20 | (op1) << 10 | (op2)) /* Opcodes for MI_MATH_INSTR */ diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index e8403fa53909..8a2483ccbfb9 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -65,8 +65,6 @@ int intel_gt_probe_lmem(struct intel_gt *gt) int err; mem = intel_gt_setup_lmem(gt); - if (mem == ERR_PTR(-ENODEV)) - mem = intel_gt_setup_fake_lmem(gt); if (IS_ERR(mem)) { err = PTR_ERR(mem); if (err == -ENODEV) @@ -458,7 +456,9 @@ static int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size) struct i915_vma *vma; int ret; - obj = i915_gem_object_create_lmem(i915, size, I915_BO_ALLOC_VOLATILE); + obj = i915_gem_object_create_lmem(i915, size, + I915_BO_ALLOC_VOLATILE | + I915_BO_ALLOC_GPU_ONLY); if (IS_ERR(obj)) obj = i915_gem_object_create_stolen(i915, size); if (IS_ERR(obj)) @@ -913,6 +913,25 @@ u32 intel_gt_read_register_fw(struct intel_gt *gt, i915_reg_t reg) return intel_uncore_read_fw(gt->uncore, reg); } +u32 intel_gt_read_register(struct intel_gt *gt, i915_reg_t reg) +{ + int type; + u8 sliceid, subsliceid; + + for (type = 0; type < NUM_STEERING_TYPES; type++) { + if (intel_gt_reg_needs_read_steering(gt, reg, type)) { + intel_gt_get_valid_steering(gt, type, &sliceid, + &subsliceid); + return intel_uncore_read_with_mcr_steering(gt->uncore, + reg, + sliceid, + subsliceid); + } + } + + return intel_uncore_read(gt->uncore, reg); +} + void intel_gt_info_print(const struct intel_gt_info *info, struct drm_printer *p) { diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h index 2dad46c3eff2..0f571c8ee22b 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.h +++ b/drivers/gpu/drm/i915/gt/intel_gt.h @@ -85,6 +85,7 @@ static inline bool intel_gt_needs_read_steering(struct intel_gt *gt, } u32 intel_gt_read_register_fw(struct intel_gt *gt, i915_reg_t reg); +u32 intel_gt_read_register(struct intel_gt *gt, i915_reg_t reg); void intel_gt_info_print(const struct intel_gt_info *info, struct drm_printer *p); diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c index 983264e10e0a..e443ac4c8059 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c @@ -100,7 +100,7 @@ gen11_gt_identity_handler(struct intel_gt *gt, const u32 identity) if (unlikely(!intr)) return; - if (class <= COPY_ENGINE_CLASS) + if (class <= COPY_ENGINE_CLASS || class == COMPUTE_CLASS) return gen11_engine_irq_handler(gt, class, instance, intr); if (class == OTHER_CLASS) @@ -182,6 +182,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt) /* Disable RCS, BCS, VCS and VECS class engines. */ intel_uncore_write(uncore, GEN11_RENDER_COPY_INTR_ENABLE, 0); intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE, 0); + if (CCS_MASK(gt)) + intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, 0); /* Restore masks irqs on RCS, BCS, VCS and VECS engines. */ intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK, ~0); @@ -195,6 +197,10 @@ void gen11_gt_irq_reset(struct intel_gt *gt) intel_uncore_write(uncore, GEN11_VECS0_VECS1_INTR_MASK, ~0); if (HAS_ENGINE(gt, VECS2) || HAS_ENGINE(gt, VECS3)) intel_uncore_write(uncore, GEN12_VECS2_VECS3_INTR_MASK, ~0); + if (HAS_ENGINE(gt, CCS0) || HAS_ENGINE(gt, CCS1)) + intel_uncore_write(uncore, GEN12_CCS0_CCS1_INTR_MASK, ~0); + if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3)) + intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~0); intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0); intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK, ~0); @@ -225,6 +231,8 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt) /* Enable RCS, BCS, VCS and VECS class interrupts. */ intel_uncore_write(uncore, GEN11_RENDER_COPY_INTR_ENABLE, dmask); intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE, dmask); + if (CCS_MASK(gt)) + intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, smask); /* Unmask irqs on RCS, BCS, VCS and VECS engines. */ intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK, ~smask); @@ -238,6 +246,11 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt) intel_uncore_write(uncore, GEN11_VECS0_VECS1_INTR_MASK, ~dmask); if (HAS_ENGINE(gt, VECS2) || HAS_ENGINE(gt, VECS3)) intel_uncore_write(uncore, GEN12_VECS2_VECS3_INTR_MASK, ~dmask); + if (HAS_ENGINE(gt, CCS0) || HAS_ENGINE(gt, CCS1)) + intel_uncore_write(uncore, GEN12_CCS0_CCS1_INTR_MASK, ~dmask); + if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3)) + intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~dmask); + /* * RPS interrupts will get enabled/disabled on demand when RPS itself * is enabled/disabled. diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h index 18d158d77aba..19cd34f24263 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h @@ -465,6 +465,9 @@ #define GEN9_PGCTL_SSB_EU210_ACK (1 << 12) #define GEN9_PGCTL_SSB_EU311_ACK (1 << 14) +#define VF_PREEMPTION _MMIO(0x83a4) +#define PREEMPTION_VERTEX_COUNT REG_GENMASK(15, 0) + #define GEN8_RC6_CTX_INFO _MMIO(0x8504) #define GEN12_SQCM _MMIO(0x8724) @@ -1057,6 +1060,7 @@ #define FLOW_CONTROL_ENABLE REG_BIT(15) #define UGM_BACKUP_MODE REG_BIT(13) #define MDQ_ARBITRATION_MODE REG_BIT(12) +#define SYSTOLIC_DOP_CLOCK_GATING_DIS REG_BIT(10) #define PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE REG_BIT(8) #define STALL_DOP_GATING_DISABLE REG_BIT(5) #define THROTTLE_12_5 REG_GENMASK(4, 2) @@ -1324,6 +1328,9 @@ #define ECOBITS_PPGTT_CACHE64B (3 << 8) #define ECOBITS_PPGTT_CACHE4B (0 << 8) +#define GEN12_RCU_MODE _MMIO(0x14800) +#define GEN12_RCU_MODE_CCS_ENABLE REG_BIT(0) + #define CHV_FUSE_GT _MMIO(VLV_DISPLAY_BASE + 0x2168) #define CHV_FGT_DISABLE_SS0 (1 << 10) #define CHV_FGT_DISABLE_SS1 (1 << 11) @@ -1449,6 +1456,10 @@ #define GEN11_KCR (19) #define GEN11_GTPM (16) #define GEN11_BCS (15) +#define GEN12_CCS3 (7) +#define GEN12_CCS2 (6) +#define GEN12_CCS1 (5) +#define GEN12_CCS0 (4) #define GEN11_RCS0 (0) #define GEN11_VECS(x) (31 - (x)) #define GEN11_VCS(x) (x) @@ -1461,6 +1472,7 @@ #define GEN11_GPM_WGBOXPERF_INTR_ENABLE _MMIO(0x19003c) #define GEN11_CRYPTO_RSVD_INTR_ENABLE _MMIO(0x190040) #define GEN11_GUNIT_CSME_INTR_ENABLE _MMIO(0x190044) +#define GEN12_CCS_RSVD_INTR_ENABLE _MMIO(0x190048) #define GEN11_INTR_IDENTITY_REG(x) _MMIO(0x190060 + ((x) * 4)) #define GEN11_INTR_DATA_VALID (1 << 31) @@ -1486,41 +1498,9 @@ #define GEN11_GPM_WGBOXPERF_INTR_MASK _MMIO(0x1900ec) #define GEN11_CRYPTO_RSVD_INTR_MASK _MMIO(0x1900f0) #define GEN11_GUNIT_CSME_INTR_MASK _MMIO(0x1900f4) +#define GEN12_CCS0_CCS1_INTR_MASK _MMIO(0x190100) +#define GEN12_CCS2_CCS3_INTR_MASK _MMIO(0x190104) #define GEN12_SFC_DONE(n) _MMIO(0x1cc000 + (n) * 0x1000) -enum { - INTEL_ADVANCED_CONTEXT = 0, - INTEL_LEGACY_32B_CONTEXT, - INTEL_ADVANCED_AD_CONTEXT, - INTEL_LEGACY_64B_CONTEXT -}; - -enum { - FAULT_AND_HANG = 0, - FAULT_AND_HALT, /* Debug only */ - FAULT_AND_STREAM, - FAULT_AND_CONTINUE /* Unsupported */ -}; - -#define CTX_GTT_ADDRESS_MASK GENMASK(31, 12) -#define GEN8_CTX_VALID (1 << 0) -#define GEN8_CTX_FORCE_PD_RESTORE (1 << 1) -#define GEN8_CTX_FORCE_RESTORE (1 << 2) -#define GEN8_CTX_L3LLC_COHERENT (1 << 5) -#define GEN8_CTX_PRIVILEGE (1 << 8) -#define GEN8_CTX_ADDRESSING_MODE_SHIFT 3 -#define GEN8_CTX_ID_SHIFT 32 -#define GEN8_CTX_ID_WIDTH 21 -#define GEN11_SW_CTX_ID_SHIFT 37 -#define GEN11_SW_CTX_ID_WIDTH 11 -#define GEN11_ENGINE_CLASS_SHIFT 61 -#define GEN11_ENGINE_CLASS_WIDTH 3 -#define GEN11_ENGINE_INSTANCE_SHIFT 48 -#define GEN11_ENGINE_INSTANCE_WIDTH 6 -#define XEHP_SW_CTX_ID_SHIFT 39 -#define XEHP_SW_CTX_ID_WIDTH 16 -#define XEHP_SW_COUNTER_SHIFT 58 -#define XEHP_SW_COUNTER_WIDTH 6 - #endif /* __INTEL_GT_REGS__ */ diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c index 49a8fb63e6e5..4bcdfcab3642 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.c +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c @@ -107,14 +107,19 @@ void __i915_vm_close(struct i915_address_space *vm) list_for_each_entry_safe(vma, vn, &vm->bound_list, vm_link) { struct drm_i915_gem_object *obj = vma->obj; - /* Keep the obj (and hence the vma) alive as _we_ destroy it */ - if (!kref_get_unless_zero(&obj->base.refcount)) + if (!kref_get_unless_zero(&obj->base.refcount)) { + /* + * Unbind the dying vma to ensure the bound_list + * is completely drained. We leave the destruction to + * the object destructor. + */ + atomic_and(~I915_VMA_PIN_MASK, &vma->flags); + WARN_ON(__i915_vma_unbind(vma)); continue; + } - atomic_and(~I915_VMA_PIN_MASK, &vma->flags); - WARN_ON(__i915_vma_unbind(vma)); - __i915_vma_put(vma); - + /* Keep the obj (and hence the vma) alive as _we_ destroy it */ + i915_vma_destroy_locked(vma); i915_gem_object_put(obj); } GEM_BUG_ON(!list_empty(&vm->bound_list)); @@ -225,6 +230,18 @@ void i915_address_space_init(struct i915_address_space *vm, int subclass) GEM_BUG_ON(!vm->total); drm_mm_init(&vm->mm, 0, vm->total); + + memset64(vm->min_alignment, I915_GTT_MIN_ALIGNMENT, + ARRAY_SIZE(vm->min_alignment)); + + if (HAS_64K_PAGES(vm->i915) && NEEDS_COMPACT_PT(vm->i915)) { + vm->min_alignment[INTEL_MEMORY_LOCAL] = I915_GTT_PAGE_SIZE_2M; + vm->min_alignment[INTEL_MEMORY_STOLEN_LOCAL] = I915_GTT_PAGE_SIZE_2M; + } else if (HAS_64K_PAGES(vm->i915)) { + vm->min_alignment[INTEL_MEMORY_LOCAL] = I915_GTT_PAGE_SIZE_64K; + vm->min_alignment[INTEL_MEMORY_STOLEN_LOCAL] = I915_GTT_PAGE_SIZE_64K; + } + vm->mm.head_node.color = I915_COLOR_UNEVICTABLE; INIT_LIST_HEAD(&vm->bound_list); diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h index 8073438b67c8..9d83c2d3959c 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.h +++ b/drivers/gpu/drm/i915/gt/intel_gtt.h @@ -29,6 +29,8 @@ #include "i915_selftest.h" #include "i915_vma_resource.h" #include "i915_vma_types.h" +#include "i915_params.h" +#include "intel_memory_region.h" #define I915_GFP_ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN) @@ -90,6 +92,8 @@ typedef u64 gen8_pte_t; #define GEN12_GGTT_PTE_LM BIT_ULL(1) +#define GEN12_PDE_64K BIT(6) + /* * Cacheability Control is a 4-bit value. The low three bits are stored in bits * 3:1 of the PTE, while the fourth bit is stored in bit 11 of the PTE. @@ -158,6 +162,7 @@ struct i915_page_table { atomic_t used; struct i915_page_table *stash; }; + bool is_compact; }; struct i915_page_directory { @@ -195,6 +200,14 @@ void *__px_vaddr(struct drm_i915_gem_object *p); struct i915_vm_pt_stash { /* preallocated chains of page tables/directories */ struct i915_page_table *pt[2]; + /* + * Optionally override the alignment/size of the physical page that + * contains each PT. If not set defaults back to the usual + * I915_GTT_PAGE_SIZE_4K. This does not influence the other paging + * structures. MUST be a power-of-two. ONLY applicable on discrete + * platforms. + */ + int pt_sz; }; struct i915_vma_ops { @@ -223,6 +236,7 @@ struct i915_address_space { struct device *dma; u64 total; /* size addr space maps (ex. 2GB for ggtt) */ u64 reserved; /* size addr space reserved */ + u64 min_alignment[INTEL_MEMORY_STOLEN_LOCAL + 1]; unsigned int bind_async_flags; @@ -384,6 +398,25 @@ i915_vm_has_scratch_64K(struct i915_address_space *vm) return vm->scratch_order == get_order(I915_GTT_PAGE_SIZE_64K); } +static inline u64 i915_vm_min_alignment(struct i915_address_space *vm, + enum intel_memory_type type) +{ + /* avoid INTEL_MEMORY_MOCK overflow */ + if ((int)type >= ARRAY_SIZE(vm->min_alignment)) + type = INTEL_MEMORY_SYSTEM; + + return vm->min_alignment[type]; +} + +static inline u64 i915_vm_obj_min_alignment(struct i915_address_space *vm, + struct drm_i915_gem_object *obj) +{ + struct intel_memory_region *mr = READ_ONCE(obj->mm.region); + enum intel_memory_type type = mr ? mr->type : INTEL_MEMORY_SYSTEM; + + return i915_vm_min_alignment(vm, type); +} + static inline bool i915_vm_has_cache_coloring(struct i915_address_space *vm) { @@ -570,7 +603,7 @@ void free_scratch(struct i915_address_space *vm); struct drm_i915_gem_object *alloc_pt_dma(struct i915_address_space *vm, int sz); struct drm_i915_gem_object *alloc_pt_lmem(struct i915_address_space *vm, int sz); -struct i915_page_table *alloc_pt(struct i915_address_space *vm); +struct i915_page_table *alloc_pt(struct i915_address_space *vm, int sz); struct i915_page_directory *alloc_pd(struct i915_address_space *vm); struct i915_page_directory *__alloc_pd(int npde); diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 004e1216e654..07bef7128fdb 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -623,7 +623,7 @@ static const u8 *reg_offsets(const struct intel_engine_cs *engine) GEM_BUG_ON(GRAPHICS_VER(engine->i915) >= 12 && !intel_engine_has_relative_mmio(engine)); - if (engine->class == RENDER_CLASS) { + if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) { if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 55)) return dg2_rcs_offsets; else if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 50)) @@ -1217,6 +1217,14 @@ gen12_emit_indirect_ctx_xcs(const struct intel_context *ce, u32 *cs) cs = gen12_emit_timestamp_wa(ce, cs); cs = gen12_emit_restore_scratch(ce, cs); + /* Wa_16013000631:dg2 */ + if (IS_DG2_GRAPHICS_STEP(ce->engine->i915, G10, STEP_B0, STEP_C0) || + IS_DG2_G11(ce->engine->i915)) + if (ce->engine->class == COMPUTE_CLASS) + cs = gen8_emit_pipe_control(cs, + PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE, + 0); + return cs; } @@ -1619,7 +1627,7 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine) unsigned int i; int err; - if (engine->class != RENDER_CLASS) + if (!(engine->flags & I915_ENGINE_HAS_RCS_REG_STATE)) return; switch (GRAPHICS_VER(engine->i915)) { diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.h b/drivers/gpu/drm/i915/gt/intel_lrc.h index 0b76f096b559..6e4f9f58fca5 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.h +++ b/drivers/gpu/drm/i915/gt/intel_lrc.h @@ -6,6 +6,9 @@ #ifndef __INTEL_LRC_H__ #define __INTEL_LRC_H__ +#include "i915_priolist_types.h" + +#include <linux/bitfield.h> #include <linux/types.h> struct drm_i915_gem_object; @@ -69,4 +72,52 @@ void lrc_check_regs(const struct intel_context *ce, void lrc_update_runtime(struct intel_context *ce); +enum { + INTEL_ADVANCED_CONTEXT = 0, + INTEL_LEGACY_32B_CONTEXT, + INTEL_ADVANCED_AD_CONTEXT, + INTEL_LEGACY_64B_CONTEXT +}; + +enum { + FAULT_AND_HANG = 0, + FAULT_AND_HALT, /* Debug only */ + FAULT_AND_STREAM, + FAULT_AND_CONTINUE /* Unsupported */ +}; + +#define CTX_GTT_ADDRESS_MASK GENMASK(31, 12) +#define GEN8_CTX_VALID (1 << 0) +#define GEN8_CTX_FORCE_PD_RESTORE (1 << 1) +#define GEN8_CTX_FORCE_RESTORE (1 << 2) +#define GEN8_CTX_L3LLC_COHERENT (1 << 5) +#define GEN8_CTX_PRIVILEGE (1 << 8) +#define GEN8_CTX_ADDRESSING_MODE_SHIFT 3 +#define GEN12_CTX_PRIORITY_MASK GENMASK(10, 9) +#define GEN12_CTX_PRIORITY_HIGH FIELD_PREP(GEN12_CTX_PRIORITY_MASK, 2) +#define GEN12_CTX_PRIORITY_NORMAL FIELD_PREP(GEN12_CTX_PRIORITY_MASK, 1) +#define GEN12_CTX_PRIORITY_LOW FIELD_PREP(GEN12_CTX_PRIORITY_MASK, 0) +#define GEN8_CTX_ID_SHIFT 32 +#define GEN8_CTX_ID_WIDTH 21 +#define GEN11_SW_CTX_ID_SHIFT 37 +#define GEN11_SW_CTX_ID_WIDTH 11 +#define GEN11_ENGINE_CLASS_SHIFT 61 +#define GEN11_ENGINE_CLASS_WIDTH 3 +#define GEN11_ENGINE_INSTANCE_SHIFT 48 +#define GEN11_ENGINE_INSTANCE_WIDTH 6 +#define XEHP_SW_CTX_ID_SHIFT 39 +#define XEHP_SW_CTX_ID_WIDTH 16 +#define XEHP_SW_COUNTER_SHIFT 58 +#define XEHP_SW_COUNTER_WIDTH 6 + +static inline u32 lrc_desc_priority(int prio) +{ + if (prio > I915_PRIORITY_NORMAL) + return GEN12_CTX_PRIORITY_HIGH; + else if (prio < I915_PRIORITY_NORMAL) + return GEN12_CTX_PRIORITY_LOW; + else + return GEN12_CTX_PRIORITY_NORMAL; +} + #endif /* __INTEL_LRC_H__ */ diff --git a/drivers/gpu/drm/i915/gt/intel_migrate.c b/drivers/gpu/drm/i915/gt/intel_migrate.c index 18b44af56969..20444d6ceb3c 100644 --- a/drivers/gpu/drm/i915/gt/intel_migrate.c +++ b/drivers/gpu/drm/i915/gt/intel_migrate.c @@ -32,6 +32,38 @@ static bool engine_supports_migration(struct intel_engine_cs *engine) return true; } +static void xehpsdv_toggle_pdes(struct i915_address_space *vm, + struct i915_page_table *pt, + void *data) +{ + struct insert_pte_data *d = data; + + /* + * Insert a dummy PTE into every PT that will map to LMEM to ensure + * we have a correctly setup PDE structure for later use. + */ + vm->insert_page(vm, 0, d->offset, I915_CACHE_NONE, PTE_LM); + GEM_BUG_ON(!pt->is_compact); + d->offset += SZ_2M; +} + +static void xehpsdv_insert_pte(struct i915_address_space *vm, + struct i915_page_table *pt, + void *data) +{ + struct insert_pte_data *d = data; + + /* + * We are playing tricks here, since the actual pt, from the hw + * pov, is only 256bytes with 32 entries, or 4096bytes with 512 + * entries, but we are still guaranteed that the physical + * alignment is 64K underneath for the pt, and we are careful + * not to access the space in the void. + */ + vm->insert_page(vm, px_dma(pt), d->offset, I915_CACHE_NONE, PTE_LM); + d->offset += SZ_64K; +} + static void insert_pte(struct i915_address_space *vm, struct i915_page_table *pt, void *data) @@ -74,7 +106,32 @@ static struct i915_address_space *migrate_vm(struct intel_gt *gt) * i.e. within the same non-preemptible window so that we do not switch * to another migration context that overwrites the PTE. * - * TODO: Add support for huge LMEM PTEs + * This changes quite a bit on platforms with HAS_64K_PAGES support, + * where we instead have three windows, each CHUNK_SIZE in size. The + * first is reserved for mapping system-memory, and that just uses the + * 512 entry layout using 4K GTT pages. The other two windows just map + * lmem pages and must use the new compact 32 entry layout using 64K GTT + * pages, which ensures we can address any lmem object that the user + * throws at us. We then also use the xehpsdv_toggle_pdes as a way of + * just toggling the PDE bit(GEN12_PDE_64K) for us, to enable the + * compact layout for each of these page-tables, that fall within the + * [CHUNK_SIZE, 3 * CHUNK_SIZE) range. + * + * We lay the ppGTT out as: + * + * [0, CHUNK_SZ) -> first window/object, maps smem + * [CHUNK_SZ, 2 * CHUNK_SZ) -> second window/object, maps lmem src + * [2 * CHUNK_SZ, 3 * CHUNK_SZ) -> third window/object, maps lmem dst + * + * For the PTE window it's also quite different, since each PTE must + * point to some 64K page, one for each PT(since it's in lmem), and yet + * each is only <= 4096bytes, but since the unused space within that PTE + * range is never touched, this should be fine. + * + * So basically each PT now needs 64K of virtual memory, instead of 4K, + * which looks like: + * + * [3 * CHUNK_SZ, 3 * CHUNK_SZ + ((3 * CHUNK_SZ / SZ_2M) * SZ_64K)] -> PTE */ vm = i915_ppgtt_create(gt, I915_BO_ALLOC_PM_EARLY); @@ -86,6 +143,9 @@ static struct i915_address_space *migrate_vm(struct intel_gt *gt) goto err_vm; } + if (HAS_64K_PAGES(gt->i915)) + stash.pt_sz = I915_GTT_PAGE_SIZE_64K; + /* * Each engine instance is assigned its own chunk in the VM, so * that we can run multiple instances concurrently @@ -105,14 +165,20 @@ static struct i915_address_space *migrate_vm(struct intel_gt *gt) * We copy in 8MiB chunks. Each PDE covers 2MiB, so we need * 4x2 page directories for source/destination. */ - sz = 2 * CHUNK_SZ; + if (HAS_64K_PAGES(gt->i915)) + sz = 3 * CHUNK_SZ; + else + sz = 2 * CHUNK_SZ; d.offset = base + sz; /* * We need another page directory setup so that we can write * the 8x512 PTE in each chunk. */ - sz += (sz >> 12) * sizeof(u64); + if (HAS_64K_PAGES(gt->i915)) + sz += (sz / SZ_2M) * SZ_64K; + else + sz += (sz >> 12) * sizeof(u64); err = i915_vm_alloc_pt_stash(&vm->vm, &stash, sz); if (err) @@ -133,7 +199,18 @@ static struct i915_address_space *migrate_vm(struct intel_gt *gt) goto err_vm; /* Now allow the GPU to rewrite the PTE via its own ppGTT */ - vm->vm.foreach(&vm->vm, base, d.offset - base, insert_pte, &d); + if (HAS_64K_PAGES(gt->i915)) { + vm->vm.foreach(&vm->vm, base, d.offset - base, + xehpsdv_insert_pte, &d); + d.offset = base + CHUNK_SZ; + vm->vm.foreach(&vm->vm, + d.offset, + 2 * CHUNK_SZ, + xehpsdv_toggle_pdes, &d); + } else { + vm->vm.foreach(&vm->vm, base, d.offset - base, + insert_pte, &d); + } } return &vm->vm; @@ -269,19 +346,38 @@ static int emit_pte(struct i915_request *rq, u64 offset, int length) { + bool has_64K_pages = HAS_64K_PAGES(rq->engine->i915); const u64 encode = rq->context->vm->pte_encode(0, cache_level, is_lmem ? PTE_LM : 0); struct intel_ring *ring = rq->ring; - int total = 0; + int pkt, dword_length; + u32 total = 0; + u32 page_size; u32 *hdr, *cs; - int pkt; GEM_BUG_ON(GRAPHICS_VER(rq->engine->i915) < 8); + page_size = I915_GTT_PAGE_SIZE; + dword_length = 0x400; + /* Compute the page directory offset for the target address range */ - offset >>= 12; - offset *= sizeof(u64); - offset += 2 * CHUNK_SZ; + if (has_64K_pages) { + GEM_BUG_ON(!IS_ALIGNED(offset, SZ_2M)); + + offset /= SZ_2M; + offset *= SZ_64K; + offset += 3 * CHUNK_SZ; + + if (is_lmem) { + page_size = I915_GTT_PAGE_SIZE_64K; + dword_length = 0x40; + } + } else { + offset >>= 12; + offset *= sizeof(u64); + offset += 2 * CHUNK_SZ; + } + offset += (u64)rq->engine->instance << 32; cs = intel_ring_begin(rq, 6); @@ -289,7 +385,7 @@ static int emit_pte(struct i915_request *rq, return PTR_ERR(cs); /* Pack as many PTE updates as possible into a single MI command */ - pkt = min_t(int, 0x400, ring->space / sizeof(u32) + 5); + pkt = min_t(int, dword_length, ring->space / sizeof(u32) + 5); pkt = min_t(int, pkt, (ring->size - ring->emit) / sizeof(u32) + 5); hdr = cs; @@ -299,6 +395,8 @@ static int emit_pte(struct i915_request *rq, do { if (cs - hdr >= pkt) { + int dword_rem; + *hdr += cs - hdr - 2; *cs++ = MI_NOOP; @@ -310,7 +408,18 @@ static int emit_pte(struct i915_request *rq, if (IS_ERR(cs)) return PTR_ERR(cs); - pkt = min_t(int, 0x400, ring->space / sizeof(u32) + 5); + dword_rem = dword_length; + if (has_64K_pages) { + if (IS_ALIGNED(total, SZ_2M)) { + offset = round_up(offset, SZ_64K); + } else { + dword_rem = SZ_2M - (total & (SZ_2M - 1)); + dword_rem /= page_size; + dword_rem *= 2; + } + } + + pkt = min_t(int, dword_rem, ring->space / sizeof(u32) + 5); pkt = min_t(int, pkt, (ring->size - ring->emit) / sizeof(u32) + 5); hdr = cs; @@ -319,13 +428,15 @@ static int emit_pte(struct i915_request *rq, *cs++ = upper_32_bits(offset); } + GEM_BUG_ON(!IS_ALIGNED(it->dma, page_size)); + *cs++ = lower_32_bits(encode | it->dma); *cs++ = upper_32_bits(encode | it->dma); offset += 8; - total += I915_GTT_PAGE_SIZE; + total += page_size; - it->dma += I915_GTT_PAGE_SIZE; + it->dma += page_size; if (it->dma >= it->max) { it->sg = __sg_next(it->sg); if (!it->sg || sg_dma_len(it->sg) == 0) @@ -356,7 +467,8 @@ static bool wa_1209644611_applies(int ver, u32 size) return height % 4 == 3 && height <= 8; } -static int emit_copy(struct i915_request *rq, int size) +static int emit_copy(struct i915_request *rq, + u32 dst_offset, u32 src_offset, int size) { const int ver = GRAPHICS_VER(rq->engine->i915); u32 instance = rq->engine->instance; @@ -371,31 +483,31 @@ static int emit_copy(struct i915_request *rq, int size) *cs++ = BLT_DEPTH_32 | PAGE_SIZE; *cs++ = 0; *cs++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4; - *cs++ = CHUNK_SZ; /* dst offset */ + *cs++ = dst_offset; *cs++ = instance; *cs++ = 0; *cs++ = PAGE_SIZE; - *cs++ = 0; /* src offset */ + *cs++ = src_offset; *cs++ = instance; } else if (ver >= 8) { *cs++ = XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGBA | (10 - 2); *cs++ = BLT_DEPTH_32 | BLT_ROP_SRC_COPY | PAGE_SIZE; *cs++ = 0; *cs++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4; - *cs++ = CHUNK_SZ; /* dst offset */ + *cs++ = dst_offset; *cs++ = instance; *cs++ = 0; *cs++ = PAGE_SIZE; - *cs++ = 0; /* src offset */ + *cs++ = src_offset; *cs++ = instance; } else { GEM_BUG_ON(instance); *cs++ = SRC_COPY_BLT_CMD | BLT_WRITE_RGBA | (6 - 2); *cs++ = BLT_DEPTH_32 | BLT_ROP_SRC_COPY | PAGE_SIZE; *cs++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE; - *cs++ = CHUNK_SZ; /* dst offset */ + *cs++ = dst_offset; *cs++ = PAGE_SIZE; - *cs++ = 0; /* src offset */ + *cs++ = src_offset; } intel_ring_advance(rq, cs); @@ -423,6 +535,7 @@ intel_context_migrate_copy(struct intel_context *ce, GEM_BUG_ON(ce->ring->size < SZ_64K); do { + u32 src_offset, dst_offset; int len; rq = i915_request_create(ce); @@ -450,15 +563,28 @@ intel_context_migrate_copy(struct intel_context *ce, if (err) goto out_rq; - len = emit_pte(rq, &it_src, src_cache_level, src_is_lmem, 0, - CHUNK_SZ); + src_offset = 0; + dst_offset = CHUNK_SZ; + if (HAS_64K_PAGES(ce->engine->i915)) { + GEM_BUG_ON(!src_is_lmem && !dst_is_lmem); + + src_offset = 0; + dst_offset = 0; + if (src_is_lmem) + src_offset = CHUNK_SZ; + if (dst_is_lmem) + dst_offset = 2 * CHUNK_SZ; + } + + len = emit_pte(rq, &it_src, src_cache_level, src_is_lmem, + src_offset, CHUNK_SZ); if (len <= 0) { err = len; goto out_rq; } err = emit_pte(rq, &it_dst, dst_cache_level, dst_is_lmem, - CHUNK_SZ, len); + dst_offset, len); if (err < 0) goto out_rq; if (err < len) { @@ -470,7 +596,7 @@ intel_context_migrate_copy(struct intel_context *ce, if (err) goto out_rq; - err = emit_copy(rq, len); + err = emit_copy(rq, dst_offset, src_offset, len); /* Arbitration is re-enabled between requests. */ out_rq: @@ -488,14 +614,15 @@ out_ce: return err; } -static int emit_clear(struct i915_request *rq, int size, u32 value) +static int emit_clear(struct i915_request *rq, u64 offset, int size, u32 value) { const int ver = GRAPHICS_VER(rq->engine->i915); - u32 instance = rq->engine->instance; u32 *cs; GEM_BUG_ON(size >> PAGE_SHIFT > S16_MAX); + offset += (u64)rq->engine->instance << 32; + cs = intel_ring_begin(rq, ver >= 8 ? 8 : 6); if (IS_ERR(cs)) return PTR_ERR(cs); @@ -505,17 +632,17 @@ static int emit_clear(struct i915_request *rq, int size, u32 value) *cs++ = BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | PAGE_SIZE; *cs++ = 0; *cs++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4; - *cs++ = 0; /* offset */ - *cs++ = instance; + *cs++ = lower_32_bits(offset); + *cs++ = upper_32_bits(offset); *cs++ = value; *cs++ = MI_NOOP; } else { - GEM_BUG_ON(instance); + GEM_BUG_ON(upper_32_bits(offset)); *cs++ = XY_COLOR_BLT_CMD | BLT_WRITE_RGBA | (6 - 2); *cs++ = BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | PAGE_SIZE; *cs++ = 0; *cs++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4; - *cs++ = 0; + *cs++ = lower_32_bits(offset); *cs++ = value; } @@ -542,6 +669,7 @@ intel_context_migrate_clear(struct intel_context *ce, GEM_BUG_ON(ce->ring->size < SZ_64K); do { + u32 offset; int len; rq = i915_request_create(ce); @@ -569,7 +697,11 @@ intel_context_migrate_clear(struct intel_context *ce, if (err) goto out_rq; - len = emit_pte(rq, &it, cache_level, is_lmem, 0, CHUNK_SZ); + offset = 0; + if (HAS_64K_PAGES(ce->engine->i915) && is_lmem) + offset = CHUNK_SZ; + + len = emit_pte(rq, &it, cache_level, is_lmem, offset, CHUNK_SZ); if (len <= 0) { err = len; goto out_rq; @@ -579,7 +711,7 @@ intel_context_migrate_clear(struct intel_context *ce, if (err) goto out_rq; - err = emit_clear(rq, len, value); + err = emit_clear(rq, offset, len, value); /* Arbitration is re-enabled between requests. */ out_rq: diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c b/drivers/gpu/drm/i915/gt/intel_ppgtt.c index 48e6e2f87700..d91e2beb7517 100644 --- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c @@ -12,7 +12,7 @@ #include "gen6_ppgtt.h" #include "gen8_ppgtt.h" -struct i915_page_table *alloc_pt(struct i915_address_space *vm) +struct i915_page_table *alloc_pt(struct i915_address_space *vm, int sz) { struct i915_page_table *pt; @@ -20,12 +20,13 @@ struct i915_page_table *alloc_pt(struct i915_address_space *vm) if (unlikely(!pt)) return ERR_PTR(-ENOMEM); - pt->base = vm->alloc_pt_dma(vm, I915_GTT_PAGE_SIZE_4K); + pt->base = vm->alloc_pt_dma(vm, sz); if (IS_ERR(pt->base)) { kfree(pt); return ERR_PTR(-ENOMEM); } + pt->is_compact = false; atomic_set(&pt->used, 0); return pt; } @@ -220,17 +221,25 @@ int i915_vm_alloc_pt_stash(struct i915_address_space *vm, u64 size) { unsigned long count; - int shift, n; + int shift, n, pt_sz; shift = vm->pd_shift; if (!shift) return 0; + pt_sz = stash->pt_sz; + if (!pt_sz) + pt_sz = I915_GTT_PAGE_SIZE_4K; + else + GEM_BUG_ON(!IS_DGFX(vm->i915)); + + GEM_BUG_ON(!is_power_of_2(pt_sz)); + count = pd_count(size, shift); while (count--) { struct i915_page_table *pt; - pt = alloc_pt(vm); + pt = alloc_pt(vm, pt_sz); if (IS_ERR(pt)) { i915_vm_free_pt_stash(vm, stash); return PTR_ERR(pt); diff --git a/drivers/gpu/drm/i915/gt/intel_region_lmem.c b/drivers/gpu/drm/i915/gt/intel_region_lmem.c index a04e0cf4a94b..6cecfdae07ad 100644 --- a/drivers/gpu/drm/i915/gt/intel_region_lmem.c +++ b/drivers/gpu/drm/i915/gt/intel_region_lmem.c @@ -14,60 +14,6 @@ #include "gt/intel_gt.h" #include "gt/intel_gt_regs.h" -static int init_fake_lmem_bar(struct intel_memory_region *mem) -{ - struct drm_i915_private *i915 = mem->i915; - struct i915_ggtt *ggtt = to_gt(i915)->ggtt; - unsigned long n; - int ret; - - /* We want to 1:1 map the mappable aperture to our reserved region */ - - mem->fake_mappable.start = 0; - mem->fake_mappable.size = resource_size(&mem->region); - mem->fake_mappable.color = I915_COLOR_UNEVICTABLE; - - ret = drm_mm_reserve_node(&ggtt->vm.mm, &mem->fake_mappable); - if (ret) - return ret; - - mem->remap_addr = dma_map_resource(i915->drm.dev, - mem->region.start, - mem->fake_mappable.size, - DMA_BIDIRECTIONAL, - DMA_ATTR_FORCE_CONTIGUOUS); - if (dma_mapping_error(i915->drm.dev, mem->remap_addr)) { - drm_mm_remove_node(&mem->fake_mappable); - return -EINVAL; - } - - for (n = 0; n < mem->fake_mappable.size >> PAGE_SHIFT; ++n) { - ggtt->vm.insert_page(&ggtt->vm, - mem->remap_addr + (n << PAGE_SHIFT), - n << PAGE_SHIFT, - I915_CACHE_NONE, 0); - } - - mem->region = (struct resource)DEFINE_RES_MEM(mem->remap_addr, - mem->fake_mappable.size); - - return 0; -} - -static void release_fake_lmem_bar(struct intel_memory_region *mem) -{ - if (!drm_mm_node_allocated(&mem->fake_mappable)) - return; - - drm_mm_remove_node(&mem->fake_mappable); - - dma_unmap_resource(mem->i915->drm.dev, - mem->remap_addr, - mem->fake_mappable.size, - DMA_BIDIRECTIONAL, - DMA_ATTR_FORCE_CONTIGUOUS); -} - static int region_lmem_release(struct intel_memory_region *mem) { @@ -75,7 +21,6 @@ region_lmem_release(struct intel_memory_region *mem) ret = intel_region_ttm_fini(mem); io_mapping_fini(&mem->iomap); - release_fake_lmem_bar(mem); return ret; } @@ -85,17 +30,10 @@ region_lmem_init(struct intel_memory_region *mem) { int ret; - if (mem->i915->params.fake_lmem_start) { - ret = init_fake_lmem_bar(mem); - GEM_BUG_ON(ret); - } - if (!io_mapping_init_wc(&mem->iomap, mem->io_start, - resource_size(&mem->region))) { - ret = -EIO; - goto out_no_io; - } + mem->io_size)) + return -EIO; ret = intel_region_ttm_init(mem); if (ret) @@ -105,8 +43,6 @@ region_lmem_init(struct intel_memory_region *mem) out_no_buddy: io_mapping_fini(&mem->iomap); -out_no_io: - release_fake_lmem_bar(mem); return ret; } @@ -117,50 +53,6 @@ static const struct intel_memory_region_ops intel_region_lmem_ops = { .init_object = __i915_gem_ttm_object_init, }; -struct intel_memory_region * -intel_gt_setup_fake_lmem(struct intel_gt *gt) -{ - struct drm_i915_private *i915 = gt->i915; - struct pci_dev *pdev = to_pci_dev(i915->drm.dev); - struct intel_memory_region *mem; - resource_size_t mappable_end; - resource_size_t io_start; - resource_size_t start; - - if (!HAS_LMEM(i915)) - return ERR_PTR(-ENODEV); - - if (!i915->params.fake_lmem_start) - return ERR_PTR(-ENODEV); - - GEM_BUG_ON(i915_ggtt_has_aperture(to_gt(i915)->ggtt)); - - /* Your mappable aperture belongs to me now! */ - mappable_end = pci_resource_len(pdev, 2); - io_start = pci_resource_start(pdev, 2); - start = i915->params.fake_lmem_start; - - mem = intel_memory_region_create(i915, - start, - mappable_end, - PAGE_SIZE, - io_start, - INTEL_MEMORY_LOCAL, - 0, - &intel_region_lmem_ops); - if (!IS_ERR(mem)) { - drm_info(&i915->drm, "Intel graphics fake LMEM: %pR\n", - &mem->region); - drm_info(&i915->drm, - "Intel graphics fake LMEM IO start: %llx\n", - (u64)mem->io_start); - drm_info(&i915->drm, "Intel graphics fake LMEM size: %llx\n", - (u64)resource_size(&mem->region)); - } - - return mem; -} - static bool get_legacy_lowmem_region(struct intel_uncore *uncore, u64 *start, u32 *size) { @@ -207,8 +99,29 @@ static struct intel_memory_region *setup_lmem(struct intel_gt *gt) if (!IS_DGFX(i915)) return ERR_PTR(-ENODEV); - /* Stolen starts from GSMBASE on DG1 */ - lmem_size = intel_uncore_read64(uncore, GEN12_GSMBASE); + if (HAS_FLAT_CCS(i915)) { + u64 tile_stolen, flat_ccs_base; + + lmem_size = pci_resource_len(pdev, 2); + flat_ccs_base = intel_gt_read_register(gt, XEHPSDV_FLAT_CCS_BASE_ADDR); + flat_ccs_base = (flat_ccs_base >> XEHPSDV_CCS_BASE_SHIFT) * SZ_64K; + + if (GEM_WARN_ON(lmem_size < flat_ccs_base)) + return ERR_PTR(-ENODEV); + + tile_stolen = lmem_size - flat_ccs_base; + + /* If the FLAT_CCS_BASE_ADDR register is not populated, flag an error */ + if (tile_stolen == lmem_size) + drm_err(&i915->drm, + "CCS_BASE_ADDR register did not have expected value\n"); + + lmem_size -= tile_stolen; + } else { + /* Stolen starts from GSMBASE without CCS */ + lmem_size = intel_uncore_read64(&i915->uncore, GEN12_GSMBASE); + } + io_start = pci_resource_start(pdev, 2); if (GEM_WARN_ON(lmem_size > pci_resource_len(pdev, 2))) @@ -221,6 +134,7 @@ static struct intel_memory_region *setup_lmem(struct intel_gt *gt) lmem_size, min_page_size, io_start, + lmem_size, INTEL_MEMORY_LOCAL, 0, &intel_region_lmem_ops); @@ -234,6 +148,8 @@ static struct intel_memory_region *setup_lmem(struct intel_gt *gt) drm_dbg(&i915->drm, "Local memory: %pR\n", &mem->region); drm_dbg(&i915->drm, "Local memory IO start: %pa\n", &mem->io_start); + drm_info(&i915->drm, "Local memory IO size: %pa\n", + &mem->io_size); drm_info(&i915->drm, "Local memory available: %pa\n", &lmem_size); diff --git a/drivers/gpu/drm/i915/gt/intel_region_lmem.h b/drivers/gpu/drm/i915/gt/intel_region_lmem.h index 062d0542ae34..1438576b527a 100644 --- a/drivers/gpu/drm/i915/gt/intel_region_lmem.h +++ b/drivers/gpu/drm/i915/gt/intel_region_lmem.h @@ -10,7 +10,4 @@ struct intel_gt; struct intel_memory_region *intel_gt_setup_lmem(struct intel_gt *gt); -struct intel_memory_region * -intel_gt_setup_fake_lmem(struct intel_gt *gt); - #endif /* !__INTEL_REGION_LMEM_H */ diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index fd95449ed46d..c8124101aada 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.c +++ b/drivers/gpu/drm/i915/gt/intel_rps.c @@ -1486,7 +1486,7 @@ void intel_rps_enable(struct intel_rps *rps) if (has_busy_stats(rps)) intel_rps_set_timer(rps); - else if (GRAPHICS_VER(i915) >= 6) + else if (GRAPHICS_VER(i915) >= 6 && GRAPHICS_VER(i915) <= 11) intel_rps_set_interrupts(rps); else /* Ironlake currently uses intel_ips.ko */ {} diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.c b/drivers/gpu/drm/i915/gt/intel_sseu.c index 29118c652811..4ac0bbaf0c31 100644 --- a/drivers/gpu/drm/i915/gt/intel_sseu.c +++ b/drivers/gpu/drm/i915/gt/intel_sseu.c @@ -32,7 +32,9 @@ intel_sseu_subslice_total(const struct sseu_dev_info *sseu) return total; } -u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice) +static u32 +_intel_sseu_get_subslices(const struct sseu_dev_info *sseu, + const u8 *subslice_mask, u8 slice) { int i, offset = slice * sseu->ss_stride; u32 mask = 0; @@ -40,12 +42,21 @@ u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice) GEM_BUG_ON(slice >= sseu->max_slices); for (i = 0; i < sseu->ss_stride; i++) - mask |= (u32)sseu->subslice_mask[offset + i] << - i * BITS_PER_BYTE; + mask |= (u32)subslice_mask[offset + i] << i * BITS_PER_BYTE; return mask; } +u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice) +{ + return _intel_sseu_get_subslices(sseu, sseu->subslice_mask, slice); +} + +u32 intel_sseu_get_compute_subslices(const struct sseu_dev_info *sseu) +{ + return _intel_sseu_get_subslices(sseu, sseu->compute_subslice_mask, 0); +} + void intel_sseu_set_subslices(struct sseu_dev_info *sseu, int slice, u8 *subslice_mask, u32 ss_mask) { diff --git a/drivers/gpu/drm/i915/gt/intel_sseu.h b/drivers/gpu/drm/i915/gt/intel_sseu.h index 60882a74741e..8a79cd8eaab4 100644 --- a/drivers/gpu/drm/i915/gt/intel_sseu.h +++ b/drivers/gpu/drm/i915/gt/intel_sseu.h @@ -103,7 +103,9 @@ intel_sseu_subslice_total(const struct sseu_dev_info *sseu); unsigned int intel_sseu_subslices_per_slice(const struct sseu_dev_info *sseu, u8 slice); -u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice); +u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice); + +u32 intel_sseu_get_compute_subslices(const struct sseu_dev_info *sseu); void intel_sseu_set_subslices(struct sseu_dev_info *sseu, int slice, u8 *subslice_mask, u32 ss_mask); diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index 26038066e90b..c014b40d2e9f 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -684,11 +684,10 @@ static void dg2_ctx_workarounds_init(struct intel_engine_cs *engine, wa_masked_en(wal, SLICE_COMMON_ECO_CHICKEN1, MSC_MSAA_REODER_BUF_BYPASS_DISABLE); - /* Wa_22012532006:dg2 */ - if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_C0) || - IS_DG2_GRAPHICS_STEP(engine->i915, G11, STEP_A0, STEP_B0)) - wa_masked_en(wal, GEN9_HALF_SLICE_CHICKEN7, - DG2_DISABLE_ROUND_ENABLE_ALLOW_FOR_SSLA); + /* Wa_14014947963:dg2 */ + if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_B0, STEP_FOREVER) || + IS_DG2_G11(engine->i915) || IS_DG2_G12(engine->i915)) + wa_masked_field_set(wal, VF_PREEMPTION, PREEMPTION_VERTEX_COUNT, 0x4000); } static void fakewa_disable_nestedbb_mode(struct intel_engine_cs *engine, @@ -1344,12 +1343,6 @@ xehpsdv_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) /* Wa_1409757795:xehpsdv */ wa_write_or(wal, SCCGCTL94DC, CG3DDISURB); - /* Wa_18011725039:xehpsdv */ - if (IS_XEHPSDV_GRAPHICS_STEP(i915, STEP_A1, STEP_B0)) { - wa_masked_dis(wal, MLTICTXCTL, TDONRENDER); - wa_write_or(wal, L3SQCREG1_CCS0, FLUSHALLNONCOH); - } - /* Wa_16011155590:xehpsdv */ if (IS_XEHPSDV_GRAPHICS_STEP(i915, STEP_A0, STEP_B0)) wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE, @@ -1386,19 +1379,12 @@ xehpsdv_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) GAMTLBVEBOX0_CLKGATE_DIS); } - /* Wa_14012362059:xehpsdv */ - wa_write_or(wal, GEN12_MERT_MOD_CTRL, FORCE_MISS_FTLB); - /* Wa_16012725990:xehpsdv */ if (IS_XEHPSDV_GRAPHICS_STEP(i915, STEP_A1, STEP_FOREVER)) wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE, VFUNIT_CLKGATE_DIS); /* Wa_14011060649:xehpsdv */ wa_14011060649(gt, wal); - - /* Wa_14014368820:xehpsdv */ - wa_write_or(wal, GEN12_GAMCNTRL_CTRL, INVALIDATION_BROADCAST_MODE_DIS | - GLOBAL_INVALIDATION_MODE); } static void @@ -1440,10 +1426,6 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) } if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0)) { - /* Wa_14010680813:dg2_g10 */ - wa_write_or(wal, GEN12_GAMSTLB_CTRL, CONTROL_BLOCK_CLKGATE_DIS | - EGRESS_BLOCK_CLKGATE_DIS | TAG_BLOCK_CLKGATE_DIS); - /* Wa_14010948348:dg2_g10 */ wa_write_or(wal, UNSLCGCTL9430, MSQDUNIT_CLKGATE_DIS); @@ -1490,16 +1472,6 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) wa_write_or(wal, SSMCGCTL9530, RTFUNIT_CLKGATE_DIS); } - if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0) || - IS_DG2_GRAPHICS_STEP(gt->i915, G11, STEP_A0, STEP_B0)) { - /* Wa_14012362059:dg2 */ - wa_write_or(wal, GEN12_MERT_MOD_CTRL, FORCE_MISS_FTLB); - } - - /* Wa_1509235366:dg2 */ - wa_write_or(wal, GEN12_GAMCNTRL_CTRL, INVALIDATION_BROADCAST_MODE_DIS | - GLOBAL_INVALIDATION_MODE); - /* Wa_14014830051:dg2 */ wa_write_clr(wal, SARB_CHICKEN1, COMP_CKN_IN); @@ -1508,14 +1480,7 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) * recommended tuning settings documented in the bspec's * performance guide section. */ - wa_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS); wa_write_or(wal, GEN12_SQCM, EN_32B_ACCESS); - - /* Wa_18018781329:dg2 */ - wa_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB); - wa_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB); - wa_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB); - wa_write_or(wal, VEBX_MOD_CTRL, FORCE_MISS_FTLB); } static void @@ -1943,6 +1908,11 @@ static void dg2_whitelist_build(struct intel_engine_cs *engine) RING_FORCE_TO_NONPRIV_RANGE_4); break; + case COMPUTE_CLASS: + /* Wa_16011157294:dg2_g10 */ + if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0)) + whitelist_reg(w, GEN9_CTX_PREEMPT_REG); + break; default: break; } @@ -2049,6 +2019,23 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) if (IS_DG2(i915)) { /* Wa_14015227452:dg2 */ wa_masked_en(wal, GEN9_ROW_CHICKEN4, XEHP_DIS_BBL_SYSPIPE); + + /* Wa_1509235366:dg2 */ + wa_write_or(wal, GEN12_GAMCNTRL_CTRL, INVALIDATION_BROADCAST_MODE_DIS | + GLOBAL_INVALIDATION_MODE); + + /* + * The following are not actually "workarounds" but rather + * recommended tuning settings documented in the bspec's + * performance guide section. + */ + wa_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS); + + /* Wa_18018781329:dg2 */ + wa_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB); + wa_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB); + wa_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB); + wa_write_or(wal, VEBX_MOD_CTRL, FORCE_MISS_FTLB); } if (IS_DG2_GRAPHICS_STEP(i915, G11, STEP_A0, STEP_B0)) { @@ -2149,6 +2136,24 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) IS_DG2_GRAPHICS_STEP(i915, G11, STEP_A0, STEP_B0)) wa_write_or(wal, RT_CTRL, DIS_NULL_QUERY); + /* Wa_22012532006:dg2 */ + if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_C0) || + IS_DG2_GRAPHICS_STEP(engine->i915, G11, STEP_A0, STEP_B0)) + wa_masked_en(wal, GEN9_HALF_SLICE_CHICKEN7, + DG2_DISABLE_ROUND_ENABLE_ALLOW_FOR_SSLA); + + if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0)) { + /* Wa_14010680813:dg2_g10 */ + wa_write_or(wal, GEN12_GAMSTLB_CTRL, CONTROL_BLOCK_CLKGATE_DIS | + EGRESS_BLOCK_CLKGATE_DIS | TAG_BLOCK_CLKGATE_DIS); + } + + if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0) || + IS_DG2_GRAPHICS_STEP(engine->i915, G11, STEP_A0, STEP_B0)) { + /* Wa_14012362059:dg2 */ + wa_write_or(wal, GEN12_MERT_MOD_CTRL, FORCE_MISS_FTLB); + } + if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) || IS_TGL_UY_GRAPHICS_STEP(i915, STEP_A0, STEP_B0)) { /* @@ -2568,6 +2573,53 @@ xcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) } } +/* + * The workarounds in this function apply to shared registers in + * the general render reset domain that aren't tied to a + * specific engine. Since all render+compute engines get reset + * together, and the contents of these registers are lost during + * the shared render domain reset, we'll define such workarounds + * here and then add them to just a single RCS or CCS engine's + * workaround list (whichever engine has the XXXX flag). + */ +static void +general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) +{ + struct drm_i915_private *i915 = engine->i915; + + if (IS_XEHPSDV(i915)) { + /* Wa_1409954639 */ + wa_masked_en(wal, + GEN8_ROW_CHICKEN, + SYSTOLIC_DOP_CLOCK_GATING_DIS); + + /* Wa_1607196519 */ + wa_masked_en(wal, + GEN9_ROW_CHICKEN4, + GEN12_DISABLE_GRF_CLEAR); + + /* Wa_14010670810:xehpsdv */ + wa_write_or(wal, XEHP_L3NODEARBCFG, XEHP_LNESPARE); + + /* Wa_14010449647:xehpsdv */ + wa_masked_en(wal, GEN7_HALF_SLICE_CHICKEN1, + GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE); + + /* Wa_18011725039:xehpsdv */ + if (IS_XEHPSDV_GRAPHICS_STEP(i915, STEP_A1, STEP_B0)) { + wa_masked_dis(wal, MLTICTXCTL, TDONRENDER); + wa_write_or(wal, L3SQCREG1_CCS0, FLUSHALLNONCOH); + } + + /* Wa_14012362059:xehpsdv */ + wa_write_or(wal, GEN12_MERT_MOD_CTRL, FORCE_MISS_FTLB); + + /* Wa_14014368820:xehpsdv */ + wa_write_or(wal, GEN12_GAMCNTRL_CTRL, INVALIDATION_BROADCAST_MODE_DIS | + GLOBAL_INVALIDATION_MODE); + } +} + static void engine_init_workarounds(struct intel_engine_cs *engine, struct i915_wa_list *wal) { @@ -2576,6 +2628,14 @@ engine_init_workarounds(struct intel_engine_cs *engine, struct i915_wa_list *wal engine_fake_wa_init(engine, wal); + /* + * These are common workarounds that just need to applied + * to a single RCS/CCS engine's workaround list since + * they're reset as part of the general render domain reset. + */ + if (engine->class == RENDER_CLASS) + general_render_compute_wa_init(engine, wal); + if (engine->class == RENDER_CLASS) rcs_engine_wa_init(engine, wal); else diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c index 0683b27a3890..402f085f3a02 100644 --- a/drivers/gpu/drm/i915/gt/shmem_utils.c +++ b/drivers/gpu/drm/i915/gt/shmem_utils.c @@ -3,6 +3,7 @@ * Copyright © 2020 Intel Corporation */ +#include <linux/iosys-map.h> #include <linux/mm.h> #include <linux/pagemap.h> #include <linux/shmem_fs.h> @@ -123,6 +124,37 @@ static int __shmem_rw(struct file *file, loff_t off, return 0; } +int shmem_read_to_iosys_map(struct file *file, loff_t off, + struct iosys_map *map, size_t map_off, size_t len) +{ + unsigned long pfn; + + for (pfn = off >> PAGE_SHIFT; len; pfn++) { + unsigned int this = + min_t(size_t, PAGE_SIZE - offset_in_page(off), len); + struct page *page; + void *vaddr; + + page = shmem_read_mapping_page_gfp(file->f_mapping, pfn, + GFP_KERNEL); + if (IS_ERR(page)) + return PTR_ERR(page); + + vaddr = kmap(page); + iosys_map_memcpy_to(map, map_off, vaddr + offset_in_page(off), + this); + mark_page_accessed(page); + kunmap(page); + put_page(page); + + len -= this; + map_off += this; + off = 0; + } + + return 0; +} + int shmem_read(struct file *file, loff_t off, void *dst, size_t len) { return __shmem_rw(file, off, dst, len, false); diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.h b/drivers/gpu/drm/i915/gt/shmem_utils.h index c1669170c351..b2b04d88c6e5 100644 --- a/drivers/gpu/drm/i915/gt/shmem_utils.h +++ b/drivers/gpu/drm/i915/gt/shmem_utils.h @@ -8,6 +8,7 @@ #include <linux/types.h> +struct iosys_map; struct drm_i915_gem_object; struct file; @@ -17,6 +18,8 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj); void *shmem_pin_map(struct file *file); void shmem_unpin_map(struct file *file, void *ptr); +int shmem_read_to_iosys_map(struct file *file, loff_t off, + struct iosys_map *map, size_t map_off, size_t len); int shmem_read(struct file *file, loff_t off, void *dst, size_t len); int shmem_write(struct file *file, loff_t off, void *src, size_t len); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h index 9d779de16613..bf7079480d47 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -6,8 +6,9 @@ #ifndef _INTEL_GUC_H_ #define _INTEL_GUC_H_ -#include <linux/xarray.h> #include <linux/delay.h> +#include <linux/iosys-map.h> +#include <linux/xarray.h> #include "intel_uncore.h" #include "intel_guc_fw.h" @@ -146,8 +147,8 @@ struct intel_guc { /** @ads_vma: object allocated to hold the GuC ADS */ struct i915_vma *ads_vma; - /** @ads_blob: contents of the GuC ADS */ - struct __guc_ads_blob *ads_blob; + /** @ads_map: contents of the GuC ADS */ + struct iosys_map ads_map; /** @ads_regset_size: size of the save/restore regsets in the ADS */ u32 ads_regset_size; /** diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c index 7e41175618f5..9bb551b83e7a 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -60,6 +60,19 @@ struct __guc_ads_blob { struct guc_mmio_reg regset[0]; } __packed; +#define ads_blob_read(guc_, field_) \ + iosys_map_rd_field(&(guc_)->ads_map, 0, struct __guc_ads_blob, field_) + +#define ads_blob_write(guc_, field_, val_) \ + iosys_map_wr_field(&(guc_)->ads_map, 0, struct __guc_ads_blob, \ + field_, val_) + +#define info_map_write(map_, field_, val_) \ + iosys_map_wr_field(map_, 0, struct guc_gt_system_info, field_, val_) + +#define info_map_read(map_, field_) \ + iosys_map_rd_field(map_, 0, struct guc_gt_system_info, field_) + static u32 guc_ads_regset_size(struct intel_guc *guc) { GEM_BUG_ON(!guc->ads_regset_size); @@ -123,33 +136,37 @@ static u32 guc_ads_blob_size(struct intel_guc *guc) guc_ads_private_data_size(guc); } -static void guc_policies_init(struct intel_guc *guc, struct guc_policies *policies) +static void guc_policies_init(struct intel_guc *guc) { struct intel_gt *gt = guc_to_gt(guc); struct drm_i915_private *i915 = gt->i915; + u32 global_flags = 0; - policies->dpc_promote_time = GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US; - policies->max_num_work_items = GLOBAL_POLICY_MAX_NUM_WI; + ads_blob_write(guc, policies.dpc_promote_time, + GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US); + ads_blob_write(guc, policies.max_num_work_items, + GLOBAL_POLICY_MAX_NUM_WI); - policies->global_flags = 0; if (i915->params.reset < 2) - policies->global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET; + global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET; - policies->is_valid = 1; + ads_blob_write(guc, policies.global_flags, global_flags); + ads_blob_write(guc, policies.is_valid, 1); } void intel_guc_ads_print_policy_info(struct intel_guc *guc, struct drm_printer *dp) { - struct __guc_ads_blob *blob = guc->ads_blob; - - if (unlikely(!blob)) + if (unlikely(iosys_map_is_null(&guc->ads_map))) return; drm_printf(dp, "Global scheduling policies:\n"); - drm_printf(dp, " DPC promote time = %u\n", blob->policies.dpc_promote_time); - drm_printf(dp, " Max num work items = %u\n", blob->policies.max_num_work_items); - drm_printf(dp, " Flags = %u\n", blob->policies.global_flags); + drm_printf(dp, " DPC promote time = %u\n", + ads_blob_read(guc, policies.dpc_promote_time)); + drm_printf(dp, " Max num work items = %u\n", + ads_blob_read(guc, policies.max_num_work_items)); + drm_printf(dp, " Flags = %u\n", + ads_blob_read(guc, policies.global_flags)); } static int guc_action_policies_update(struct intel_guc *guc, u32 policy_offset) @@ -164,29 +181,30 @@ static int guc_action_policies_update(struct intel_guc *guc, u32 policy_offset) int intel_guc_global_policies_update(struct intel_guc *guc) { - struct __guc_ads_blob *blob = guc->ads_blob; struct intel_gt *gt = guc_to_gt(guc); + u32 scheduler_policies; intel_wakeref_t wakeref; int ret; - if (!blob) + if (iosys_map_is_null(&guc->ads_map)) return -EOPNOTSUPP; - GEM_BUG_ON(!blob->ads.scheduler_policies); + scheduler_policies = ads_blob_read(guc, ads.scheduler_policies); + GEM_BUG_ON(!scheduler_policies); - guc_policies_init(guc, &blob->policies); + guc_policies_init(guc); if (!intel_guc_is_ready(guc)) return 0; with_intel_runtime_pm(>->i915->runtime_pm, wakeref) - ret = guc_action_policies_update(guc, blob->ads.scheduler_policies); + ret = guc_action_policies_update(guc, scheduler_policies); return ret; } static void guc_mapping_table_init(struct intel_gt *gt, - struct guc_gt_system_info *system_info) + struct iosys_map *info_map) { unsigned int i, j; struct intel_engine_cs *engine; @@ -195,14 +213,14 @@ static void guc_mapping_table_init(struct intel_gt *gt, /* Table must be set to invalid values for entries not used */ for (i = 0; i < GUC_MAX_ENGINE_CLASSES; ++i) for (j = 0; j < GUC_MAX_INSTANCES_PER_CLASS; ++j) - system_info->mapping_table[i][j] = - GUC_MAX_INSTANCES_PER_CLASS; + info_map_write(info_map, mapping_table[i][j], + GUC_MAX_INSTANCES_PER_CLASS); for_each_engine(engine, gt, id) { u8 guc_class = engine_class_to_guc_class(engine->class); - system_info->mapping_table[guc_class][ilog2(engine->logical_mask)] = - engine->instance; + info_map_write(info_map, mapping_table[guc_class][ilog2(engine->logical_mask)], + engine->instance); } } @@ -317,6 +335,10 @@ static int guc_mmio_regset_init(struct temp_regset *regset, ret |= GUC_MMIO_REG_ADD(regset, RING_HWS_PGA(base), false); ret |= GUC_MMIO_REG_ADD(regset, RING_IMR(base), false); + if (engine->class == RENDER_CLASS && + CCS_MASK(engine->gt)) + ret |= GUC_MMIO_REG_ADD(regset, GEN12_RCU_MODE, true); + for (i = 0, wa = wal->list; i < wal->count; i++, wa++) ret |= GUC_MMIO_REG_ADD(regset, wa->reg, wa->masked_reg); @@ -365,64 +387,69 @@ fail_regset_init: return ret; } -static void guc_mmio_reg_state_init(struct intel_guc *guc, - struct __guc_ads_blob *blob) +static void guc_mmio_reg_state_init(struct intel_guc *guc) { struct intel_gt *gt = guc_to_gt(guc); struct intel_engine_cs *engine; - struct guc_mmio_reg *ads_registers; enum intel_engine_id id; u32 addr_ggtt, offset; offset = guc_ads_regset_offset(guc); addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset; - ads_registers = (struct guc_mmio_reg *)(((u8 *)blob) + offset); - memcpy(ads_registers, guc->ads_regset, guc->ads_regset_size); + iosys_map_memcpy_to(&guc->ads_map, offset, guc->ads_regset, + guc->ads_regset_size); for_each_engine(engine, gt, id) { u32 count = guc->ads_regset_count[id]; - struct guc_mmio_reg_set *ads_reg_set; u8 guc_class; /* Class index is checked in class converter */ GEM_BUG_ON(engine->instance >= GUC_MAX_INSTANCES_PER_CLASS); guc_class = engine_class_to_guc_class(engine->class); - ads_reg_set = &blob->ads.reg_state_list[guc_class][engine->instance]; if (!count) { - ads_reg_set->address = 0; - ads_reg_set->count = 0; + ads_blob_write(guc, + ads.reg_state_list[guc_class][engine->instance].address, + 0); + ads_blob_write(guc, + ads.reg_state_list[guc_class][engine->instance].count, + 0); continue; } - ads_reg_set->address = addr_ggtt; - ads_reg_set->count = count; + ads_blob_write(guc, + ads.reg_state_list[guc_class][engine->instance].address, + addr_ggtt); + ads_blob_write(guc, + ads.reg_state_list[guc_class][engine->instance].count, + count); addr_ggtt += count * sizeof(struct guc_mmio_reg); } } static void fill_engine_enable_masks(struct intel_gt *gt, - struct guc_gt_system_info *info) + struct iosys_map *info_map) { - info->engine_enabled_masks[GUC_RENDER_CLASS] = 1; - info->engine_enabled_masks[GUC_BLITTER_CLASS] = 1; - info->engine_enabled_masks[GUC_VIDEO_CLASS] = VDBOX_MASK(gt); - info->engine_enabled_masks[GUC_VIDEOENHANCE_CLASS] = VEBOX_MASK(gt); + info_map_write(info_map, engine_enabled_masks[GUC_RENDER_CLASS], 1); + info_map_write(info_map, engine_enabled_masks[GUC_COMPUTE_CLASS], CCS_MASK(gt)); + info_map_write(info_map, engine_enabled_masks[GUC_BLITTER_CLASS], 1); + info_map_write(info_map, engine_enabled_masks[GUC_VIDEO_CLASS], VDBOX_MASK(gt)); + info_map_write(info_map, engine_enabled_masks[GUC_VIDEOENHANCE_CLASS], VEBOX_MASK(gt)); } #define LR_HW_CONTEXT_SIZE (80 * sizeof(u32)) #define LRC_SKIP_SIZE (LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE) -static int guc_prep_golden_context(struct intel_guc *guc, - struct __guc_ads_blob *blob) +static int guc_prep_golden_context(struct intel_guc *guc) { struct intel_gt *gt = guc_to_gt(guc); u32 addr_ggtt, offset; u32 total_size = 0, alloc_size, real_size; u8 engine_class, guc_class; - struct guc_gt_system_info *info, local_info; + struct guc_gt_system_info local_info; + struct iosys_map info_map; /* * Reserve the memory for the golden contexts and point GuC at it but @@ -436,14 +463,15 @@ static int guc_prep_golden_context(struct intel_guc *guc, * GuC will also validate that the LRC base + size fall within the * allowed GGTT range. */ - if (blob) { + if (!iosys_map_is_null(&guc->ads_map)) { offset = guc_ads_golden_ctxt_offset(guc); addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset; - info = &blob->system_info; + info_map = IOSYS_MAP_INIT_OFFSET(&guc->ads_map, + offsetof(struct __guc_ads_blob, system_info)); } else { memset(&local_info, 0, sizeof(local_info)); - info = &local_info; - fill_engine_enable_masks(gt, info); + iosys_map_set_vaddr(&info_map, &local_info); + fill_engine_enable_masks(gt, &info_map); } for (engine_class = 0; engine_class <= MAX_ENGINE_CLASS; ++engine_class) { @@ -452,14 +480,14 @@ static int guc_prep_golden_context(struct intel_guc *guc, guc_class = engine_class_to_guc_class(engine_class); - if (!info->engine_enabled_masks[guc_class]) + if (!info_map_read(&info_map, engine_enabled_masks[guc_class])) continue; real_size = intel_engine_context_size(gt, engine_class); alloc_size = PAGE_ALIGN(real_size); total_size += alloc_size; - if (!blob) + if (iosys_map_is_null(&guc->ads_map)) continue; /* @@ -473,15 +501,18 @@ static int guc_prep_golden_context(struct intel_guc *guc, * what comes before it in the context image (which is identical * on all engines). */ - blob->ads.eng_state_size[guc_class] = real_size - LRC_SKIP_SIZE; - blob->ads.golden_context_lrca[guc_class] = addr_ggtt; + ads_blob_write(guc, ads.eng_state_size[guc_class], + real_size - LRC_SKIP_SIZE); + ads_blob_write(guc, ads.golden_context_lrca[guc_class], + addr_ggtt); + addr_ggtt += alloc_size; } - if (!blob) - return total_size; + /* Make sure current size matches what we calculated previously */ + if (guc->ads_golden_ctxt_size) + GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size); - GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size); return total_size; } @@ -505,18 +536,16 @@ static struct intel_engine_cs *find_engine_state(struct intel_gt *gt, u8 engine_ static void guc_init_golden_context(struct intel_guc *guc) { - struct __guc_ads_blob *blob = guc->ads_blob; struct intel_engine_cs *engine; struct intel_gt *gt = guc_to_gt(guc); - u32 addr_ggtt, offset; - u32 total_size = 0, alloc_size, real_size; + unsigned long offset; + u32 addr_ggtt, total_size = 0, alloc_size, real_size; u8 engine_class, guc_class; - u8 *ptr; if (!intel_uc_uses_guc_submission(>->uc)) return; - GEM_BUG_ON(!blob); + GEM_BUG_ON(iosys_map_is_null(&guc->ads_map)); /* * Go back and fill in the golden context data now that it is @@ -524,15 +553,13 @@ static void guc_init_golden_context(struct intel_guc *guc) */ offset = guc_ads_golden_ctxt_offset(guc); addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset; - ptr = ((u8 *)blob) + offset; for (engine_class = 0; engine_class <= MAX_ENGINE_CLASS; ++engine_class) { if (engine_class == OTHER_CLASS) continue; guc_class = engine_class_to_guc_class(engine_class); - - if (!blob->system_info.engine_enabled_masks[guc_class]) + if (!ads_blob_read(guc, system_info.engine_enabled_masks[guc_class])) continue; real_size = intel_engine_context_size(gt, engine_class); @@ -543,24 +570,26 @@ static void guc_init_golden_context(struct intel_guc *guc) if (!engine) { drm_err(>->i915->drm, "No engine state recorded for class %d!\n", engine_class); - blob->ads.eng_state_size[guc_class] = 0; - blob->ads.golden_context_lrca[guc_class] = 0; + ads_blob_write(guc, ads.eng_state_size[guc_class], 0); + ads_blob_write(guc, ads.golden_context_lrca[guc_class], 0); continue; } - GEM_BUG_ON(blob->ads.eng_state_size[guc_class] != + GEM_BUG_ON(ads_blob_read(guc, ads.eng_state_size[guc_class]) != real_size - LRC_SKIP_SIZE); - GEM_BUG_ON(blob->ads.golden_context_lrca[guc_class] != addr_ggtt); + GEM_BUG_ON(ads_blob_read(guc, ads.golden_context_lrca[guc_class]) != addr_ggtt); + addr_ggtt += alloc_size; - shmem_read(engine->default_state, 0, ptr, real_size); - ptr += alloc_size; + shmem_read_to_iosys_map(engine->default_state, 0, &guc->ads_map, + offset, real_size); + offset += alloc_size; } GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size); } -static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *blob) +static void guc_capture_list_init(struct intel_guc *guc) { int i, j; u32 addr_ggtt, offset; @@ -572,11 +601,11 @@ static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob * for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) { for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) { - blob->ads.capture_instance[i][j] = addr_ggtt; - blob->ads.capture_class[i][j] = addr_ggtt; + ads_blob_write(guc, ads.capture_instance[i][j], addr_ggtt); + ads_blob_write(guc, ads.capture_class[i][j], addr_ggtt); } - blob->ads.capture_global[i] = addr_ggtt; + ads_blob_write(guc, ads.capture_global[i], addr_ggtt); } } @@ -584,47 +613,52 @@ static void __guc_ads_init(struct intel_guc *guc) { struct intel_gt *gt = guc_to_gt(guc); struct drm_i915_private *i915 = gt->i915; - struct __guc_ads_blob *blob = guc->ads_blob; + struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(&guc->ads_map, + offsetof(struct __guc_ads_blob, system_info)); u32 base; /* GuC scheduling policies */ - guc_policies_init(guc, &blob->policies); + guc_policies_init(guc); /* System info */ - fill_engine_enable_masks(gt, &blob->system_info); + fill_engine_enable_masks(gt, &info_map); - blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED] = - hweight8(gt->info.sseu.slice_mask); - blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK] = - gt->info.vdbox_sfc_access; + ads_blob_write(guc, system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED], + hweight8(gt->info.sseu.slice_mask)); + ads_blob_write(guc, system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK], + gt->info.vdbox_sfc_access); if (GRAPHICS_VER(i915) >= 12 && !IS_DGFX(i915)) { u32 distdbreg = intel_uncore_read(gt->uncore, GEN12_DIST_DBS_POPULATED); - blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI] = - ((distdbreg >> GEN12_DOORBELLS_PER_SQIDI_SHIFT) & - GEN12_DOORBELLS_PER_SQIDI) + 1; + ads_blob_write(guc, + system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI], + ((distdbreg >> GEN12_DOORBELLS_PER_SQIDI_SHIFT) + & GEN12_DOORBELLS_PER_SQIDI) + 1); } /* Golden contexts for re-initialising after a watchdog reset */ - guc_prep_golden_context(guc, blob); + guc_prep_golden_context(guc); - guc_mapping_table_init(guc_to_gt(guc), &blob->system_info); + guc_mapping_table_init(guc_to_gt(guc), &info_map); base = intel_guc_ggtt_offset(guc, guc->ads_vma); /* Capture list for hang debug */ - guc_capture_list_init(guc, blob); + guc_capture_list_init(guc); /* ADS */ - blob->ads.scheduler_policies = base + ptr_offset(blob, policies); - blob->ads.gt_system_info = base + ptr_offset(blob, system_info); + ads_blob_write(guc, ads.scheduler_policies, base + + offsetof(struct __guc_ads_blob, policies)); + ads_blob_write(guc, ads.gt_system_info, base + + offsetof(struct __guc_ads_blob, system_info)); /* MMIO save/restore list */ - guc_mmio_reg_state_init(guc, blob); + guc_mmio_reg_state_init(guc); /* Private Data */ - blob->ads.private_data = base + guc_ads_private_data_offset(guc); + ads_blob_write(guc, ads.private_data, base + + guc_ads_private_data_offset(guc)); i915_gem_object_flush_map(guc->ads_vma->obj); } @@ -638,6 +672,7 @@ static void __guc_ads_init(struct intel_guc *guc) */ int intel_guc_ads_create(struct intel_guc *guc) { + void *ads_blob; u32 size; int ret; @@ -653,7 +688,7 @@ int intel_guc_ads_create(struct intel_guc *guc) guc->ads_regset_size = ret; /* Likewise the golden contexts: */ - ret = guc_prep_golden_context(guc, NULL); + ret = guc_prep_golden_context(guc); if (ret < 0) return ret; guc->ads_golden_ctxt_size = ret; @@ -662,10 +697,15 @@ int intel_guc_ads_create(struct intel_guc *guc) size = guc_ads_blob_size(guc); ret = intel_guc_allocate_and_map_vma(guc, size, &guc->ads_vma, - (void **)&guc->ads_blob); + &ads_blob); if (ret) return ret; + if (i915_gem_object_is_lmem(guc->ads_vma->obj)) + iosys_map_set_vaddr_iomem(&guc->ads_map, (void __iomem *)ads_blob); + else + iosys_map_set_vaddr(&guc->ads_map, ads_blob); + __guc_ads_init(guc); return 0; @@ -686,7 +726,7 @@ void intel_guc_ads_init_late(struct intel_guc *guc) void intel_guc_ads_destroy(struct intel_guc *guc) { i915_vma_unpin_and_release(&guc->ads_vma, I915_VMA_RELEASE_MAP); - guc->ads_blob = NULL; + iosys_map_clear(&guc->ads_map); kfree(guc->ads_regset); } @@ -698,8 +738,8 @@ static void guc_ads_private_data_reset(struct intel_guc *guc) if (!size) return; - memset((void *)guc->ads_blob + guc_ads_private_data_offset(guc), 0, - size); + iosys_map_memset(&guc->ads_map, guc_ads_private_data_offset(guc), + 0, size); } /** @@ -722,18 +762,16 @@ void intel_guc_ads_reset(struct intel_guc *guc) u32 intel_guc_engine_usage_offset(struct intel_guc *guc) { - struct __guc_ads_blob *blob = guc->ads_blob; - u32 base = intel_guc_ggtt_offset(guc, guc->ads_vma); - u32 offset = base + ptr_offset(blob, engine_usage); - - return offset; + return intel_guc_ggtt_offset(guc, guc->ads_vma) + + offsetof(struct __guc_ads_blob, engine_usage); } -struct guc_engine_usage_record *intel_guc_engine_usage(struct intel_engine_cs *engine) +struct iosys_map intel_guc_engine_usage_record_map(struct intel_engine_cs *engine) { struct intel_guc *guc = &engine->gt->uc.guc; - struct __guc_ads_blob *blob = guc->ads_blob; u8 guc_class = engine_class_to_guc_class(engine->class); + size_t offset = offsetof(struct __guc_ads_blob, + engine_usage.engines[guc_class][ilog2(engine->logical_mask)]); - return &blob->engine_usage.engines[guc_class][ilog2(engine->logical_mask)]; + return IOSYS_MAP_INIT_OFFSET(&guc->ads_map, offset); } diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h index e74c110facff..1c64f4d6ea21 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h @@ -7,6 +7,7 @@ #define _INTEL_GUC_ADS_H_ #include <linux/types.h> +#include <linux/iosys-map.h> struct intel_guc; struct drm_printer; @@ -18,7 +19,7 @@ void intel_guc_ads_init_late(struct intel_guc *guc); void intel_guc_ads_reset(struct intel_guc *guc); void intel_guc_ads_print_policy_info(struct intel_guc *guc, struct drm_printer *p); -struct guc_engine_usage_record *intel_guc_engine_usage(struct intel_engine_cs *engine); +struct iosys_map intel_guc_engine_usage_record_map(struct intel_engine_cs *engine); u32 intel_guc_engine_usage_offset(struct intel_guc *guc); #endif diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h index 6a4612a852e2..4b300b6cc0f9 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h @@ -46,8 +46,8 @@ #define GUC_VIDEO_CLASS 1 #define GUC_VIDEOENHANCE_CLASS 2 #define GUC_BLITTER_CLASS 3 -#define GUC_RESERVED_CLASS 4 -#define GUC_LAST_ENGINE_CLASS GUC_RESERVED_CLASS +#define GUC_COMPUTE_CLASS 4 +#define GUC_LAST_ENGINE_CLASS GUC_COMPUTE_CLASS #define GUC_MAX_ENGINE_CLASSES 16 #define GUC_MAX_INSTANCES_PER_CLASS 32 @@ -156,23 +156,37 @@ FIELD_PREP(HOST2GUC_PC_SLPC_REQUEST_MSG_1_EVENT_ID, id) | \ FIELD_PREP(HOST2GUC_PC_SLPC_REQUEST_MSG_1_EVENT_ARGC, c) \ ) +/* the GuC arrays don't include OTHER_CLASS */ +static u8 engine_class_guc_class_map[] = { + [RENDER_CLASS] = GUC_RENDER_CLASS, + [COPY_ENGINE_CLASS] = GUC_BLITTER_CLASS, + [VIDEO_DECODE_CLASS] = GUC_VIDEO_CLASS, + [VIDEO_ENHANCEMENT_CLASS] = GUC_VIDEOENHANCE_CLASS, + [COMPUTE_CLASS] = GUC_COMPUTE_CLASS, +}; + +static u8 guc_class_engine_class_map[] = { + [GUC_RENDER_CLASS] = RENDER_CLASS, + [GUC_BLITTER_CLASS] = COPY_ENGINE_CLASS, + [GUC_VIDEO_CLASS] = VIDEO_DECODE_CLASS, + [GUC_VIDEOENHANCE_CLASS] = VIDEO_ENHANCEMENT_CLASS, + [GUC_COMPUTE_CLASS] = COMPUTE_CLASS, +}; + static inline u8 engine_class_to_guc_class(u8 class) { - BUILD_BUG_ON(GUC_RENDER_CLASS != RENDER_CLASS); - BUILD_BUG_ON(GUC_BLITTER_CLASS != COPY_ENGINE_CLASS); - BUILD_BUG_ON(GUC_VIDEO_CLASS != VIDEO_DECODE_CLASS); - BUILD_BUG_ON(GUC_VIDEOENHANCE_CLASS != VIDEO_ENHANCEMENT_CLASS); + BUILD_BUG_ON(ARRAY_SIZE(engine_class_guc_class_map) != MAX_ENGINE_CLASS + 1); GEM_BUG_ON(class > MAX_ENGINE_CLASS || class == OTHER_CLASS); - return class; + return engine_class_guc_class_map[class]; } static inline u8 guc_class_to_engine_class(u8 guc_class) { + BUILD_BUG_ON(ARRAY_SIZE(guc_class_engine_class_map) != GUC_LAST_ENGINE_CLASS + 1); GEM_BUG_ON(guc_class > GUC_LAST_ENGINE_CLASS); - GEM_BUG_ON(guc_class == GUC_RESERVED_CLASS); - return guc_class; + return guc_class_engine_class_map[guc_class]; } /* Work item for submitting workloads into work queue of GuC. */ diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index b3d28b003b73..ac749ab11035 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -11,6 +11,7 @@ #include "intel_mchbar_regs.h" #include "gt/intel_gt.h" #include "gt/intel_gt_regs.h" +#include "gt/intel_rps.h" static inline struct intel_guc *slpc_to_guc(struct intel_guc_slpc *slpc) { @@ -115,7 +116,7 @@ static int guc_action_slpc_unset_param(struct intel_guc *guc, u8 id) { u32 request[] = { GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST, - SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 2), + SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1), id, }; @@ -579,10 +580,10 @@ static int slpc_use_fused_rp0(struct intel_guc_slpc *slpc) static void slpc_get_rp_values(struct intel_guc_slpc *slpc) { + struct intel_rps *rps = &slpc_to_gt(slpc)->rps; u32 rp_state_cap; - rp_state_cap = intel_uncore_read(slpc_to_gt(slpc)->uncore, - GEN6_RP_STATE_CAP); + rp_state_cap = intel_rps_read_state_cap(rps); slpc->rp0_freq = REG_FIELD_GET(RP0_CAP_MASK, rp_state_cap) * GT_FREQUENCY_MULTIPLIER; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index b3a429a92c0d..1ce7e04aa837 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -174,11 +174,8 @@ static inline void init_sched_state(struct intel_context *ce) __maybe_unused static bool sched_state_is_init(struct intel_context *ce) { - /* - * XXX: Kernel contexts can have SCHED_STATE_NO_LOCK_REGISTERED after - * suspend. - */ - return !(ce->guc_state.sched_state &= + /* Kernel contexts can have SCHED_STATE_REGISTERED after suspend. */ + return !(ce->guc_state.sched_state & ~(SCHED_STATE_BLOCKED_MASK | SCHED_STATE_REGISTERED)); } @@ -1139,6 +1136,9 @@ __extend_last_switch(struct intel_guc *guc, u64 *prev_start, u32 new_start) *prev_start = ((u64)gt_stamp_hi << 32) | new_start; } +#define record_read(map_, field_) \ + iosys_map_rd_field(map_, 0, struct guc_engine_usage_record, field_) + /* * GuC updates shared memory and KMD reads it. Since this is not synchronized, * we run into a race where the value read is inconsistent. Sometimes the @@ -1153,17 +1153,17 @@ __extend_last_switch(struct intel_guc *guc, u64 *prev_start, u32 new_start) static void __get_engine_usage_record(struct intel_engine_cs *engine, u32 *last_in, u32 *id, u32 *total) { - struct guc_engine_usage_record *rec = intel_guc_engine_usage(engine); + struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine); int i = 0; do { - *last_in = READ_ONCE(rec->last_switch_in_stamp); - *id = READ_ONCE(rec->current_context_index); - *total = READ_ONCE(rec->total_runtime); + *last_in = record_read(&rec_map, last_switch_in_stamp); + *id = record_read(&rec_map, current_context_index); + *total = record_read(&rec_map, total_runtime); - if (READ_ONCE(rec->last_switch_in_stamp) == *last_in && - READ_ONCE(rec->current_context_index) == *id && - READ_ONCE(rec->total_runtime) == *total) + if (record_read(&rec_map, last_switch_in_stamp) == *last_in && + record_read(&rec_map, current_context_index) == *id && + record_read(&rec_map, total_runtime) == *total) break; } while (++i < 6); } @@ -1818,24 +1818,11 @@ int intel_guc_submission_init(struct intel_guc *guc) */ GEM_BUG_ON(!guc->lrc_desc_pool); - xa_init_flags(&guc->context_lookup, XA_FLAGS_LOCK_IRQ); - - spin_lock_init(&guc->submission_state.lock); - INIT_LIST_HEAD(&guc->submission_state.guc_id_list); - ida_init(&guc->submission_state.guc_ids); - INIT_LIST_HEAD(&guc->submission_state.destroyed_contexts); - INIT_WORK(&guc->submission_state.destroyed_worker, - destroyed_worker_func); - INIT_WORK(&guc->submission_state.reset_fail_worker, - reset_fail_worker_func); - guc->submission_state.guc_ids_bitmap = bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID(guc), GFP_KERNEL); if (!guc->submission_state.guc_ids_bitmap) return -ENOMEM; - spin_lock_init(&guc->timestamp.lock); - INIT_DELAYED_WORK(&guc->timestamp.work, guc_timestamp_ping); guc->timestamp.ping_delay = (POLL_TIME_CLKS / gt->clock_frequency + 1) * HZ; guc->timestamp.shift = gpm_timestamp_shift(gt); @@ -3608,6 +3595,9 @@ static int guc_resume(struct intel_engine_cs *engine) setup_hwsp(engine); start_engine(engine); + if (engine->class == RENDER_CLASS) + xehp_enable_ccs_engines(engine); + return 0; } @@ -3789,7 +3779,7 @@ int intel_guc_submission_setup(struct intel_engine_cs *engine) guc_default_irqs(engine); guc_init_breadcrumbs(engine); - if (engine->class == RENDER_CLASS) + if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) rcs_submission_override(engine); lrc_init_wa_ctx(engine); @@ -3831,6 +3821,20 @@ static bool __guc_submission_selected(struct intel_guc *guc) void intel_guc_submission_init_early(struct intel_guc *guc) { + xa_init_flags(&guc->context_lookup, XA_FLAGS_LOCK_IRQ); + + spin_lock_init(&guc->submission_state.lock); + INIT_LIST_HEAD(&guc->submission_state.guc_id_list); + ida_init(&guc->submission_state.guc_ids); + INIT_LIST_HEAD(&guc->submission_state.destroyed_contexts); + INIT_WORK(&guc->submission_state.destroyed_worker, + destroyed_worker_func); + INIT_WORK(&guc->submission_state.reset_fail_worker, + reset_fail_worker_func); + + spin_lock_init(&guc->timestamp.lock); + INIT_DELAYED_WORK(&guc->timestamp.work, guc_timestamp_ping); + guc->submission_state.num_guc_ids = GUC_MAX_LRC_DESCRIPTORS; guc->submission_supported = __guc_submission_supported(guc); guc->submission_selected = __guc_submission_selected(guc); @@ -4022,10 +4026,9 @@ static void guc_handle_context_reset(struct intel_guc *guc, capture_error_state(guc, ce); guc_context_replay(ce); } else { - drm_err(&guc_to_gt(guc)->i915->drm, - "Invalid GuC engine reset notificaion for 0x%04X on %s: banned = %d, blocked = %d", - ce->guc_id.id, ce->engine->name, intel_context_is_banned(ce), - context_blocked(ce)); + drm_info(&guc_to_gt(guc)->i915->drm, + "Ignoring context reset notification of banned context 0x%04X on %s", + ce->guc_id.id, ce->engine->name); } } diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c b/drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c index 1297ddbf7f88..812220a43df8 100644 --- a/drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c +++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c @@ -154,6 +154,10 @@ static int intel_guc_multi_lrc_basic(void *arg) int ret; for (class = 0; class < MAX_ENGINE_CLASS + 1; ++class) { + /* We don't support breadcrumb handshake on these classes */ + if (class == COMPUTE_CLASS || class == RENDER_CLASS) + continue; + ret = __intel_guc_multi_lrc_basic(gt, class); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 1c67ff735f18..62b3f332bbf5 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -835,21 +835,6 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!i915->params.nuclear_pageflip && match_info->graphics.ver < 5) i915->drm.driver_features &= ~DRIVER_ATOMIC; - /* - * Check if we support fake LMEM -- for now we only unleash this for - * the live selftests(test-and-exit). - */ -#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) - if (IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM)) { - if (GRAPHICS_VER(i915) >= 9 && i915_selftest.live < 0 && - i915->params.fake_lmem_start) { - mkwrite_device_info(i915)->memory_regions = - REGION_SMEM | REGION_LMEM | REGION_STOLEN_SMEM; - GEM_BUG_ON(!HAS_LMEM(i915)); - } - } -#endif - ret = pci_enable_device(pdev); if (ret) goto out_fini; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f600d1cb01b3..d134838b3458 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1147,11 +1147,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define IS_ICL_WITH_PORT_F(dev_priv) \ IS_SUBPLATFORM(dev_priv, INTEL_ICELAKE, INTEL_SUBPLATFORM_PORTF) -#define IS_TGL_U(dev_priv) \ - IS_SUBPLATFORM(dev_priv, INTEL_TIGERLAKE, INTEL_SUBPLATFORM_ULT) - -#define IS_TGL_Y(dev_priv) \ - IS_SUBPLATFORM(dev_priv, INTEL_TIGERLAKE, INTEL_SUBPLATFORM_ULX) +#define IS_TGL_UY(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_TIGERLAKE, INTEL_SUBPLATFORM_UY) #define IS_SKL_GRAPHICS_STEP(p, since, until) (IS_SKYLAKE(p) && IS_GRAPHICS_STEP(p, since, until)) @@ -1170,11 +1167,11 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, IS_DISPLAY_STEP(__i915, since, until)) #define IS_TGL_UY_GRAPHICS_STEP(__i915, since, until) \ - ((IS_TGL_U(__i915) || IS_TGL_Y(__i915)) && \ + (IS_TGL_UY(__i915) && \ IS_GRAPHICS_STEP(__i915, since, until)) #define IS_TGL_GRAPHICS_STEP(__i915, since, until) \ - (IS_TIGERLAKE(__i915) && !(IS_TGL_U(__i915) || IS_TGL_Y(__i915)) && \ + (IS_TIGERLAKE(__i915) && !IS_TGL_UY(__i915)) && \ IS_GRAPHICS_STEP(__i915, since, until)) #define IS_RKL_DISPLAY_STEP(p, since, until) \ @@ -1244,6 +1241,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, ENGINE_INSTANCES_MASK(gt, VCS0, I915_MAX_VCS) #define VEBOX_MASK(gt) \ ENGINE_INSTANCES_MASK(gt, VECS0, I915_MAX_VECS) +#define CCS_MASK(gt) \ + ENGINE_INSTANCES_MASK(gt, CCS0, I915_MAX_CCS) /* * The Gen7 cmdparser copies the scanned buffer to the ggtt for execution @@ -1340,17 +1339,28 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, /* * Set this flag, when platform requires 64K GTT page sizes or larger for - * device local memory access. Also this flag implies that we require or - * at least support the compact PT layout for the ppGTT when using the 64K - * GTT pages. + * device local memory access. */ #define HAS_64K_PAGES(dev_priv) (INTEL_INFO(dev_priv)->has_64k_pages) +/* + * Set this flag when platform doesn't allow both 64k pages and 4k pages in + * the same PT. this flag means we need to support compact PT layout for the + * ppGTT when using the 64K GTT pages. + */ +#define NEEDS_COMPACT_PT(dev_priv) (INTEL_INFO(dev_priv)->needs_compact_pt) + #define HAS_IPC(dev_priv) (INTEL_INFO(dev_priv)->display.has_ipc) #define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i)) #define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM) +/* + * Platform has the dedicated compression control state for each lmem surfaces + * stored in lmem to support the 3D and media compression formats. + */ +#define HAS_FLAT_CCS(dev_priv) (INTEL_INFO(dev_priv)->has_flat_ccs) + #define HAS_GT_UC(dev_priv) (INTEL_INFO(dev_priv)->has_gt_uc) #define HAS_POOLED_EU(dev_priv) (INTEL_INFO(dev_priv)->has_pooled_eu) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 525ae832aa9a..eea355c2fc28 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -195,11 +195,6 @@ i915_param_named(enable_gvt, bool, 0400, "Enable support for Intel GVT-g graphics virtualization host support(default:false)"); #endif -#if IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM) -i915_param_named_unsafe(fake_lmem_start, ulong, 0400, - "Fake LMEM start offset (default: 0)"); -#endif - #if CONFIG_DRM_I915_REQUEST_TIMEOUT i915_param_named_unsafe(request_timeout_ms, uint, 0600, "Default request/fence/batch buffer expiration timeout."); diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index c9d53ff910a0..c779a6f85c7e 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -72,7 +72,6 @@ struct drm_printer; param(int, fastboot, -1, 0600) \ param(int, enable_dpcd_backlight, -1, 0600) \ param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \ - param(unsigned long, fake_lmem_start, 0, IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM) ? 0400 : 0) \ param(unsigned int, request_timeout_ms, CONFIG_DRM_I915_REQUEST_TIMEOUT, CONFIG_DRM_I915_REQUEST_TIMEOUT ? 0600 : 0) \ /* leave bools at the end to not create holes */ \ param(bool, enable_hangcheck, true, 0600) \ diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 8246cbe9b01d..c32c0c6661c8 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -1005,6 +1005,7 @@ static const struct intel_device_info adl_p_info = { XE_HP_PAGE_SIZES, \ .dma_mask_size = 46, \ .has_64bit_reloc = 1, \ + .has_flat_ccs = 1, \ .has_global_mocs = 1, \ .has_gt_uc = 1, \ .has_llc = 1, \ @@ -1030,6 +1031,7 @@ static const struct intel_device_info xehpsdv_info = { PLATFORM(INTEL_XEHPSDV), .display = { }, .has_64k_pages = 1, + .needs_compact_pt = 1, .platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VECS1) | BIT(VECS2) | BIT(VECS3) | @@ -1049,6 +1051,7 @@ static const struct intel_device_info dg2_info = { PLATFORM(INTEL_DG2), .has_guc_deprivilege = 1, .has_64k_pages = 1, + .needs_compact_pt = 1, .platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VECS1) | diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 00fb40029f43..0a9c3fcc09b1 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -4374,6 +4374,10 @@ void i915_perf_init(struct drm_i915_private *i915) /* XXX const struct i915_perf_ops! */ + /* i915_perf is not enabled for DG2 yet */ + if (IS_DG2(i915)) + return; + perf->oa_formats = oa_formats; if (IS_HASWELL(i915)) { perf->ops.is_valid_b_counter_reg = gen7_is_valid_b_counter_addr; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2b8a3086ed35..4da10e131216 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -971,6 +971,10 @@ #define GEN11_VEBOX2_RING_BASE 0x1d8000 #define XEHP_VEBOX3_RING_BASE 0x1e8000 #define XEHP_VEBOX4_RING_BASE 0x1f8000 +#define GEN12_COMPUTE0_RING_BASE 0x1a000 +#define GEN12_COMPUTE1_RING_BASE 0x1c000 +#define GEN12_COMPUTE2_RING_BASE 0x1e000 +#define GEN12_COMPUTE3_RING_BASE 0x26000 #define BLT_RING_BASE 0x22000 @@ -8460,6 +8464,20 @@ enum skl_power_gate { #define SGGI_DIS REG_BIT(15) #define SGR_DIS REG_BIT(13) +#define XEHPSDV_FLAT_CCS_BASE_ADDR _MMIO(0x4910) +#define XEHPSDV_CCS_BASE_SHIFT 8 + +/* gamt regs */ +#define GEN8_L3_LRA_1_GPGPU _MMIO(0x4dd4) +#define GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_BDW 0x67F1427F /* max/min for LRA1/2 */ +#define GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_CHV 0x5FF101FF /* max/min for LRA1/2 */ +#define GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL 0x67F1427F /* " " */ +#define GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT 0x5FF101FF /* " " */ + +#define MMCD_MISC_CTRL _MMIO(0x4ddc) /* skl+ */ +#define MMCD_PCLA (1 << 31) +#define MMCD_HOTSPOT_EN (1 << 27) + #define _ICL_PHY_MISC_A 0x64C00 #define _ICL_PHY_MISC_B 0x64C04 #define _DG2_PHY_MISC_TC1 0x64C14 /* TC1="PHY E" but offset as if "PHY F" */ @@ -8823,12 +8841,6 @@ enum skl_power_gate { #define DSB_ENABLE (1 << 31) #define DSB_STATUS (1 << 0) -#define TGL_ROOT_DEVICE_ID 0x9A00 -#define TGL_ROOT_DEVICE_MASK 0xFF00 -#define TGL_ROOT_DEVICE_SKU_MASK 0xF -#define TGL_ROOT_DEVICE_SKU_ULX 0x2 -#define TGL_ROOT_DEVICE_SKU_ULT 0x4 - #define CLKREQ_POLICY _MMIO(0x101038) #define CLKREQ_POLICY_MEM_UP_OVRD REG_BIT(1) diff --git a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c index 76d5211c25eb..129f668f21ff 100644 --- a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c +++ b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c @@ -19,6 +19,9 @@ struct i915_ttm_buddy_manager { struct drm_buddy mm; struct list_head reserved; struct mutex lock; + unsigned long visible_size; + unsigned long visible_avail; + unsigned long visible_reserved; u64 default_page_size; }; @@ -79,7 +82,7 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man, lpfn = pages; } - if (size > mm->size) { + if (size > lpfn << PAGE_SHIFT) { err = -E2BIG; goto err_free_res; } @@ -87,6 +90,12 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man, n_pages = size >> ilog2(mm->chunk_size); mutex_lock(&bman->lock); + if (lpfn <= bman->visible_size && n_pages > bman->visible_avail) { + mutex_unlock(&bman->lock); + err = -ENOSPC; + goto err_free_res; + } + err = drm_buddy_alloc_blocks(mm, (u64)place->fpfn << PAGE_SHIFT, (u64)lpfn << PAGE_SHIFT, (u64)n_pages << PAGE_SHIFT, @@ -107,6 +116,38 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man, mutex_unlock(&bman->lock); } + if (lpfn <= bman->visible_size) { + bman_res->used_visible_size = bman_res->base.num_pages; + } else { + struct drm_buddy_block *block; + + list_for_each_entry(block, &bman_res->blocks, link) { + unsigned long start = + drm_buddy_block_offset(block) >> PAGE_SHIFT; + + if (start < bman->visible_size) { + unsigned long end = start + + (drm_buddy_block_size(mm, block) >> PAGE_SHIFT); + + bman_res->used_visible_size += + min(end, bman->visible_size) - start; + } + } + } + + if (bman_res->used_visible_size) { + mutex_lock(&bman->lock); + bman->visible_avail -= bman_res->used_visible_size; + mutex_unlock(&bman->lock); + } + + if (place->lpfn - place->fpfn == n_pages) + bman_res->base.start = place->fpfn; + else if (lpfn <= bman->visible_size) + bman_res->base.start = 0; + else + bman_res->base.start = bman->visible_size; + *res = &bman_res->base; return 0; @@ -128,6 +169,7 @@ static void i915_ttm_buddy_man_free(struct ttm_resource_manager *man, mutex_lock(&bman->lock); drm_buddy_free_list(&bman->mm, &bman_res->blocks); + bman->visible_avail += bman_res->used_visible_size; mutex_unlock(&bman->lock); ttm_resource_fini(man, res); @@ -143,6 +185,12 @@ static void i915_ttm_buddy_man_debug(struct ttm_resource_manager *man, mutex_lock(&bman->lock); drm_printf(printer, "default_page_size: %lluKiB\n", bman->default_page_size >> 10); + drm_printf(printer, "visible_avail: %lluMiB\n", + (u64)bman->visible_avail << PAGE_SHIFT >> 20); + drm_printf(printer, "visible_size: %lluMiB\n", + (u64)bman->visible_size << PAGE_SHIFT >> 20); + drm_printf(printer, "visible_reserved: %lluMiB\n", + (u64)bman->visible_reserved << PAGE_SHIFT >> 20); drm_buddy_print(&bman->mm, printer); @@ -164,6 +212,7 @@ static const struct ttm_resource_manager_func i915_ttm_buddy_manager_func = { * @type: Memory type we want to manage * @use_tt: Set use_tt for the manager * @size: The size in bytes to manage + * @visible_size: The CPU visible size in bytes to manage * @default_page_size: The default minimum page size in bytes for allocations, * this must be at least as large as @chunk_size, and can be overridden by * setting the BO page_alignment, to be larger or smaller as needed. @@ -187,7 +236,7 @@ static const struct ttm_resource_manager_func i915_ttm_buddy_manager_func = { */ int i915_ttm_buddy_man_init(struct ttm_device *bdev, unsigned int type, bool use_tt, - u64 size, u64 default_page_size, + u64 size, u64 visible_size, u64 default_page_size, u64 chunk_size) { struct ttm_resource_manager *man; @@ -206,6 +255,8 @@ int i915_ttm_buddy_man_init(struct ttm_device *bdev, INIT_LIST_HEAD(&bman->reserved); GEM_BUG_ON(default_page_size < chunk_size); bman->default_page_size = default_page_size; + bman->visible_size = visible_size >> PAGE_SHIFT; + bman->visible_avail = bman->visible_size; man = &bman->manager; man->use_tt = use_tt; @@ -250,6 +301,8 @@ int i915_ttm_buddy_man_fini(struct ttm_device *bdev, unsigned int type) mutex_lock(&bman->lock); drm_buddy_free_list(mm, &bman->reserved); drm_buddy_fini(mm); + bman->visible_avail += bman->visible_reserved; + WARN_ON_ONCE(bman->visible_avail != bman->visible_size); mutex_unlock(&bman->lock); ttm_resource_manager_cleanup(man); @@ -273,6 +326,7 @@ int i915_ttm_buddy_man_reserve(struct ttm_resource_manager *man, { struct i915_ttm_buddy_manager *bman = to_buddy_manager(man); struct drm_buddy *mm = &bman->mm; + unsigned long fpfn = start >> PAGE_SHIFT; unsigned long flags = 0; int ret; @@ -284,8 +338,37 @@ int i915_ttm_buddy_man_reserve(struct ttm_resource_manager *man, size, mm->chunk_size, &bman->reserved, flags); + + if (fpfn < bman->visible_size) { + unsigned long lpfn = fpfn + (size >> PAGE_SHIFT); + unsigned long visible = min(lpfn, bman->visible_size) - fpfn; + + bman->visible_reserved += visible; + bman->visible_avail -= visible; + } mutex_unlock(&bman->lock); return ret; } +/** + * i915_ttm_buddy_man_visible_size - Return the size of the CPU visible portion + * in pages. + * @man: The buddy allocator ttm manager + */ +u64 i915_ttm_buddy_man_visible_size(struct ttm_resource_manager *man) +{ + struct i915_ttm_buddy_manager *bman = to_buddy_manager(man); + + return bman->visible_size; +} + +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) +void i915_ttm_buddy_man_force_visible_size(struct ttm_resource_manager *man, + u64 size) +{ + struct i915_ttm_buddy_manager *bman = to_buddy_manager(man); + + bman->visible_size = size; +} +#endif diff --git a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.h b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.h index 72c90b432e87..52d9586d242c 100644 --- a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.h +++ b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.h @@ -21,6 +21,8 @@ struct drm_buddy; * @base: struct ttm_resource base class we extend * @blocks: the list of struct i915_buddy_block for this resource/allocation * @flags: DRM_BUDDY_*_ALLOCATION flags + * @used_visible_size: How much of this resource, if any, uses the CPU visible + * portion, in pages. * @mm: the struct i915_buddy_mm for this resource * * Extends the struct ttm_resource to manage an address space allocation with @@ -30,6 +32,7 @@ struct i915_ttm_buddy_resource { struct ttm_resource base; struct list_head blocks; unsigned long flags; + unsigned long used_visible_size; struct drm_buddy *mm; }; @@ -48,11 +51,19 @@ to_ttm_buddy_resource(struct ttm_resource *res) int i915_ttm_buddy_man_init(struct ttm_device *bdev, unsigned type, bool use_tt, - u64 size, u64 default_page_size, u64 chunk_size); + u64 size, u64 visible_size, + u64 default_page_size, u64 chunk_size); int i915_ttm_buddy_man_fini(struct ttm_device *bdev, unsigned int type); int i915_ttm_buddy_man_reserve(struct ttm_resource_manager *man, u64 start, u64 size); +u64 i915_ttm_buddy_man_visible_size(struct ttm_resource_manager *man); + +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) +void i915_ttm_buddy_man_force_visible_size(struct ttm_resource_manager *man, + u64 size); +#endif + #endif diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 845cd88f8313..94fcdb7bd21d 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -540,6 +540,9 @@ void __iomem *i915_vma_pin_iomap(struct i915_vma *vma) void __iomem *ptr; int err; + if (WARN_ON_ONCE(vma->obj->flags & I915_BO_ALLOC_GPU_ONLY)) + return IO_ERR_PTR(-EINVAL); + if (!i915_gem_object_is_lmem(vma->obj)) { if (GEM_WARN_ON(!i915_vma_is_map_and_fenceable(vma))) { err = -ENODEV; @@ -757,6 +760,14 @@ i915_vma_insert(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, end = min_t(u64, end, (1ULL << 32) - I915_GTT_PAGE_SIZE); GEM_BUG_ON(!IS_ALIGNED(end, I915_GTT_PAGE_SIZE)); + alignment = max(alignment, i915_vm_obj_min_alignment(vma->vm, vma->obj)); + /* + * for compact-pt we round up the reservation to prevent + * any smaller pages being used within the same PDE + */ + if (NEEDS_COMPACT_PT(vma->vm->i915)) + size = round_up(size, alignment); + /* If binding the object/GGTT view requires more space than the entire * aperture has, reject it early before evicting everything in a vain * attempt to find space. @@ -769,6 +780,7 @@ i915_vma_insert(struct i915_vma *vma, struct i915_gem_ww_ctx *ww, } color = 0; + if (i915_vm_has_cache_coloring(vma->vm)) color = vma->obj->cache_level; @@ -1609,15 +1621,27 @@ void i915_vma_reopen(struct i915_vma *vma) void i915_vma_release(struct kref *ref) { struct i915_vma *vma = container_of(ref, typeof(*vma), ref); + + i915_vm_put(vma->vm); + i915_active_fini(&vma->active); + GEM_WARN_ON(vma->resource); + i915_vma_free(vma); +} + +static void force_unbind(struct i915_vma *vma) +{ + if (!drm_mm_node_allocated(&vma->node)) + return; + + atomic_and(~I915_VMA_PIN_MASK, &vma->flags); + WARN_ON(__i915_vma_unbind(vma)); + GEM_BUG_ON(drm_mm_node_allocated(&vma->node)); +} + +static void release_references(struct i915_vma *vma) +{ struct drm_i915_gem_object *obj = vma->obj; - if (drm_mm_node_allocated(&vma->node)) { - mutex_lock(&vma->vm->mutex); - atomic_and(~I915_VMA_PIN_MASK, &vma->flags); - WARN_ON(__i915_vma_unbind(vma)); - mutex_unlock(&vma->vm->mutex); - GEM_BUG_ON(drm_mm_node_allocated(&vma->node)); - } GEM_BUG_ON(i915_vma_is_active(vma)); spin_lock(&obj->vma.lock); @@ -1627,11 +1651,49 @@ void i915_vma_release(struct kref *ref) spin_unlock(&obj->vma.lock); __i915_vma_remove_closed(vma); - i915_vm_put(vma->vm); - i915_active_fini(&vma->active); - GEM_WARN_ON(vma->resource); - i915_vma_free(vma); + __i915_vma_put(vma); +} + +/** + * i915_vma_destroy_locked - Remove all weak reference to the vma and put + * the initial reference. + * + * This function should be called when it's decided the vma isn't needed + * anymore. The caller must assure that it doesn't race with another lookup + * plus destroy, typically by taking an appropriate reference. + * + * Current callsites are + * - __i915_gem_object_pages_fini() + * - __i915_vm_close() - Blocks the above function by taking a reference on + * the object. + * - __i915_vma_parked() - Blocks the above functions by taking an open-count on + * the vm and a reference on the object. + * + * Because of locks taken during destruction, a vma is also guaranteed to + * stay alive while the following locks are held if it was looked up while + * holding one of the locks: + * - vm->mutex + * - obj->vma.lock + * - gt->closed_lock + * + * A vma user can also temporarily keep the vma alive while holding a vma + * reference. + */ +void i915_vma_destroy_locked(struct i915_vma *vma) +{ + lockdep_assert_held(&vma->vm->mutex); + + force_unbind(vma); + release_references(vma); +} + +void i915_vma_destroy(struct i915_vma *vma) +{ + mutex_lock(&vma->vm->mutex); + force_unbind(vma); + mutex_unlock(&vma->vm->mutex); + release_references(vma); } void i915_vma_parked(struct intel_gt *gt) @@ -1665,7 +1727,7 @@ void i915_vma_parked(struct intel_gt *gt) if (i915_gem_object_trylock(obj, NULL)) { INIT_LIST_HEAD(&vma->closed_link); - __i915_vma_put(vma); + i915_vma_destroy(vma); i915_gem_object_unlock(obj); } else { /* back you go.. */ diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 011af044ad4f..67ae7341c7e0 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -236,6 +236,9 @@ static inline void __i915_vma_put(struct i915_vma *vma) kref_put(&vma->ref, i915_vma_release); } +void i915_vma_destroy_locked(struct i915_vma *vma); +void i915_vma_destroy(struct i915_vma *vma); + #define assert_vma_held(vma) dma_resv_assert_held((vma)->obj->base.resv) static inline void i915_vma_lock(struct i915_vma *vma) diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 94da5aa37391..32c5f10e31db 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -170,6 +170,10 @@ static const u16 subplatform_portf_ids[] = { INTEL_ICL_PORT_F_IDS(0), }; +static const u16 subplatform_uy_ids[] = { + INTEL_TGL_12_GT2_IDS(0), +}; + static const u16 subplatform_n_ids[] = { INTEL_ADLN_IDS(0), }; @@ -214,6 +218,9 @@ void intel_device_info_subplatform_init(struct drm_i915_private *i915) } else if (find_devid(devid, subplatform_portf_ids, ARRAY_SIZE(subplatform_portf_ids))) { mask = BIT(INTEL_SUBPLATFORM_PORTF); + } else if (find_devid(devid, subplatform_uy_ids, + ARRAY_SIZE(subplatform_uy_ids))) { + mask = BIT(INTEL_SUBPLATFORM_UY); } else if (find_devid(devid, subplatform_n_ids, ARRAY_SIZE(subplatform_n_ids))) { mask = BIT(INTEL_SUBPLATFORM_N); @@ -222,25 +229,6 @@ void intel_device_info_subplatform_init(struct drm_i915_private *i915) mask = BIT(INTEL_SUBPLATFORM_RPL_S); } - if (IS_TIGERLAKE(i915)) { - struct pci_dev *root, *pdev = to_pci_dev(i915->drm.dev); - - root = list_first_entry(&pdev->bus->devices, typeof(*root), bus_list); - - drm_WARN_ON(&i915->drm, mask); - drm_WARN_ON(&i915->drm, (root->device & TGL_ROOT_DEVICE_MASK) != - TGL_ROOT_DEVICE_ID); - - switch (root->device & TGL_ROOT_DEVICE_SKU_MASK) { - case TGL_ROOT_DEVICE_SKU_ULX: - mask = BIT(INTEL_SUBPLATFORM_ULX); - break; - case TGL_ROOT_DEVICE_SKU_ULT: - mask = BIT(INTEL_SUBPLATFORM_ULT); - break; - } - } - GEM_BUG_ON(mask & ~INTEL_SUBPLATFORM_MASK); RUNTIME_INFO(i915)->platform_mask[pi] |= mask; diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 27dcfe6f2429..291215d9da28 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -106,6 +106,9 @@ enum intel_platform { /* ICL */ #define INTEL_SUBPLATFORM_PORTF (0) +/* TGL */ +#define INTEL_SUBPLATFORM_UY (0) + /* DG2 */ #define INTEL_SUBPLATFORM_G10 0 #define INTEL_SUBPLATFORM_G11 1 @@ -131,8 +134,10 @@ enum intel_ppgtt_type { /* Keep has_* in alphabetical order */ \ func(has_64bit_reloc); \ func(has_64k_pages); \ + func(needs_compact_pt); \ func(gpu_reset_clobbers_display); \ func(has_reset_engine); \ + func(has_flat_ccs); \ func(has_global_mocs); \ func(has_gt_uc); \ func(has_guc_deprivilege); \ diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index c70d7e286a51..1c841f68169a 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -97,10 +97,14 @@ static int iomemtest(struct intel_memory_region *mem, bool test_all, const void *caller) { - resource_size_t last = resource_size(&mem->region) - PAGE_SIZE; - resource_size_t page; + resource_size_t last, page; int err; + if (mem->io_size < PAGE_SIZE) + return 0; + + last = mem->io_size - PAGE_SIZE; + /* * Quick test to check read/write access to the iomap (backing store). * @@ -217,6 +221,7 @@ intel_memory_region_create(struct drm_i915_private *i915, resource_size_t size, resource_size_t min_page_size, resource_size_t io_start, + resource_size_t io_size, u16 type, u16 instance, const struct intel_memory_region_ops *ops) @@ -231,6 +236,7 @@ intel_memory_region_create(struct drm_i915_private *i915, mem->i915 = i915; mem->region = (struct resource)DEFINE_RES_MEM(start, size); mem->io_start = io_start; + mem->io_size = io_size; mem->min_page_size = min_page_size; mem->ops = ops; mem->total = size; diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h index 5625c9c38993..21dcbd620758 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.h +++ b/drivers/gpu/drm/i915/intel_memory_region.h @@ -67,10 +67,8 @@ struct intel_memory_region { struct io_mapping iomap; struct resource region; - /* For fake LMEM */ - struct drm_mm_node fake_mappable; - resource_size_t io_start; + resource_size_t io_size; resource_size_t min_page_size; resource_size_t total; resource_size_t avail; @@ -81,8 +79,6 @@ struct intel_memory_region { char name[16]; bool private; /* not for userspace */ - dma_addr_t remap_addr; - struct { struct mutex lock; /* Protects access to objects */ struct list_head list; @@ -103,6 +99,7 @@ intel_memory_region_create(struct drm_i915_private *i915, resource_size_t size, resource_size_t min_page_size, resource_size_t io_start, + resource_size_t io_size, u16 type, u16 instance, const struct intel_memory_region_ops *ops); diff --git a/drivers/gpu/drm/i915/intel_region_ttm.c b/drivers/gpu/drm/i915/intel_region_ttm.c index f2b888c16958..737ef3f4ab54 100644 --- a/drivers/gpu/drm/i915/intel_region_ttm.c +++ b/drivers/gpu/drm/i915/intel_region_ttm.c @@ -87,6 +87,7 @@ int intel_region_ttm_init(struct intel_memory_region *mem) ret = i915_ttm_buddy_man_init(bdev, mem_type, false, resource_size(&mem->region), + mem->io_size, mem->min_page_size, PAGE_SIZE); if (ret) return ret; @@ -199,12 +200,25 @@ intel_region_ttm_resource_alloc(struct intel_memory_region *mem, struct ttm_resource *res; int ret; + if (flags & I915_BO_ALLOC_CONTIGUOUS) + place.flags |= TTM_PL_FLAG_CONTIGUOUS; + if (mem->io_size && mem->io_size < mem->total) { + if (flags & I915_BO_ALLOC_GPU_ONLY) { + place.flags |= TTM_PL_FLAG_TOPDOWN; + } else { + place.fpfn = 0; + place.lpfn = mem->io_size >> PAGE_SHIFT; + } + } + mock_bo.base.size = size; - place.flags = flags; + mock_bo.bdev = &mem->i915->bdev; ret = man->func->alloc(man, &mock_bo, &place, &res); if (ret == -ENOSPC) ret = -ENXIO; + if (!ret) + res->bo = NULL; /* Rather blow up, then some uaf */ return ret ? ERR_PTR(ret) : res; } @@ -219,6 +233,11 @@ void intel_region_ttm_resource_free(struct intel_memory_region *mem, struct ttm_resource *res) { struct ttm_resource_manager *man = mem->region_private; + struct ttm_buffer_object mock_bo = {}; + + mock_bo.base.size = res->num_pages << PAGE_SHIFT; + mock_bo.bdev = &mem->i915->bdev; + res->bo = &mock_bo; man->func->free(man, res); } diff --git a/drivers/gpu/drm/i915/intel_step.c b/drivers/gpu/drm/i915/intel_step.c index ac1a796b2808..4fd69ecd1481 100644 --- a/drivers/gpu/drm/i915/intel_step.c +++ b/drivers/gpu/drm/i915/intel_step.c @@ -165,7 +165,7 @@ void intel_step_init(struct drm_i915_private *i915) } else if (IS_ROCKETLAKE(i915)) { revids = rkl_revids; size = ARRAY_SIZE(rkl_revids); - } else if (IS_TGL_U(i915) || IS_TGL_Y(i915)) { + } else if (IS_TGL_UY(i915)) { revids = tgl_uy_revids; size = ARRAY_SIZE(tgl_uy_revids); } else if (IS_TIGERLAKE(i915)) { diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index e7e6c4b2c81d..ab751192eb3b 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -27,9 +27,11 @@ #include "gem/i915_gem_context.h" #include "gem/i915_gem_internal.h" +#include "gem/i915_gem_region.h" #include "gem/selftests/mock_context.h" #include "gt/intel_context.h" #include "gt/intel_gpu_commands.h" +#include "gt/intel_gtt.h" #include "i915_random.h" #include "i915_selftest.h" @@ -239,6 +241,8 @@ static int lowlevel_hole(struct i915_address_space *vm, u64 hole_start, u64 hole_end, unsigned long end_time) { + const unsigned int min_alignment = + i915_vm_min_alignment(vm, INTEL_MEMORY_SYSTEM); I915_RND_STATE(seed_prng); struct i915_vma_resource *mock_vma_res; unsigned int size; @@ -252,9 +256,10 @@ static int lowlevel_hole(struct i915_address_space *vm, I915_RND_SUBSTATE(prng, seed_prng); struct drm_i915_gem_object *obj; unsigned int *order, count, n; - u64 hole_size; + u64 hole_size, aligned_size; - hole_size = (hole_end - hole_start) >> size; + aligned_size = max_t(u32, ilog2(min_alignment), size); + hole_size = (hole_end - hole_start) >> aligned_size; if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32)) hole_size = KMALLOC_MAX_SIZE / sizeof(u32); count = hole_size >> 1; @@ -275,8 +280,8 @@ static int lowlevel_hole(struct i915_address_space *vm, } GEM_BUG_ON(!order); - GEM_BUG_ON(count * BIT_ULL(size) > vm->total); - GEM_BUG_ON(hole_start + count * BIT_ULL(size) > hole_end); + GEM_BUG_ON(count * BIT_ULL(aligned_size) > vm->total); + GEM_BUG_ON(hole_start + count * BIT_ULL(aligned_size) > hole_end); /* Ignore allocation failures (i.e. don't report them as * a test failure) as we are purposefully allocating very @@ -299,10 +304,10 @@ static int lowlevel_hole(struct i915_address_space *vm, } for (n = 0; n < count; n++) { - u64 addr = hole_start + order[n] * BIT_ULL(size); + u64 addr = hole_start + order[n] * BIT_ULL(aligned_size); intel_wakeref_t wakeref; - GEM_BUG_ON(addr + BIT_ULL(size) > vm->total); + GEM_BUG_ON(addr + BIT_ULL(aligned_size) > vm->total); if (igt_timeout(end_time, "%s timed out before %d/%d\n", @@ -345,7 +350,7 @@ alloc_vm_end: } mock_vma_res->bi.pages = obj->mm.pages; - mock_vma_res->node_size = BIT_ULL(size); + mock_vma_res->node_size = BIT_ULL(aligned_size); mock_vma_res->start = addr; with_intel_runtime_pm(vm->gt->uncore->rpm, wakeref) @@ -356,7 +361,7 @@ alloc_vm_end: i915_random_reorder(order, count, &prng); for (n = 0; n < count; n++) { - u64 addr = hole_start + order[n] * BIT_ULL(size); + u64 addr = hole_start + order[n] * BIT_ULL(aligned_size); intel_wakeref_t wakeref; GEM_BUG_ON(addr + BIT_ULL(size) > vm->total); @@ -400,8 +405,10 @@ static int fill_hole(struct i915_address_space *vm, { const u64 hole_size = hole_end - hole_start; struct drm_i915_gem_object *obj; + const unsigned int min_alignment = + i915_vm_min_alignment(vm, INTEL_MEMORY_SYSTEM); const unsigned long max_pages = - min_t(u64, ULONG_MAX - 1, hole_size/2 >> PAGE_SHIFT); + min_t(u64, ULONG_MAX - 1, (hole_size / 2) >> ilog2(min_alignment)); const unsigned long max_step = max(int_sqrt(max_pages), 2UL); unsigned long npages, prime, flags; struct i915_vma *vma; @@ -442,14 +449,17 @@ static int fill_hole(struct i915_address_space *vm, offset = p->offset; list_for_each_entry(obj, &objects, st_link) { + u64 aligned_size = round_up(obj->base.size, + min_alignment); + vma = i915_vma_instance(obj, vm, NULL); if (IS_ERR(vma)) continue; if (p->step < 0) { - if (offset < hole_start + obj->base.size) + if (offset < hole_start + aligned_size) break; - offset -= obj->base.size; + offset -= aligned_size; } err = i915_vma_pin(vma, 0, 0, offset | flags); @@ -471,22 +481,25 @@ static int fill_hole(struct i915_address_space *vm, i915_vma_unpin(vma); if (p->step > 0) { - if (offset + obj->base.size > hole_end) + if (offset + aligned_size > hole_end) break; - offset += obj->base.size; + offset += aligned_size; } } offset = p->offset; list_for_each_entry(obj, &objects, st_link) { + u64 aligned_size = round_up(obj->base.size, + min_alignment); + vma = i915_vma_instance(obj, vm, NULL); if (IS_ERR(vma)) continue; if (p->step < 0) { - if (offset < hole_start + obj->base.size) + if (offset < hole_start + aligned_size) break; - offset -= obj->base.size; + offset -= aligned_size; } if (!drm_mm_node_allocated(&vma->node) || @@ -507,22 +520,25 @@ static int fill_hole(struct i915_address_space *vm, } if (p->step > 0) { - if (offset + obj->base.size > hole_end) + if (offset + aligned_size > hole_end) break; - offset += obj->base.size; + offset += aligned_size; } } offset = p->offset; list_for_each_entry_reverse(obj, &objects, st_link) { + u64 aligned_size = round_up(obj->base.size, + min_alignment); + vma = i915_vma_instance(obj, vm, NULL); if (IS_ERR(vma)) continue; if (p->step < 0) { - if (offset < hole_start + obj->base.size) + if (offset < hole_start + aligned_size) break; - offset -= obj->base.size; + offset -= aligned_size; } err = i915_vma_pin(vma, 0, 0, offset | flags); @@ -544,22 +560,25 @@ static int fill_hole(struct i915_address_space *vm, i915_vma_unpin(vma); if (p->step > 0) { - if (offset + obj->base.size > hole_end) + if (offset + aligned_size > hole_end) break; - offset += obj->base.size; + offset += aligned_size; } } offset = p->offset; list_for_each_entry_reverse(obj, &objects, st_link) { + u64 aligned_size = round_up(obj->base.size, + min_alignment); + vma = i915_vma_instance(obj, vm, NULL); if (IS_ERR(vma)) continue; if (p->step < 0) { - if (offset < hole_start + obj->base.size) + if (offset < hole_start + aligned_size) break; - offset -= obj->base.size; + offset -= aligned_size; } if (!drm_mm_node_allocated(&vma->node) || @@ -580,9 +599,9 @@ static int fill_hole(struct i915_address_space *vm, } if (p->step > 0) { - if (offset + obj->base.size > hole_end) + if (offset + aligned_size > hole_end) break; - offset += obj->base.size; + offset += aligned_size; } } } @@ -612,6 +631,7 @@ static int walk_hole(struct i915_address_space *vm, const u64 hole_size = hole_end - hole_start; const unsigned long max_pages = min_t(u64, ULONG_MAX - 1, hole_size >> PAGE_SHIFT); + unsigned long min_alignment; unsigned long flags; u64 size; @@ -621,6 +641,8 @@ static int walk_hole(struct i915_address_space *vm, if (i915_is_ggtt(vm)) flags |= PIN_GLOBAL; + min_alignment = i915_vm_min_alignment(vm, INTEL_MEMORY_SYSTEM); + for_each_prime_number_from(size, 1, max_pages) { struct drm_i915_gem_object *obj; struct i915_vma *vma; @@ -639,7 +661,7 @@ static int walk_hole(struct i915_address_space *vm, for (addr = hole_start; addr + obj->base.size < hole_end; - addr += obj->base.size) { + addr += round_up(obj->base.size, min_alignment)) { err = i915_vma_pin(vma, 0, 0, addr | flags); if (err) { pr_err("%s bind failed at %llx + %llx [hole %llx- %llx] with err=%d\n", @@ -691,6 +713,7 @@ static int pot_hole(struct i915_address_space *vm, { struct drm_i915_gem_object *obj; struct i915_vma *vma; + unsigned int min_alignment; unsigned long flags; unsigned int pot; int err = 0; @@ -699,6 +722,8 @@ static int pot_hole(struct i915_address_space *vm, if (i915_is_ggtt(vm)) flags |= PIN_GLOBAL; + min_alignment = i915_vm_min_alignment(vm, INTEL_MEMORY_SYSTEM); + obj = i915_gem_object_create_internal(vm->i915, 2 * I915_GTT_PAGE_SIZE); if (IS_ERR(obj)) return PTR_ERR(obj); @@ -711,13 +736,13 @@ static int pot_hole(struct i915_address_space *vm, /* Insert a pair of pages across every pot boundary within the hole */ for (pot = fls64(hole_end - 1) - 1; - pot > ilog2(2 * I915_GTT_PAGE_SIZE); + pot > ilog2(2 * min_alignment); pot--) { u64 step = BIT_ULL(pot); u64 addr; - for (addr = round_up(hole_start + I915_GTT_PAGE_SIZE, step) - I915_GTT_PAGE_SIZE; - addr <= round_down(hole_end - 2*I915_GTT_PAGE_SIZE, step) - I915_GTT_PAGE_SIZE; + for (addr = round_up(hole_start + min_alignment, step) - min_alignment; + addr <= round_down(hole_end - (2 * min_alignment), step) - min_alignment; addr += step) { err = i915_vma_pin(vma, 0, 0, addr | flags); if (err) { @@ -762,6 +787,7 @@ static int drunk_hole(struct i915_address_space *vm, unsigned long end_time) { I915_RND_STATE(prng); + unsigned int min_alignment; unsigned int size; unsigned long flags; @@ -769,15 +795,18 @@ static int drunk_hole(struct i915_address_space *vm, if (i915_is_ggtt(vm)) flags |= PIN_GLOBAL; + min_alignment = i915_vm_min_alignment(vm, INTEL_MEMORY_SYSTEM); + /* Keep creating larger objects until one cannot fit into the hole */ for (size = 12; (hole_end - hole_start) >> size; size++) { struct drm_i915_gem_object *obj; unsigned int *order, count, n; struct i915_vma *vma; - u64 hole_size; + u64 hole_size, aligned_size; int err = -ENODEV; - hole_size = (hole_end - hole_start) >> size; + aligned_size = max_t(u32, ilog2(min_alignment), size); + hole_size = (hole_end - hole_start) >> aligned_size; if (hole_size > KMALLOC_MAX_SIZE / sizeof(u32)) hole_size = KMALLOC_MAX_SIZE / sizeof(u32); count = hole_size >> 1; @@ -817,7 +846,7 @@ static int drunk_hole(struct i915_address_space *vm, GEM_BUG_ON(vma->size != BIT_ULL(size)); for (n = 0; n < count; n++) { - u64 addr = hole_start + order[n] * BIT_ULL(size); + u64 addr = hole_start + order[n] * BIT_ULL(aligned_size); err = i915_vma_pin(vma, 0, 0, addr | flags); if (err) { @@ -869,11 +898,14 @@ static int __shrink_hole(struct i915_address_space *vm, { struct drm_i915_gem_object *obj; unsigned long flags = PIN_OFFSET_FIXED | PIN_USER; + unsigned int min_alignment; unsigned int order = 12; LIST_HEAD(objects); int err = 0; u64 addr; + min_alignment = i915_vm_min_alignment(vm, INTEL_MEMORY_SYSTEM); + /* Keep creating larger objects until one cannot fit into the hole */ for (addr = hole_start; addr < hole_end; ) { struct i915_vma *vma; @@ -914,7 +946,7 @@ static int __shrink_hole(struct i915_address_space *vm, } i915_vma_unpin(vma); - addr += size; + addr += round_up(size, min_alignment); /* * Since we are injecting allocation faults at random intervals, @@ -1038,6 +1070,118 @@ err_purge: return err; } +static int misaligned_case(struct i915_address_space *vm, struct intel_memory_region *mr, + u64 addr, u64 size, unsigned long flags) +{ + struct drm_i915_gem_object *obj; + struct i915_vma *vma; + int err = 0; + u64 expected_vma_size, expected_node_size; + bool is_stolen = mr->type == INTEL_MEMORY_STOLEN_SYSTEM || + mr->type == INTEL_MEMORY_STOLEN_LOCAL; + + obj = i915_gem_object_create_region(mr, size, 0, 0); + if (IS_ERR(obj)) { + /* if iGVT-g or DMAR is active, stolen mem will be uninitialized */ + if (PTR_ERR(obj) == -ENODEV && is_stolen) + return 0; + return PTR_ERR(obj); + } + + vma = i915_vma_instance(obj, vm, NULL); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto err_put; + } + + err = i915_vma_pin(vma, 0, 0, addr | flags); + if (err) + goto err_put; + i915_vma_unpin(vma); + + if (!drm_mm_node_allocated(&vma->node)) { + err = -EINVAL; + goto err_put; + } + + if (i915_vma_misplaced(vma, 0, 0, addr | flags)) { + err = -EINVAL; + goto err_put; + } + + expected_vma_size = round_up(size, 1 << (ffs(vma->resource->page_sizes_gtt) - 1)); + expected_node_size = expected_vma_size; + + if (NEEDS_COMPACT_PT(vm->i915) && i915_gem_object_is_lmem(obj)) { + /* compact-pt should expand lmem node to 2MB */ + expected_vma_size = round_up(size, I915_GTT_PAGE_SIZE_64K); + expected_node_size = round_up(size, I915_GTT_PAGE_SIZE_2M); + } + + if (vma->size != expected_vma_size || vma->node.size != expected_node_size) { + err = i915_vma_unbind_unlocked(vma); + err = -EBADSLT; + goto err_put; + } + + err = i915_vma_unbind_unlocked(vma); + if (err) + goto err_put; + + GEM_BUG_ON(drm_mm_node_allocated(&vma->node)); + +err_put: + i915_gem_object_put(obj); + cleanup_freed_objects(vm->i915); + return err; +} + +static int misaligned_pin(struct i915_address_space *vm, + u64 hole_start, u64 hole_end, + unsigned long end_time) +{ + struct intel_memory_region *mr; + enum intel_region_id id; + unsigned long flags = PIN_OFFSET_FIXED | PIN_USER; + int err = 0; + u64 hole_size = hole_end - hole_start; + + if (i915_is_ggtt(vm)) + flags |= PIN_GLOBAL; + + for_each_memory_region(mr, vm->i915, id) { + u64 min_alignment = i915_vm_min_alignment(vm, (enum intel_memory_type)id); + u64 size = min_alignment; + u64 addr = round_down(hole_start + (hole_size / 2), min_alignment); + + /* avoid -ENOSPC on very small hole setups */ + if (hole_size < 3 * min_alignment) + continue; + + /* we can't test < 4k alignment due to flags being encoded in lower bits */ + if (min_alignment != I915_GTT_PAGE_SIZE_4K) { + err = misaligned_case(vm, mr, addr + (min_alignment / 2), size, flags); + /* misaligned should error with -EINVAL*/ + if (!err) + err = -EBADSLT; + if (err != -EINVAL) + return err; + } + + /* test for vma->size expansion to min page size */ + err = misaligned_case(vm, mr, addr, PAGE_SIZE, flags); + if (err) + return err; + + /* test for intermediate size not expanding vma->size for large alignments */ + err = misaligned_case(vm, mr, addr, size / 2, flags); + if (err) + return err; + } + + return 0; +} + static int exercise_ppgtt(struct drm_i915_private *dev_priv, int (*func)(struct i915_address_space *vm, u64 hole_start, u64 hole_end, @@ -1107,6 +1251,11 @@ static int igt_ppgtt_shrink_boom(void *arg) return exercise_ppgtt(arg, shrink_boom); } +static int igt_ppgtt_misaligned_pin(void *arg) +{ + return exercise_ppgtt(arg, misaligned_pin); +} + static int sort_holes(void *priv, const struct list_head *A, const struct list_head *B) { @@ -1179,6 +1328,11 @@ static int igt_ggtt_lowlevel(void *arg) return exercise_ggtt(arg, lowlevel_hole); } +static int igt_ggtt_misaligned_pin(void *arg) +{ + return exercise_ggtt(arg, misaligned_pin); +} + static int igt_ggtt_page(void *arg) { const unsigned int count = PAGE_SIZE/sizeof(u32); @@ -2151,12 +2305,14 @@ int i915_gem_gtt_live_selftests(struct drm_i915_private *i915) SUBTEST(igt_ppgtt_fill), SUBTEST(igt_ppgtt_shrink), SUBTEST(igt_ppgtt_shrink_boom), + SUBTEST(igt_ppgtt_misaligned_pin), SUBTEST(igt_ggtt_lowlevel), SUBTEST(igt_ggtt_drunk), SUBTEST(igt_ggtt_walk), SUBTEST(igt_ggtt_pot), SUBTEST(igt_ggtt_fill), SUBTEST(igt_ggtt_page), + SUBTEST(igt_ggtt_misaligned_pin), SUBTEST(igt_cs_tlb), }; diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c index 7acba1d2135e..ba32893e0873 100644 --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c @@ -17,6 +17,7 @@ #include "gem/i915_gem_context.h" #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_region.h" +#include "gem/i915_gem_ttm.h" #include "gem/selftests/igt_gem_utils.h" #include "gem/selftests/mock_context.h" #include "gt/intel_engine_pm.h" @@ -170,7 +171,7 @@ static int igt_mock_reserve(void *arg) if (!order) return 0; - mem = mock_region_create(i915, 0, SZ_2G, I915_GTT_PAGE_SIZE_4K, 0); + mem = mock_region_create(i915, 0, SZ_2G, I915_GTT_PAGE_SIZE_4K, 0, 0); if (IS_ERR(mem)) { pr_err("failed to create memory region\n"); err = PTR_ERR(mem); @@ -383,7 +384,7 @@ static int igt_mock_splintered_region(void *arg) */ size = (SZ_4G - 1) & PAGE_MASK; - mem = mock_region_create(i915, 0, size, PAGE_SIZE, 0); + mem = mock_region_create(i915, 0, size, PAGE_SIZE, 0, 0); if (IS_ERR(mem)) return PTR_ERR(mem); @@ -471,7 +472,7 @@ static int igt_mock_max_segment(void *arg) */ size = SZ_8G; - mem = mock_region_create(i915, 0, size, PAGE_SIZE, 0); + mem = mock_region_create(i915, 0, size, PAGE_SIZE, 0, 0); if (IS_ERR(mem)) return PTR_ERR(mem); @@ -512,6 +513,147 @@ out_put: return err; } +static u64 igt_object_mappable_total(struct drm_i915_gem_object *obj) +{ + struct intel_memory_region *mr = obj->mm.region; + struct i915_ttm_buddy_resource *bman_res = + to_ttm_buddy_resource(obj->mm.res); + struct drm_buddy *mm = bman_res->mm; + struct drm_buddy_block *block; + u64 total; + + total = 0; + list_for_each_entry(block, &bman_res->blocks, link) { + u64 start = drm_buddy_block_offset(block); + u64 end = start + drm_buddy_block_size(mm, block); + + if (start < mr->io_size) + total += min_t(u64, end, mr->io_size) - start; + } + + return total; +} + +static int igt_mock_io_size(void *arg) +{ + struct intel_memory_region *mr = arg; + struct drm_i915_private *i915 = mr->i915; + struct drm_i915_gem_object *obj; + u64 mappable_theft_total; + u64 io_size; + u64 total; + u64 ps; + u64 rem; + u64 size; + I915_RND_STATE(prng); + LIST_HEAD(objects); + int err = 0; + + ps = SZ_4K; + if (i915_prandom_u64_state(&prng) & 1) + ps = SZ_64K; /* For something like DG2 */ + + div64_u64_rem(i915_prandom_u64_state(&prng), SZ_8G, &total); + total = round_down(total, ps); + total = max_t(u64, total, SZ_1G); + + div64_u64_rem(i915_prandom_u64_state(&prng), total - ps, &io_size); + io_size = round_down(io_size, ps); + io_size = max_t(u64, io_size, SZ_256M); /* 256M seems to be the common lower limit */ + + pr_info("%s with ps=%llx, io_size=%llx, total=%llx\n", + __func__, ps, io_size, total); + + mr = mock_region_create(i915, 0, total, ps, 0, io_size); + if (IS_ERR(mr)) { + err = PTR_ERR(mr); + goto out_err; + } + + mappable_theft_total = 0; + rem = total - io_size; + do { + div64_u64_rem(i915_prandom_u64_state(&prng), rem, &size); + size = round_down(size, ps); + size = max(size, ps); + + obj = igt_object_create(mr, &objects, size, + I915_BO_ALLOC_GPU_ONLY); + if (IS_ERR(obj)) { + pr_err("%s TOPDOWN failed with rem=%llx, size=%llx\n", + __func__, rem, size); + err = PTR_ERR(obj); + goto out_close; + } + + mappable_theft_total += igt_object_mappable_total(obj); + rem -= size; + } while (rem); + + pr_info("%s mappable theft=(%lluMiB/%lluMiB), total=%lluMiB\n", + __func__, + (u64)mappable_theft_total >> 20, + (u64)io_size >> 20, + (u64)total >> 20); + + /* + * Even if we allocate all of the non-mappable portion, we should still + * be able to dip into the mappable portion. + */ + obj = igt_object_create(mr, &objects, io_size, + I915_BO_ALLOC_GPU_ONLY); + if (IS_ERR(obj)) { + pr_err("%s allocation unexpectedly failed\n", __func__); + err = PTR_ERR(obj); + goto out_close; + } + + close_objects(mr, &objects); + + rem = io_size; + do { + div64_u64_rem(i915_prandom_u64_state(&prng), rem, &size); + size = round_down(size, ps); + size = max(size, ps); + + obj = igt_object_create(mr, &objects, size, 0); + if (IS_ERR(obj)) { + pr_err("%s MAPPABLE failed with rem=%llx, size=%llx\n", + __func__, rem, size); + err = PTR_ERR(obj); + goto out_close; + } + + if (igt_object_mappable_total(obj) != size) { + pr_err("%s allocation is not mappable(size=%llx)\n", + __func__, size); + err = -EINVAL; + goto out_close; + } + rem -= size; + } while (rem); + + /* + * We assume CPU access is required by default, which should result in a + * failure here, even though the non-mappable portion is free. + */ + obj = igt_object_create(mr, &objects, ps, 0); + if (!IS_ERR(obj)) { + pr_err("%s allocation unexpectedly succeeded\n", __func__); + err = -EINVAL; + goto out_close; + } + +out_close: + close_objects(mr, &objects); + intel_memory_region_destroy(mr); +out_err: + if (err == -ENOMEM) + err = 0; + + return err; +} + static int igt_gpu_write_dw(struct intel_context *ce, struct i915_vma *vma, u32 dword, @@ -680,8 +822,14 @@ static int igt_lmem_create_with_ps(void *arg) i915_gem_object_lock(obj, NULL); err = i915_gem_object_pin_pages(obj); - if (err) + if (err) { + if (err == -ENXIO || err == -E2BIG || err == -ENOMEM) { + pr_info("%s not enough lmem for ps(%u) err=%d\n", + __func__, ps, err); + err = 0; + } goto out_put; + } daddr = i915_gem_object_get_dma_address(obj, 0); if (!IS_ALIGNED(daddr, ps)) { @@ -1179,6 +1327,7 @@ int intel_memory_region_mock_selftests(void) SUBTEST(igt_mock_contiguous), SUBTEST(igt_mock_splintered_region), SUBTEST(igt_mock_max_segment), + SUBTEST(igt_mock_io_size), }; struct intel_memory_region *mem; struct drm_i915_private *i915; @@ -1188,7 +1337,7 @@ int intel_memory_region_mock_selftests(void) if (!i915) return -ENOMEM; - mem = mock_region_create(i915, 0, SZ_2G, I915_GTT_PAGE_SIZE_4K, 0); + mem = mock_region_create(i915, 0, SZ_2G, I915_GTT_PAGE_SIZE_4K, 0, 0); if (IS_ERR(mem)) { pr_err("failed to create memory region\n"); err = PTR_ERR(mem); diff --git a/drivers/gpu/drm/i915/selftests/mock_region.c b/drivers/gpu/drm/i915/selftests/mock_region.c index 19bff8afcaaa..f64325491f35 100644 --- a/drivers/gpu/drm/i915/selftests/mock_region.c +++ b/drivers/gpu/drm/i915/selftests/mock_region.c @@ -22,17 +22,12 @@ static void mock_region_put_pages(struct drm_i915_gem_object *obj, static int mock_region_get_pages(struct drm_i915_gem_object *obj) { - unsigned int flags; struct sg_table *pages; int err; - flags = 0; - if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) - flags |= TTM_PL_FLAG_CONTIGUOUS; - obj->mm.res = intel_region_ttm_resource_alloc(obj->mm.region, obj->base.size, - flags); + obj->flags); if (IS_ERR(obj->mm.res)) return PTR_ERR(obj->mm.res); @@ -107,7 +102,8 @@ mock_region_create(struct drm_i915_private *i915, resource_size_t start, resource_size_t size, resource_size_t min_page_size, - resource_size_t io_start) + resource_size_t io_start, + resource_size_t io_size) { int instance = ida_alloc_max(&i915->selftest.mock_region_instances, TTM_NUM_MEM_TYPES - TTM_PL_PRIV - 1, @@ -117,6 +113,7 @@ mock_region_create(struct drm_i915_private *i915, return ERR_PTR(instance); return intel_memory_region_create(i915, start, size, min_page_size, - io_start, INTEL_MEMORY_MOCK, instance, + io_start, io_size, + INTEL_MEMORY_MOCK, instance, &mock_region_ops); } diff --git a/drivers/gpu/drm/i915/selftests/mock_region.h b/drivers/gpu/drm/i915/selftests/mock_region.h index 329bf74dfaca..e36c3a433551 100644 --- a/drivers/gpu/drm/i915/selftests/mock_region.h +++ b/drivers/gpu/drm/i915/selftests/mock_region.h @@ -16,6 +16,7 @@ mock_region_create(struct drm_i915_private *i915, resource_size_t start, resource_size_t size, resource_size_t min_page_size, - resource_size_t io_start); + resource_size_t io_start, + resource_size_t io_size); #endif /* !__MOCK_REGION_H */ diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 4fd931413705..c79502525963 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -34,15 +34,6 @@ config DRM_MSM_GPU_STATE depends on DRM_MSM && (DEBUG_FS || DEV_COREDUMP) default y -config DRM_MSM_REGISTER_LOGGING - bool "MSM DRM register logging" - depends on DRM_MSM - default n - help - Compile in support for logging register reads/writes in a format - that can be parsed by envytools demsm tool. If enabled, register - logging can be switched on via msm.reglog=y module param. - config DRM_MSM_GPU_SUDO bool "Enable SUDO flag on submits" depends on DRM_MSM && EXPERT diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 03ab55c37beb..e9cc7d8ac301 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -66,7 +66,6 @@ msm-y := \ disp/dpu1/dpu_hw_top.o \ disp/dpu1/dpu_hw_util.o \ disp/dpu1/dpu_hw_vbif.o \ - disp/dpu1/dpu_io_util.o \ disp/dpu1/dpu_kms.o \ disp/dpu1/dpu_mdss.o \ disp/dpu1/dpu_plane.o \ @@ -87,6 +86,7 @@ msm-y := \ msm_gem_vma.o \ msm_gpu.o \ msm_gpu_devfreq.o \ + msm_io_utils.o \ msm_iommu.o \ msm_perf.o \ msm_rd.o \ @@ -102,6 +102,7 @@ msm-$(CONFIG_DRM_MSM_GPU_STATE) += adreno/a6xx_gpu_state.o msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ dp/dp_catalog.o \ + dp/dp_clk_util.o \ dp/dp_ctrl.o \ dp/dp_display.o \ dp/dp_drm.o \ diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h index 4ff529576093..afa6023346c4 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a2xx.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-06-21 15:24:24) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14609 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 69086 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84231 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a4xx.xml ( 113358 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a5xx.xml ( 149512 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx.xml ( 184954 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-07-22 15:21:56) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c index 22e8295a5e2b..6c9a747eb4ad 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -471,6 +471,7 @@ static u32 a2xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, + .set_param = adreno_set_param, .hw_init = a2xx_hw_init, .pm_suspend = msm_gpu_pm_suspend, .pm_resume = msm_gpu_pm_resume, diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h b/drivers/gpu/drm/msm/adreno/a3xx.xml.h index e106b65abe26..520ae3f375a1 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a3xx.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-06-21 15:24:24) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14609 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 69086 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84231 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a4xx.xml ( 113358 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a5xx.xml ( 149512 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx.xml ( 184954 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-07-22 15:21:56) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) @@ -1466,7 +1466,7 @@ static inline uint32_t A3XX_RB_COPY_DEST_INFO_ENDIAN(enum adreno_rb_surface_endi #define REG_A3XX_RB_DEPTH_CONTROL 0x00002100 #define A3XX_RB_DEPTH_CONTROL_FRAG_WRITES_Z 0x00000001 -#define A3XX_RB_DEPTH_CONTROL_Z_ENABLE 0x00000002 +#define A3XX_RB_DEPTH_CONTROL_Z_TEST_ENABLE 0x00000002 #define A3XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE 0x00000004 #define A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE 0x00000008 #define A3XX_RB_DEPTH_CONTROL_ZFUNC__MASK 0x00000070 @@ -1476,7 +1476,7 @@ static inline uint32_t A3XX_RB_DEPTH_CONTROL_ZFUNC(enum adreno_compare_func val) return ((val) << A3XX_RB_DEPTH_CONTROL_ZFUNC__SHIFT) & A3XX_RB_DEPTH_CONTROL_ZFUNC__MASK; } #define A3XX_RB_DEPTH_CONTROL_Z_CLAMP_ENABLE 0x00000080 -#define A3XX_RB_DEPTH_CONTROL_Z_TEST_ENABLE 0x80000000 +#define A3XX_RB_DEPTH_CONTROL_Z_READ_ENABLE 0x80000000 #define REG_A3XX_RB_DEPTH_CLEAR 0x00002101 diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 2e481e2692ba..0ab0e1dd8bbb 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -486,6 +486,7 @@ static u32 a3xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, + .set_param = adreno_set_param, .hw_init = a3xx_hw_init, .pm_suspend = msm_gpu_pm_suspend, .pm_resume = msm_gpu_pm_resume, diff --git a/drivers/gpu/drm/msm/adreno/a4xx.xml.h b/drivers/gpu/drm/msm/adreno/a4xx.xml.h index b26ede96ae2a..7e5c21015d10 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a4xx.xml.h @@ -8,21 +8,21 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13) - -Copyright (C) 2013-2021 by the following authors: +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-06-21 15:24:24) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14609 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 69086 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84231 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a4xx.xml ( 113358 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a5xx.xml ( 149512 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx.xml ( 184954 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-07-22 15:21:56) + +Copyright (C) 2013-2022 by the following authors: - Rob Clark <[email protected]> (robclark) - Ilia Mirkin <[email protected]> (imirkin) @@ -837,6 +837,7 @@ enum a4xx_tex_type { A4XX_TEX_2D = 1, A4XX_TEX_CUBE = 2, A4XX_TEX_3D = 3, + A4XX_TEX_BUFFER = 4, }; #define A4XX_CGC_HLSQ_EARLY_CYC__MASK 0x00700000 @@ -1360,7 +1361,7 @@ static inline uint32_t A4XX_RB_FS_OUTPUT_REG_MRT(uint32_t val) #define REG_A4XX_RB_DEPTH_CONTROL 0x00002101 #define A4XX_RB_DEPTH_CONTROL_FRAG_WRITES_Z 0x00000001 -#define A4XX_RB_DEPTH_CONTROL_Z_ENABLE 0x00000002 +#define A4XX_RB_DEPTH_CONTROL_Z_TEST_ENABLE 0x00000002 #define A4XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE 0x00000004 #define A4XX_RB_DEPTH_CONTROL_ZFUNC__MASK 0x00000070 #define A4XX_RB_DEPTH_CONTROL_ZFUNC__SHIFT 4 @@ -1371,7 +1372,7 @@ static inline uint32_t A4XX_RB_DEPTH_CONTROL_ZFUNC(enum adreno_compare_func val) #define A4XX_RB_DEPTH_CONTROL_Z_CLAMP_ENABLE 0x00000080 #define A4XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE 0x00010000 #define A4XX_RB_DEPTH_CONTROL_FORCE_FRAGZ_TO_FS 0x00020000 -#define A4XX_RB_DEPTH_CONTROL_Z_TEST_ENABLE 0x80000000 +#define A4XX_RB_DEPTH_CONTROL_Z_READ_ENABLE 0x80000000 #define REG_A4XX_RB_DEPTH_CLEAR 0x00002102 @@ -2541,6 +2542,8 @@ static inline uint32_t A4XX_SP_FS_MRT_REG_REGID(uint32_t val) return ((val) << A4XX_SP_FS_MRT_REG_REGID__SHIFT) & A4XX_SP_FS_MRT_REG_REGID__MASK; } #define A4XX_SP_FS_MRT_REG_HALF_PRECISION 0x00000100 +#define A4XX_SP_FS_MRT_REG_COLOR_SINT 0x00000400 +#define A4XX_SP_FS_MRT_REG_COLOR_UINT 0x00000800 #define A4XX_SP_FS_MRT_REG_MRTFORMAT__MASK 0x0003f000 #define A4XX_SP_FS_MRT_REG_MRTFORMAT__SHIFT 12 static inline uint32_t A4XX_SP_FS_MRT_REG_MRTFORMAT(enum a4xx_color_fmt val) @@ -2550,6 +2553,40 @@ static inline uint32_t A4XX_SP_FS_MRT_REG_MRTFORMAT(enum a4xx_color_fmt val) #define A4XX_SP_FS_MRT_REG_COLOR_SRGB 0x00040000 #define REG_A4XX_SP_CS_CTRL_REG0 0x00002300 +#define A4XX_SP_CS_CTRL_REG0_THREADMODE__MASK 0x00000001 +#define A4XX_SP_CS_CTRL_REG0_THREADMODE__SHIFT 0 +static inline uint32_t A4XX_SP_CS_CTRL_REG0_THREADMODE(enum a3xx_threadmode val) +{ + return ((val) << A4XX_SP_CS_CTRL_REG0_THREADMODE__SHIFT) & A4XX_SP_CS_CTRL_REG0_THREADMODE__MASK; +} +#define A4XX_SP_CS_CTRL_REG0_VARYING 0x00000002 +#define A4XX_SP_CS_CTRL_REG0_CACHEINVALID 0x00000004 +#define A4XX_SP_CS_CTRL_REG0_HALFREGFOOTPRINT__MASK 0x000003f0 +#define A4XX_SP_CS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT 4 +static inline uint32_t A4XX_SP_CS_CTRL_REG0_HALFREGFOOTPRINT(uint32_t val) +{ + return ((val) << A4XX_SP_CS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT) & A4XX_SP_CS_CTRL_REG0_HALFREGFOOTPRINT__MASK; +} +#define A4XX_SP_CS_CTRL_REG0_FULLREGFOOTPRINT__MASK 0x0000fc00 +#define A4XX_SP_CS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT 10 +static inline uint32_t A4XX_SP_CS_CTRL_REG0_FULLREGFOOTPRINT(uint32_t val) +{ + return ((val) << A4XX_SP_CS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT) & A4XX_SP_CS_CTRL_REG0_FULLREGFOOTPRINT__MASK; +} +#define A4XX_SP_CS_CTRL_REG0_INOUTREGOVERLAP__MASK 0x000c0000 +#define A4XX_SP_CS_CTRL_REG0_INOUTREGOVERLAP__SHIFT 18 +static inline uint32_t A4XX_SP_CS_CTRL_REG0_INOUTREGOVERLAP(uint32_t val) +{ + return ((val) << A4XX_SP_CS_CTRL_REG0_INOUTREGOVERLAP__SHIFT) & A4XX_SP_CS_CTRL_REG0_INOUTREGOVERLAP__MASK; +} +#define A4XX_SP_CS_CTRL_REG0_THREADSIZE__MASK 0x00100000 +#define A4XX_SP_CS_CTRL_REG0_THREADSIZE__SHIFT 20 +static inline uint32_t A4XX_SP_CS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val) +{ + return ((val) << A4XX_SP_CS_CTRL_REG0_THREADSIZE__SHIFT) & A4XX_SP_CS_CTRL_REG0_THREADSIZE__MASK; +} +#define A4XX_SP_CS_CTRL_REG0_SUPERTHREADMODE 0x00200000 +#define A4XX_SP_CS_CTRL_REG0_PIXLODENABLE 0x00400000 #define REG_A4XX_SP_CS_OBJ_OFFSET_REG 0x00002301 @@ -3795,12 +3832,18 @@ static inline uint32_t A4XX_HLSQ_CL_NDRANGE_5_SIZE_Z(uint32_t val) #define REG_A4XX_HLSQ_CL_NDRANGE_6 0x000023d3 #define REG_A4XX_HLSQ_CL_CONTROL_0 0x000023d4 -#define A4XX_HLSQ_CL_CONTROL_0_WGIDCONSTID__MASK 0x000000ff +#define A4XX_HLSQ_CL_CONTROL_0_WGIDCONSTID__MASK 0x00000fff #define A4XX_HLSQ_CL_CONTROL_0_WGIDCONSTID__SHIFT 0 static inline uint32_t A4XX_HLSQ_CL_CONTROL_0_WGIDCONSTID(uint32_t val) { return ((val) << A4XX_HLSQ_CL_CONTROL_0_WGIDCONSTID__SHIFT) & A4XX_HLSQ_CL_CONTROL_0_WGIDCONSTID__MASK; } +#define A4XX_HLSQ_CL_CONTROL_0_KERNELDIMCONSTID__MASK 0x00fff000 +#define A4XX_HLSQ_CL_CONTROL_0_KERNELDIMCONSTID__SHIFT 12 +static inline uint32_t A4XX_HLSQ_CL_CONTROL_0_KERNELDIMCONSTID(uint32_t val) +{ + return ((val) << A4XX_HLSQ_CL_CONTROL_0_KERNELDIMCONSTID__SHIFT) & A4XX_HLSQ_CL_CONTROL_0_KERNELDIMCONSTID__MASK; +} #define A4XX_HLSQ_CL_CONTROL_0_LOCALIDREGID__MASK 0xff000000 #define A4XX_HLSQ_CL_CONTROL_0_LOCALIDREGID__SHIFT 24 static inline uint32_t A4XX_HLSQ_CL_CONTROL_0_LOCALIDREGID(uint32_t val) @@ -3809,8 +3852,32 @@ static inline uint32_t A4XX_HLSQ_CL_CONTROL_0_LOCALIDREGID(uint32_t val) } #define REG_A4XX_HLSQ_CL_CONTROL_1 0x000023d5 +#define A4XX_HLSQ_CL_CONTROL_1_UNK0CONSTID__MASK 0x00000fff +#define A4XX_HLSQ_CL_CONTROL_1_UNK0CONSTID__SHIFT 0 +static inline uint32_t A4XX_HLSQ_CL_CONTROL_1_UNK0CONSTID(uint32_t val) +{ + return ((val) << A4XX_HLSQ_CL_CONTROL_1_UNK0CONSTID__SHIFT) & A4XX_HLSQ_CL_CONTROL_1_UNK0CONSTID__MASK; +} +#define A4XX_HLSQ_CL_CONTROL_1_WORKGROUPSIZECONSTID__MASK 0x00fff000 +#define A4XX_HLSQ_CL_CONTROL_1_WORKGROUPSIZECONSTID__SHIFT 12 +static inline uint32_t A4XX_HLSQ_CL_CONTROL_1_WORKGROUPSIZECONSTID(uint32_t val) +{ + return ((val) << A4XX_HLSQ_CL_CONTROL_1_WORKGROUPSIZECONSTID__SHIFT) & A4XX_HLSQ_CL_CONTROL_1_WORKGROUPSIZECONSTID__MASK; +} #define REG_A4XX_HLSQ_CL_KERNEL_CONST 0x000023d6 +#define A4XX_HLSQ_CL_KERNEL_CONST_UNK0CONSTID__MASK 0x00000fff +#define A4XX_HLSQ_CL_KERNEL_CONST_UNK0CONSTID__SHIFT 0 +static inline uint32_t A4XX_HLSQ_CL_KERNEL_CONST_UNK0CONSTID(uint32_t val) +{ + return ((val) << A4XX_HLSQ_CL_KERNEL_CONST_UNK0CONSTID__SHIFT) & A4XX_HLSQ_CL_KERNEL_CONST_UNK0CONSTID__MASK; +} +#define A4XX_HLSQ_CL_KERNEL_CONST_NUMWGCONSTID__MASK 0x00fff000 +#define A4XX_HLSQ_CL_KERNEL_CONST_NUMWGCONSTID__SHIFT 12 +static inline uint32_t A4XX_HLSQ_CL_KERNEL_CONST_NUMWGCONSTID(uint32_t val) +{ + return ((val) << A4XX_HLSQ_CL_KERNEL_CONST_NUMWGCONSTID__SHIFT) & A4XX_HLSQ_CL_KERNEL_CONST_NUMWGCONSTID__MASK; +} #define REG_A4XX_HLSQ_CL_KERNEL_GROUP_X 0x000023d7 @@ -3819,6 +3886,12 @@ static inline uint32_t A4XX_HLSQ_CL_CONTROL_0_LOCALIDREGID(uint32_t val) #define REG_A4XX_HLSQ_CL_KERNEL_GROUP_Z 0x000023d9 #define REG_A4XX_HLSQ_CL_WG_OFFSET 0x000023da +#define A4XX_HLSQ_CL_WG_OFFSET_UNK0CONSTID__MASK 0x00000fff +#define A4XX_HLSQ_CL_WG_OFFSET_UNK0CONSTID__SHIFT 0 +static inline uint32_t A4XX_HLSQ_CL_WG_OFFSET_UNK0CONSTID(uint32_t val) +{ + return ((val) << A4XX_HLSQ_CL_WG_OFFSET_UNK0CONSTID__SHIFT) & A4XX_HLSQ_CL_WG_OFFSET_UNK0CONSTID__MASK; +} #define REG_A4XX_HLSQ_UPDATE_CONTROL 0x000023db @@ -4130,7 +4203,7 @@ static inline uint32_t A4XX_TEX_CONST_0_FMT(enum a4xx_tex_fmt val) { return ((val) << A4XX_TEX_CONST_0_FMT__SHIFT) & A4XX_TEX_CONST_0_FMT__MASK; } -#define A4XX_TEX_CONST_0_TYPE__MASK 0x60000000 +#define A4XX_TEX_CONST_0_TYPE__MASK 0xe0000000 #define A4XX_TEX_CONST_0_TYPE__SHIFT 29 static inline uint32_t A4XX_TEX_CONST_0_TYPE(enum a4xx_tex_type val) { @@ -4158,6 +4231,7 @@ static inline uint32_t A4XX_TEX_CONST_2_PITCHALIGN(uint32_t val) { return ((val) << A4XX_TEX_CONST_2_PITCHALIGN__SHIFT) & A4XX_TEX_CONST_2_PITCHALIGN__MASK; } +#define A4XX_TEX_CONST_2_BUFFER 0x00000040 #define A4XX_TEX_CONST_2_PITCH__MASK 0x3ffffe00 #define A4XX_TEX_CONST_2_PITCH__SHIFT 9 static inline uint32_t A4XX_TEX_CONST_2_PITCH(uint32_t val) diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index c5524d6e8705..0c6b2a6d0b4c 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -621,6 +621,7 @@ static u32 a4xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, + .set_param = adreno_set_param, .hw_init = a4xx_hw_init, .pm_suspend = a4xx_pm_suspend, .pm_resume = a4xx_pm_resume, diff --git a/drivers/gpu/drm/msm/adreno/a5xx.xml.h b/drivers/gpu/drm/msm/adreno/a5xx.xml.h index 1e575ca1f270..2505b4e43ca0 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a5xx.xml.h @@ -8,21 +8,21 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13) - -Copyright (C) 2013-2021 by the following authors: +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-06-21 15:24:24) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14609 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 69086 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84231 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a4xx.xml ( 113358 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a5xx.xml ( 149512 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx.xml ( 184954 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-07-22 15:21:56) + +Copyright (C) 2013-2022 by the following authors: - Rob Clark <[email protected]> (robclark) - Ilia Mirkin <[email protected]> (imirkin) @@ -872,6 +872,7 @@ enum a5xx_tex_type { A5XX_TEX_2D = 1, A5XX_TEX_CUBE = 2, A5XX_TEX_3D = 3, + A5XX_TEX_BUFFER = 4, }; #define A5XX_INT0_RBBM_GPU_IDLE 0x00000001 @@ -2830,7 +2831,9 @@ static inline uint32_t A5XX_GRAS_VS_CL_CNTL_CULL_MASK(uint32_t val) #define A5XX_GRAS_CNTL_IJ_PERSP_PIXEL 0x00000001 #define A5XX_GRAS_CNTL_IJ_PERSP_CENTROID 0x00000002 #define A5XX_GRAS_CNTL_IJ_PERSP_SAMPLE 0x00000004 -#define A5XX_GRAS_CNTL_SIZE 0x00000008 +#define A5XX_GRAS_CNTL_IJ_LINEAR_PIXEL 0x00000008 +#define A5XX_GRAS_CNTL_IJ_LINEAR_CENTROID 0x00000010 +#define A5XX_GRAS_CNTL_IJ_LINEAR_SAMPLE 0x00000020 #define A5XX_GRAS_CNTL_COORD_MASK__MASK 0x000003c0 #define A5XX_GRAS_CNTL_COORD_MASK__SHIFT 6 static inline uint32_t A5XX_GRAS_CNTL_COORD_MASK(uint32_t val) @@ -2911,7 +2914,12 @@ static inline uint32_t A5XX_GRAS_SU_CNTL_LINEHALFWIDTH(float val) return ((((int32_t)(val * 4.0))) << A5XX_GRAS_SU_CNTL_LINEHALFWIDTH__SHIFT) & A5XX_GRAS_SU_CNTL_LINEHALFWIDTH__MASK; } #define A5XX_GRAS_SU_CNTL_POLY_OFFSET 0x00000800 -#define A5XX_GRAS_SU_CNTL_MSAA_ENABLE 0x00002000 +#define A5XX_GRAS_SU_CNTL_LINE_MODE__MASK 0x00002000 +#define A5XX_GRAS_SU_CNTL_LINE_MODE__SHIFT 13 +static inline uint32_t A5XX_GRAS_SU_CNTL_LINE_MODE(enum a5xx_line_mode val) +{ + return ((val) << A5XX_GRAS_SU_CNTL_LINE_MODE__SHIFT) & A5XX_GRAS_SU_CNTL_LINE_MODE__MASK; +} #define REG_A5XX_GRAS_SU_POINT_MINMAX 0x0000e091 #define A5XX_GRAS_SU_POINT_MINMAX_MIN__MASK 0x0000ffff @@ -3166,7 +3174,9 @@ static inline uint32_t A5XX_RB_DEST_MSAA_CNTL_SAMPLES(enum a3xx_msaa_samples val #define A5XX_RB_RENDER_CONTROL0_IJ_PERSP_PIXEL 0x00000001 #define A5XX_RB_RENDER_CONTROL0_IJ_PERSP_CENTROID 0x00000002 #define A5XX_RB_RENDER_CONTROL0_IJ_PERSP_SAMPLE 0x00000004 -#define A5XX_RB_RENDER_CONTROL0_SIZE 0x00000008 +#define A5XX_RB_RENDER_CONTROL0_IJ_LINEAR_PIXEL 0x00000008 +#define A5XX_RB_RENDER_CONTROL0_IJ_LINEAR_CENTROID 0x00000010 +#define A5XX_RB_RENDER_CONTROL0_IJ_LINEAR_SAMPLE 0x00000020 #define A5XX_RB_RENDER_CONTROL0_COORD_MASK__MASK 0x000003c0 #define A5XX_RB_RENDER_CONTROL0_COORD_MASK__SHIFT 6 static inline uint32_t A5XX_RB_RENDER_CONTROL0_COORD_MASK(uint32_t val) @@ -3490,7 +3500,7 @@ static inline uint32_t A5XX_RB_BLEND_CNTL_SAMPLE_MASK(uint32_t val) #define A5XX_RB_DEPTH_PLANE_CNTL_UNK1 0x00000002 #define REG_A5XX_RB_DEPTH_CNTL 0x0000e1b1 -#define A5XX_RB_DEPTH_CNTL_Z_ENABLE 0x00000001 +#define A5XX_RB_DEPTH_CNTL_Z_TEST_ENABLE 0x00000001 #define A5XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE 0x00000002 #define A5XX_RB_DEPTH_CNTL_ZFUNC__MASK 0x0000001c #define A5XX_RB_DEPTH_CNTL_ZFUNC__SHIFT 2 @@ -3498,7 +3508,7 @@ static inline uint32_t A5XX_RB_DEPTH_CNTL_ZFUNC(enum adreno_compare_func val) { return ((val) << A5XX_RB_DEPTH_CNTL_ZFUNC__SHIFT) & A5XX_RB_DEPTH_CNTL_ZFUNC__MASK; } -#define A5XX_RB_DEPTH_CNTL_Z_TEST_ENABLE 0x00000040 +#define A5XX_RB_DEPTH_CNTL_Z_READ_ENABLE 0x00000040 #define REG_A5XX_RB_DEPTH_BUFFER_INFO 0x0000e1b2 #define A5XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT__MASK 0x00000007 @@ -5034,6 +5044,7 @@ static inline uint32_t A5XX_RB_2D_SRC_INFO_COLOR_SWAP(enum a3xx_color_swap val) return ((val) << A5XX_RB_2D_SRC_INFO_COLOR_SWAP__SHIFT) & A5XX_RB_2D_SRC_INFO_COLOR_SWAP__MASK; } #define A5XX_RB_2D_SRC_INFO_FLAGS 0x00001000 +#define A5XX_RB_2D_SRC_INFO_SRGB 0x00002000 #define REG_A5XX_RB_2D_SRC_LO 0x00002108 @@ -5073,6 +5084,7 @@ static inline uint32_t A5XX_RB_2D_DST_INFO_COLOR_SWAP(enum a3xx_color_swap val) return ((val) << A5XX_RB_2D_DST_INFO_COLOR_SWAP__SHIFT) & A5XX_RB_2D_DST_INFO_COLOR_SWAP__MASK; } #define A5XX_RB_2D_DST_INFO_FLAGS 0x00001000 +#define A5XX_RB_2D_DST_INFO_SRGB 0x00002000 #define REG_A5XX_RB_2D_DST_LO 0x00002111 @@ -5138,6 +5150,7 @@ static inline uint32_t A5XX_GRAS_2D_SRC_INFO_COLOR_SWAP(enum a3xx_color_swap val return ((val) << A5XX_GRAS_2D_SRC_INFO_COLOR_SWAP__SHIFT) & A5XX_GRAS_2D_SRC_INFO_COLOR_SWAP__MASK; } #define A5XX_GRAS_2D_SRC_INFO_FLAGS 0x00001000 +#define A5XX_GRAS_2D_SRC_INFO_SRGB 0x00002000 #define REG_A5XX_GRAS_2D_DST_INFO 0x00002182 #define A5XX_GRAS_2D_DST_INFO_COLOR_FORMAT__MASK 0x000000ff @@ -5159,10 +5172,7 @@ static inline uint32_t A5XX_GRAS_2D_DST_INFO_COLOR_SWAP(enum a3xx_color_swap val return ((val) << A5XX_GRAS_2D_DST_INFO_COLOR_SWAP__SHIFT) & A5XX_GRAS_2D_DST_INFO_COLOR_SWAP__MASK; } #define A5XX_GRAS_2D_DST_INFO_FLAGS 0x00001000 - -#define REG_A5XX_UNKNOWN_2100 0x00002100 - -#define REG_A5XX_UNKNOWN_2180 0x00002180 +#define A5XX_GRAS_2D_DST_INFO_SRGB 0x00002000 #define REG_A5XX_UNKNOWN_2184 0x00002184 @@ -5316,7 +5326,7 @@ static inline uint32_t A5XX_TEX_CONST_1_HEIGHT(uint32_t val) } #define REG_A5XX_TEX_CONST_2 0x00000002 -#define A5XX_TEX_CONST_2_UNK4 0x00000010 +#define A5XX_TEX_CONST_2_BUFFER 0x00000010 #define A5XX_TEX_CONST_2_PITCHALIGN__MASK 0x0000000f #define A5XX_TEX_CONST_2_PITCHALIGN__SHIFT 0 static inline uint32_t A5XX_TEX_CONST_2_PITCHALIGN(uint32_t val) @@ -5329,13 +5339,12 @@ static inline uint32_t A5XX_TEX_CONST_2_PITCH(uint32_t val) { return ((val) << A5XX_TEX_CONST_2_PITCH__SHIFT) & A5XX_TEX_CONST_2_PITCH__MASK; } -#define A5XX_TEX_CONST_2_TYPE__MASK 0x60000000 +#define A5XX_TEX_CONST_2_TYPE__MASK 0xe0000000 #define A5XX_TEX_CONST_2_TYPE__SHIFT 29 static inline uint32_t A5XX_TEX_CONST_2_TYPE(enum a5xx_tex_type val) { return ((val) << A5XX_TEX_CONST_2_TYPE__SHIFT) & A5XX_TEX_CONST_2_TYPE__MASK; } -#define A5XX_TEX_CONST_2_UNK31 0x80000000 #define REG_A5XX_TEX_CONST_3 0x00000003 #define A5XX_TEX_CONST_3_ARRAY_PITCH__MASK 0x00003fff diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 3d28fcf841a6..407f50a15faa 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1700,6 +1700,7 @@ static uint32_t a5xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, + .set_param = adreno_set_param, .hw_init = a5xx_hw_init, .pm_suspend = a5xx_pm_suspend, .pm_resume = a5xx_pm_resume, diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h b/drivers/gpu/drm/msm/adreno/a6xx.xml.h index a3cb3d988ba4..b03e2c413ab1 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h @@ -8,21 +8,21 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13) - -Copyright (C) 2013-2021 by the following authors: +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-06-21 15:24:24) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14609 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 69086 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84231 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a4xx.xml ( 113358 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a5xx.xml ( 149512 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx.xml ( 184954 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-07-22 15:21:56) + +Copyright (C) 2013-2022 by the following authors: - Rob Clark <[email protected]> (robclark) - Ilia Mirkin <[email protected]> (imirkin) @@ -132,9 +132,21 @@ enum a6xx_format { FMT6_G8R8B8R8_422_UNORM = 140, FMT6_R8G8R8B8_422_UNORM = 141, FMT6_R8_G8B8_2PLANE_420_UNORM = 142, + FMT6_NV21 = 143, FMT6_R8_G8_B8_3PLANE_420_UNORM = 144, FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 = 145, - FMT6_8_PLANE_UNORM = 148, + FMT6_NV12_Y = 148, + FMT6_NV12_UV = 149, + FMT6_NV12_VU = 150, + FMT6_NV12_4R = 151, + FMT6_NV12_4R_Y = 152, + FMT6_NV12_4R_UV = 153, + FMT6_P010 = 154, + FMT6_P010_Y = 155, + FMT6_P010_UV = 156, + FMT6_TP10 = 157, + FMT6_TP10_Y = 158, + FMT6_TP10_UV = 159, FMT6_Z24_UNORM_S8_UINT = 160, FMT6_ETC2_RG11_UNORM = 171, FMT6_ETC2_RG11_SNORM = 172, @@ -885,6 +897,44 @@ enum a6xx_ztest_mode { A6XX_EARLY_LRZ_LATE_Z = 2, }; +enum a6xx_sequenced_thread_dist { + DIST_SCREEN_COORD = 0, + DIST_ALL_TO_RB0 = 1, +}; + +enum a6xx_single_prim_mode { + NO_FLUSH = 0, + FLUSH_PER_OVERLAP_AND_OVERWRITE = 1, + FLUSH_PER_OVERLAP = 3, +}; + +enum a6xx_raster_mode { + TYPE_TILED = 0, + TYPE_WRITER = 1, +}; + +enum a6xx_raster_direction { + LR_TB = 0, + RL_TB = 1, + LR_BT = 2, + RB_BT = 3, +}; + +enum a6xx_render_mode { + RENDERING_PASS = 0, + BINNING_PASS = 1, +}; + +enum a6xx_buffers_location { + BUFFERS_IN_GMEM = 0, + BUFFERS_IN_SYSMEM = 3, +}; + +enum a6xx_fragcoord_sample_mode { + FRAGCOORD_CENTER = 0, + FRAGCOORD_SAMPLE = 3, +}; + enum a6xx_rotation { ROTATE_0 = 0, ROTATE_90 = 1, @@ -912,6 +962,10 @@ enum a6xx_threadsize { THREAD128 = 1, }; +enum a6xx_isam_mode { + ISAMMODE_GL = 2, +}; + enum a6xx_tex_filter { A6XX_TEX_NEAREST = 0, A6XX_TEX_LINEAR = 1, @@ -955,6 +1009,7 @@ enum a6xx_tex_type { A6XX_TEX_2D = 1, A6XX_TEX_CUBE = 2, A6XX_TEX_3D = 3, + A6XX_TEX_BUFFER = 4, }; #define A6XX_RBBM_INT_0_MASK_RBBM_GPU_IDLE 0x00000001 @@ -1292,6 +1347,10 @@ static inline uint32_t REG_A6XX_RBBM_PERFCTR_RBBM_SEL(uint32_t i0) { return 0x00 #define REG_A6XX_RBBM_PERFCTR_GPU_BUSY_MASKED 0x0000050b +#define REG_A6XX_RBBM_PERFCTR_SRAM_INIT_CMD 0x0000050e + +#define REG_A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS 0x0000050f + #define REG_A6XX_RBBM_ISDB_CNT 0x00000533 #define REG_A6XX_RBBM_PRIMCTR_0_LO 0x00000540 @@ -1934,6 +1993,8 @@ static inline uint32_t A6XX_VBIF_TEST_BUS2_CTRL1_DATA_SEL(uint32_t val) #define REG_A6XX_GBIF_PWR_CNT_HIGH2 0x00003cd1 +#define REG_A6XX_VSC_DBG_ECO_CNTL 0x00000c00 + #define REG_A6XX_VSC_BIN_SIZE 0x00000c02 #define A6XX_VSC_BIN_SIZE_WIDTH__MASK 0x000000ff #define A6XX_VSC_BIN_SIZE_WIDTH__SHIFT 0 @@ -2076,9 +2137,9 @@ static inline uint32_t A6XX_GRAS_GS_CL_CNTL_CULL_MASK(uint32_t val) #define A6XX_GRAS_CNTL_IJ_PERSP_PIXEL 0x00000001 #define A6XX_GRAS_CNTL_IJ_PERSP_CENTROID 0x00000002 #define A6XX_GRAS_CNTL_IJ_PERSP_SAMPLE 0x00000004 -#define A6XX_GRAS_CNTL_SIZE 0x00000008 -#define A6XX_GRAS_CNTL_UNK4 0x00000010 -#define A6XX_GRAS_CNTL_SIZE_PERSAMP 0x00000020 +#define A6XX_GRAS_CNTL_IJ_LINEAR_PIXEL 0x00000008 +#define A6XX_GRAS_CNTL_IJ_LINEAR_CENTROID 0x00000010 +#define A6XX_GRAS_CNTL_IJ_LINEAR_SAMPLE 0x00000020 #define A6XX_GRAS_CNTL_COORD_MASK__MASK 0x000003c0 #define A6XX_GRAS_CNTL_COORD_MASK__SHIFT 6 static inline uint32_t A6XX_GRAS_CNTL_COORD_MASK(uint32_t val) @@ -2185,7 +2246,12 @@ static inline uint32_t A6XX_GRAS_SU_CNTL_UNK12(uint32_t val) { return ((val) << A6XX_GRAS_SU_CNTL_UNK12__SHIFT) & A6XX_GRAS_SU_CNTL_UNK12__MASK; } -#define A6XX_GRAS_SU_CNTL_MSAA_ENABLE 0x00002000 +#define A6XX_GRAS_SU_CNTL_LINE_MODE__MASK 0x00002000 +#define A6XX_GRAS_SU_CNTL_LINE_MODE__SHIFT 13 +static inline uint32_t A6XX_GRAS_SU_CNTL_LINE_MODE(enum a5xx_line_mode val) +{ + return ((val) << A6XX_GRAS_SU_CNTL_LINE_MODE__SHIFT) & A6XX_GRAS_SU_CNTL_LINE_MODE__MASK; +} #define A6XX_GRAS_SU_CNTL_UNK15__MASK 0x00018000 #define A6XX_GRAS_SU_CNTL_UNK15__SHIFT 15 static inline uint32_t A6XX_GRAS_SU_CNTL_UNK15(uint32_t val) @@ -2269,9 +2335,25 @@ static inline uint32_t A6XX_GRAS_SU_DEPTH_BUFFER_INFO_UNK3(uint32_t val) return ((val) << A6XX_GRAS_SU_DEPTH_BUFFER_INFO_UNK3__SHIFT) & A6XX_GRAS_SU_DEPTH_BUFFER_INFO_UNK3__MASK; } -#define REG_A6XX_GRAS_UNKNOWN_8099 0x00008099 +#define REG_A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL 0x00008099 +#define A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_CONSERVATIVERASEN 0x00000001 +#define A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_SHIFTAMOUNT__MASK 0x00000006 +#define A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_SHIFTAMOUNT__SHIFT 1 +static inline uint32_t A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_SHIFTAMOUNT(uint32_t val) +{ + return ((val) << A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_SHIFTAMOUNT__SHIFT) & A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_SHIFTAMOUNT__MASK; +} +#define A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_INNERCONSERVATIVERASEN 0x00000008 +#define A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_UNK4__MASK 0x00000030 +#define A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_UNK4__SHIFT 4 +static inline uint32_t A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_UNK4(uint32_t val) +{ + return ((val) << A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_UNK4__SHIFT) & A6XX_GRAS_SU_CONSERVATIVE_RAS_CNTL_UNK4__MASK; +} -#define REG_A6XX_GRAS_UNKNOWN_809A 0x0000809a +#define REG_A6XX_GRAS_SU_PATH_RENDERING_CNTL 0x0000809a +#define A6XX_GRAS_SU_PATH_RENDERING_CNTL_UNK0 0x00000001 +#define A6XX_GRAS_SU_PATH_RENDERING_CNTL_LINELENGTHEN 0x00000002 #define REG_A6XX_GRAS_VS_LAYER_CNTL 0x0000809b #define A6XX_GRAS_VS_LAYER_CNTL_WRITES_LAYER 0x00000001 @@ -2285,7 +2367,44 @@ static inline uint32_t A6XX_GRAS_SU_DEPTH_BUFFER_INFO_UNK3(uint32_t val) #define A6XX_GRAS_DS_LAYER_CNTL_WRITES_LAYER 0x00000001 #define A6XX_GRAS_DS_LAYER_CNTL_WRITES_VIEW 0x00000002 -#define REG_A6XX_GRAS_UNKNOWN_80A0 0x000080a0 +#define REG_A6XX_GRAS_SC_CNTL 0x000080a0 +#define A6XX_GRAS_SC_CNTL_CCUSINGLECACHELINESIZE__MASK 0x00000007 +#define A6XX_GRAS_SC_CNTL_CCUSINGLECACHELINESIZE__SHIFT 0 +static inline uint32_t A6XX_GRAS_SC_CNTL_CCUSINGLECACHELINESIZE(uint32_t val) +{ + return ((val) << A6XX_GRAS_SC_CNTL_CCUSINGLECACHELINESIZE__SHIFT) & A6XX_GRAS_SC_CNTL_CCUSINGLECACHELINESIZE__MASK; +} +#define A6XX_GRAS_SC_CNTL_SINGLE_PRIM_MODE__MASK 0x00000018 +#define A6XX_GRAS_SC_CNTL_SINGLE_PRIM_MODE__SHIFT 3 +static inline uint32_t A6XX_GRAS_SC_CNTL_SINGLE_PRIM_MODE(enum a6xx_single_prim_mode val) +{ + return ((val) << A6XX_GRAS_SC_CNTL_SINGLE_PRIM_MODE__SHIFT) & A6XX_GRAS_SC_CNTL_SINGLE_PRIM_MODE__MASK; +} +#define A6XX_GRAS_SC_CNTL_RASTER_MODE__MASK 0x00000020 +#define A6XX_GRAS_SC_CNTL_RASTER_MODE__SHIFT 5 +static inline uint32_t A6XX_GRAS_SC_CNTL_RASTER_MODE(enum a6xx_raster_mode val) +{ + return ((val) << A6XX_GRAS_SC_CNTL_RASTER_MODE__SHIFT) & A6XX_GRAS_SC_CNTL_RASTER_MODE__MASK; +} +#define A6XX_GRAS_SC_CNTL_RASTER_DIRECTION__MASK 0x000000c0 +#define A6XX_GRAS_SC_CNTL_RASTER_DIRECTION__SHIFT 6 +static inline uint32_t A6XX_GRAS_SC_CNTL_RASTER_DIRECTION(enum a6xx_raster_direction val) +{ + return ((val) << A6XX_GRAS_SC_CNTL_RASTER_DIRECTION__SHIFT) & A6XX_GRAS_SC_CNTL_RASTER_DIRECTION__MASK; +} +#define A6XX_GRAS_SC_CNTL_SEQUENCED_THREAD_DISTRIBUTION__MASK 0x00000100 +#define A6XX_GRAS_SC_CNTL_SEQUENCED_THREAD_DISTRIBUTION__SHIFT 8 +static inline uint32_t A6XX_GRAS_SC_CNTL_SEQUENCED_THREAD_DISTRIBUTION(enum a6xx_sequenced_thread_dist val) +{ + return ((val) << A6XX_GRAS_SC_CNTL_SEQUENCED_THREAD_DISTRIBUTION__SHIFT) & A6XX_GRAS_SC_CNTL_SEQUENCED_THREAD_DISTRIBUTION__MASK; +} +#define A6XX_GRAS_SC_CNTL_UNK9__MASK 0x00000e00 +#define A6XX_GRAS_SC_CNTL_UNK9__SHIFT 9 +static inline uint32_t A6XX_GRAS_SC_CNTL_UNK9(uint32_t val) +{ + return ((val) << A6XX_GRAS_SC_CNTL_UNK9__SHIFT) & A6XX_GRAS_SC_CNTL_UNK9__MASK; +} +#define A6XX_GRAS_SC_CNTL_EARLYVIZOUTEN 0x00001000 #define REG_A6XX_GRAS_BIN_CONTROL 0x000080a1 #define A6XX_GRAS_BIN_CONTROL_BINW__MASK 0x0000003f @@ -2300,25 +2419,30 @@ static inline uint32_t A6XX_GRAS_BIN_CONTROL_BINH(uint32_t val) { return ((val >> 4) << A6XX_GRAS_BIN_CONTROL_BINH__SHIFT) & A6XX_GRAS_BIN_CONTROL_BINH__MASK; } -#define A6XX_GRAS_BIN_CONTROL_BINNING_PASS 0x00040000 -#define A6XX_GRAS_BIN_CONTROL_UNK19__MASK 0x00080000 -#define A6XX_GRAS_BIN_CONTROL_UNK19__SHIFT 19 -static inline uint32_t A6XX_GRAS_BIN_CONTROL_UNK19(uint32_t val) +#define A6XX_GRAS_BIN_CONTROL_RENDER_MODE__MASK 0x001c0000 +#define A6XX_GRAS_BIN_CONTROL_RENDER_MODE__SHIFT 18 +static inline uint32_t A6XX_GRAS_BIN_CONTROL_RENDER_MODE(enum a6xx_render_mode val) +{ + return ((val) << A6XX_GRAS_BIN_CONTROL_RENDER_MODE__SHIFT) & A6XX_GRAS_BIN_CONTROL_RENDER_MODE__MASK; +} +#define A6XX_GRAS_BIN_CONTROL_FORCE_LRZ_WRITE_DIS 0x00200000 +#define A6XX_GRAS_BIN_CONTROL_BUFFERS_LOCATION__MASK 0x00c00000 +#define A6XX_GRAS_BIN_CONTROL_BUFFERS_LOCATION__SHIFT 22 +static inline uint32_t A6XX_GRAS_BIN_CONTROL_BUFFERS_LOCATION(enum a6xx_buffers_location val) { - return ((val) << A6XX_GRAS_BIN_CONTROL_UNK19__SHIFT) & A6XX_GRAS_BIN_CONTROL_UNK19__MASK; + return ((val) << A6XX_GRAS_BIN_CONTROL_BUFFERS_LOCATION__SHIFT) & A6XX_GRAS_BIN_CONTROL_BUFFERS_LOCATION__MASK; } -#define A6XX_GRAS_BIN_CONTROL_UNK20__MASK 0x00100000 -#define A6XX_GRAS_BIN_CONTROL_UNK20__SHIFT 20 -static inline uint32_t A6XX_GRAS_BIN_CONTROL_UNK20(uint32_t val) +#define A6XX_GRAS_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK__MASK 0x07000000 +#define A6XX_GRAS_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK__SHIFT 24 +static inline uint32_t A6XX_GRAS_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK(uint32_t val) { - return ((val) << A6XX_GRAS_BIN_CONTROL_UNK20__SHIFT) & A6XX_GRAS_BIN_CONTROL_UNK20__MASK; + return ((val) << A6XX_GRAS_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK__SHIFT) & A6XX_GRAS_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK__MASK; } -#define A6XX_GRAS_BIN_CONTROL_USE_VIZ 0x00200000 -#define A6XX_GRAS_BIN_CONTROL_UNK22__MASK 0x0fc00000 -#define A6XX_GRAS_BIN_CONTROL_UNK22__SHIFT 22 -static inline uint32_t A6XX_GRAS_BIN_CONTROL_UNK22(uint32_t val) +#define A6XX_GRAS_BIN_CONTROL_UNK27__MASK 0x08000000 +#define A6XX_GRAS_BIN_CONTROL_UNK27__SHIFT 27 +static inline uint32_t A6XX_GRAS_BIN_CONTROL_UNK27(uint32_t val) { - return ((val) << A6XX_GRAS_BIN_CONTROL_UNK22__SHIFT) & A6XX_GRAS_BIN_CONTROL_UNK22__MASK; + return ((val) << A6XX_GRAS_BIN_CONTROL_UNK27__SHIFT) & A6XX_GRAS_BIN_CONTROL_UNK27__MASK; } #define REG_A6XX_GRAS_RAS_MSAA_CNTL 0x000080a2 @@ -2558,14 +2682,21 @@ static inline uint32_t A6XX_GRAS_LRZ_CNTL_UNK6(uint32_t val) return ((val) << A6XX_GRAS_LRZ_CNTL_UNK6__SHIFT) & A6XX_GRAS_LRZ_CNTL_UNK6__MASK; } -#define REG_A6XX_GRAS_UNKNOWN_8101 0x00008101 +#define REG_A6XX_GRAS_LRZ_PS_INPUT_CNTL 0x00008101 +#define A6XX_GRAS_LRZ_PS_INPUT_CNTL_SAMPLEID 0x00000001 +#define A6XX_GRAS_LRZ_PS_INPUT_CNTL_FRAGCOORDSAMPLEMODE__MASK 0x00000006 +#define A6XX_GRAS_LRZ_PS_INPUT_CNTL_FRAGCOORDSAMPLEMODE__SHIFT 1 +static inline uint32_t A6XX_GRAS_LRZ_PS_INPUT_CNTL_FRAGCOORDSAMPLEMODE(enum a6xx_fragcoord_sample_mode val) +{ + return ((val) << A6XX_GRAS_LRZ_PS_INPUT_CNTL_FRAGCOORDSAMPLEMODE__SHIFT) & A6XX_GRAS_LRZ_PS_INPUT_CNTL_FRAGCOORDSAMPLEMODE__MASK; +} -#define REG_A6XX_GRAS_2D_BLIT_INFO 0x00008102 -#define A6XX_GRAS_2D_BLIT_INFO_COLOR_FORMAT__MASK 0x000000ff -#define A6XX_GRAS_2D_BLIT_INFO_COLOR_FORMAT__SHIFT 0 -static inline uint32_t A6XX_GRAS_2D_BLIT_INFO_COLOR_FORMAT(enum a6xx_format val) +#define REG_A6XX_GRAS_LRZ_MRT_BUF_INFO_0 0x00008102 +#define A6XX_GRAS_LRZ_MRT_BUF_INFO_0_COLOR_FORMAT__MASK 0x000000ff +#define A6XX_GRAS_LRZ_MRT_BUF_INFO_0_COLOR_FORMAT__SHIFT 0 +static inline uint32_t A6XX_GRAS_LRZ_MRT_BUF_INFO_0_COLOR_FORMAT(enum a6xx_format val) { - return ((val) << A6XX_GRAS_2D_BLIT_INFO_COLOR_FORMAT__SHIFT) & A6XX_GRAS_2D_BLIT_INFO_COLOR_FORMAT__MASK; + return ((val) << A6XX_GRAS_LRZ_MRT_BUF_INFO_0_COLOR_FORMAT__SHIFT) & A6XX_GRAS_LRZ_MRT_BUF_INFO_0_COLOR_FORMAT__MASK; } #define REG_A6XX_GRAS_LRZ_BUFFER_BASE 0x00008103 @@ -2630,11 +2761,12 @@ static inline uint32_t A6XX_GRAS_2D_BLIT_CNTL_ROTATE(enum a6xx_rotation val) { return ((val) << A6XX_GRAS_2D_BLIT_CNTL_ROTATE__SHIFT) & A6XX_GRAS_2D_BLIT_CNTL_ROTATE__MASK; } -#define A6XX_GRAS_2D_BLIT_CNTL_UNK3__MASK 0x00000078 -#define A6XX_GRAS_2D_BLIT_CNTL_UNK3__SHIFT 3 -static inline uint32_t A6XX_GRAS_2D_BLIT_CNTL_UNK3(uint32_t val) +#define A6XX_GRAS_2D_BLIT_CNTL_OVERWRITEEN 0x00000008 +#define A6XX_GRAS_2D_BLIT_CNTL_UNK4__MASK 0x00000070 +#define A6XX_GRAS_2D_BLIT_CNTL_UNK4__SHIFT 4 +static inline uint32_t A6XX_GRAS_2D_BLIT_CNTL_UNK4(uint32_t val) { - return ((val) << A6XX_GRAS_2D_BLIT_CNTL_UNK3__SHIFT) & A6XX_GRAS_2D_BLIT_CNTL_UNK3__MASK; + return ((val) << A6XX_GRAS_2D_BLIT_CNTL_UNK4__SHIFT) & A6XX_GRAS_2D_BLIT_CNTL_UNK4__MASK; } #define A6XX_GRAS_2D_BLIT_CNTL_SOLID_COLOR 0x00000080 #define A6XX_GRAS_2D_BLIT_CNTL_COLOR_FORMAT__MASK 0x0000ff00 @@ -2663,11 +2795,11 @@ static inline uint32_t A6XX_GRAS_2D_BLIT_CNTL_IFMT(enum a6xx_2d_ifmt val) { return ((val) << A6XX_GRAS_2D_BLIT_CNTL_IFMT__SHIFT) & A6XX_GRAS_2D_BLIT_CNTL_IFMT__MASK; } -#define A6XX_GRAS_2D_BLIT_CNTL_UNK29__MASK 0x20000000 -#define A6XX_GRAS_2D_BLIT_CNTL_UNK29__SHIFT 29 -static inline uint32_t A6XX_GRAS_2D_BLIT_CNTL_UNK29(uint32_t val) +#define A6XX_GRAS_2D_BLIT_CNTL_RASTER_MODE__MASK 0x20000000 +#define A6XX_GRAS_2D_BLIT_CNTL_RASTER_MODE__SHIFT 29 +static inline uint32_t A6XX_GRAS_2D_BLIT_CNTL_RASTER_MODE(enum a6xx_raster_mode val) { - return ((val) << A6XX_GRAS_2D_BLIT_CNTL_UNK29__SHIFT) & A6XX_GRAS_2D_BLIT_CNTL_UNK29__MASK; + return ((val) << A6XX_GRAS_2D_BLIT_CNTL_RASTER_MODE__SHIFT) & A6XX_GRAS_2D_BLIT_CNTL_RASTER_MODE__MASK; } #define REG_A6XX_GRAS_2D_SRC_TL_X 0x00008401 @@ -2740,7 +2872,9 @@ static inline uint32_t A6XX_GRAS_2D_RESOLVE_CNTL_2_Y(uint32_t val) return ((val) << A6XX_GRAS_2D_RESOLVE_CNTL_2_Y__SHIFT) & A6XX_GRAS_2D_RESOLVE_CNTL_2_Y__MASK; } -#define REG_A6XX_GRAS_UNKNOWN_8600 0x00008600 +#define REG_A6XX_GRAS_DBG_ECO_CNTL 0x00008600 +#define A6XX_GRAS_DBG_ECO_CNTL_UNK7 0x00000080 +#define A6XX_GRAS_DBG_ECO_CNTL_LRZCACHELOCKDIS 0x00000800 #define REG_A6XX_GRAS_ADDR_MODE_CNTL 0x00008601 @@ -2763,43 +2897,55 @@ static inline uint32_t A6XX_RB_BIN_CONTROL_BINH(uint32_t val) { return ((val >> 4) << A6XX_RB_BIN_CONTROL_BINH__SHIFT) & A6XX_RB_BIN_CONTROL_BINH__MASK; } -#define A6XX_RB_BIN_CONTROL_BINNING_PASS 0x00040000 -#define A6XX_RB_BIN_CONTROL_UNK19__MASK 0x00080000 -#define A6XX_RB_BIN_CONTROL_UNK19__SHIFT 19 -static inline uint32_t A6XX_RB_BIN_CONTROL_UNK19(uint32_t val) +#define A6XX_RB_BIN_CONTROL_RENDER_MODE__MASK 0x001c0000 +#define A6XX_RB_BIN_CONTROL_RENDER_MODE__SHIFT 18 +static inline uint32_t A6XX_RB_BIN_CONTROL_RENDER_MODE(enum a6xx_render_mode val) { - return ((val) << A6XX_RB_BIN_CONTROL_UNK19__SHIFT) & A6XX_RB_BIN_CONTROL_UNK19__MASK; + return ((val) << A6XX_RB_BIN_CONTROL_RENDER_MODE__SHIFT) & A6XX_RB_BIN_CONTROL_RENDER_MODE__MASK; } -#define A6XX_RB_BIN_CONTROL_UNK20__MASK 0x00100000 -#define A6XX_RB_BIN_CONTROL_UNK20__SHIFT 20 -static inline uint32_t A6XX_RB_BIN_CONTROL_UNK20(uint32_t val) +#define A6XX_RB_BIN_CONTROL_FORCE_LRZ_WRITE_DIS 0x00200000 +#define A6XX_RB_BIN_CONTROL_BUFFERS_LOCATION__MASK 0x00c00000 +#define A6XX_RB_BIN_CONTROL_BUFFERS_LOCATION__SHIFT 22 +static inline uint32_t A6XX_RB_BIN_CONTROL_BUFFERS_LOCATION(enum a6xx_buffers_location val) { - return ((val) << A6XX_RB_BIN_CONTROL_UNK20__SHIFT) & A6XX_RB_BIN_CONTROL_UNK20__MASK; + return ((val) << A6XX_RB_BIN_CONTROL_BUFFERS_LOCATION__SHIFT) & A6XX_RB_BIN_CONTROL_BUFFERS_LOCATION__MASK; } -#define A6XX_RB_BIN_CONTROL_USE_VIZ 0x00200000 -#define A6XX_RB_BIN_CONTROL_UNK22__MASK 0x07c00000 -#define A6XX_RB_BIN_CONTROL_UNK22__SHIFT 22 -static inline uint32_t A6XX_RB_BIN_CONTROL_UNK22(uint32_t val) +#define A6XX_RB_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK__MASK 0x07000000 +#define A6XX_RB_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK__SHIFT 24 +static inline uint32_t A6XX_RB_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK(uint32_t val) { - return ((val) << A6XX_RB_BIN_CONTROL_UNK22__SHIFT) & A6XX_RB_BIN_CONTROL_UNK22__MASK; + return ((val) << A6XX_RB_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK__SHIFT) & A6XX_RB_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK__MASK; } #define REG_A6XX_RB_RENDER_CNTL 0x00008801 -#define A6XX_RB_RENDER_CNTL_UNK3 0x00000008 -#define A6XX_RB_RENDER_CNTL_UNK4 0x00000010 -#define A6XX_RB_RENDER_CNTL_UNK5__MASK 0x00000060 -#define A6XX_RB_RENDER_CNTL_UNK5__SHIFT 5 -static inline uint32_t A6XX_RB_RENDER_CNTL_UNK5(uint32_t val) +#define A6XX_RB_RENDER_CNTL_CCUSINGLECACHELINESIZE__MASK 0x00000038 +#define A6XX_RB_RENDER_CNTL_CCUSINGLECACHELINESIZE__SHIFT 3 +static inline uint32_t A6XX_RB_RENDER_CNTL_CCUSINGLECACHELINESIZE(uint32_t val) { - return ((val) << A6XX_RB_RENDER_CNTL_UNK5__SHIFT) & A6XX_RB_RENDER_CNTL_UNK5__MASK; + return ((val) << A6XX_RB_RENDER_CNTL_CCUSINGLECACHELINESIZE__SHIFT) & A6XX_RB_RENDER_CNTL_CCUSINGLECACHELINESIZE__MASK; } +#define A6XX_RB_RENDER_CNTL_EARLYVIZOUTEN 0x00000040 #define A6XX_RB_RENDER_CNTL_BINNING 0x00000080 -#define A6XX_RB_RENDER_CNTL_UNK8__MASK 0x00001f00 +#define A6XX_RB_RENDER_CNTL_UNK8__MASK 0x00000700 #define A6XX_RB_RENDER_CNTL_UNK8__SHIFT 8 static inline uint32_t A6XX_RB_RENDER_CNTL_UNK8(uint32_t val) { return ((val) << A6XX_RB_RENDER_CNTL_UNK8__SHIFT) & A6XX_RB_RENDER_CNTL_UNK8__MASK; } +#define A6XX_RB_RENDER_CNTL_RASTER_MODE__MASK 0x00000100 +#define A6XX_RB_RENDER_CNTL_RASTER_MODE__SHIFT 8 +static inline uint32_t A6XX_RB_RENDER_CNTL_RASTER_MODE(enum a6xx_raster_mode val) +{ + return ((val) << A6XX_RB_RENDER_CNTL_RASTER_MODE__SHIFT) & A6XX_RB_RENDER_CNTL_RASTER_MODE__MASK; +} +#define A6XX_RB_RENDER_CNTL_RASTER_DIRECTION__MASK 0x00000600 +#define A6XX_RB_RENDER_CNTL_RASTER_DIRECTION__SHIFT 9 +static inline uint32_t A6XX_RB_RENDER_CNTL_RASTER_DIRECTION(enum a6xx_raster_direction val) +{ + return ((val) << A6XX_RB_RENDER_CNTL_RASTER_DIRECTION__SHIFT) & A6XX_RB_RENDER_CNTL_RASTER_DIRECTION__MASK; +} +#define A6XX_RB_RENDER_CNTL_CONSERVATIVERASEN 0x00000800 +#define A6XX_RB_RENDER_CNTL_INNERCONSERVATIVERASEN 0x00001000 #define A6XX_RB_RENDER_CNTL_FLAG_DEPTH 0x00004000 #define A6XX_RB_RENDER_CNTL_FLAG_MRTS__MASK 0x00ff0000 #define A6XX_RB_RENDER_CNTL_FLAG_MRTS__SHIFT 16 @@ -2945,9 +3091,9 @@ static inline uint32_t A6XX_RB_SAMPLE_LOCATION_1_SAMPLE_3_Y(float val) #define A6XX_RB_RENDER_CONTROL0_IJ_PERSP_PIXEL 0x00000001 #define A6XX_RB_RENDER_CONTROL0_IJ_PERSP_CENTROID 0x00000002 #define A6XX_RB_RENDER_CONTROL0_IJ_PERSP_SAMPLE 0x00000004 -#define A6XX_RB_RENDER_CONTROL0_SIZE 0x00000008 -#define A6XX_RB_RENDER_CONTROL0_UNK4 0x00000010 -#define A6XX_RB_RENDER_CONTROL0_SIZE_PERSAMP 0x00000020 +#define A6XX_RB_RENDER_CONTROL0_IJ_LINEAR_PIXEL 0x00000008 +#define A6XX_RB_RENDER_CONTROL0_IJ_LINEAR_CENTROID 0x00000010 +#define A6XX_RB_RENDER_CONTROL0_IJ_LINEAR_SAMPLE 0x00000020 #define A6XX_RB_RENDER_CONTROL0_COORD_MASK__MASK 0x000003c0 #define A6XX_RB_RENDER_CONTROL0_COORD_MASK__SHIFT 6 static inline uint32_t A6XX_RB_RENDER_CONTROL0_COORD_MASK(uint32_t val) @@ -2961,11 +3107,15 @@ static inline uint32_t A6XX_RB_RENDER_CONTROL0_COORD_MASK(uint32_t val) #define A6XX_RB_RENDER_CONTROL1_UNK1 0x00000002 #define A6XX_RB_RENDER_CONTROL1_FACENESS 0x00000004 #define A6XX_RB_RENDER_CONTROL1_SAMPLEID 0x00000008 -#define A6XX_RB_RENDER_CONTROL1_UNK4 0x00000010 -#define A6XX_RB_RENDER_CONTROL1_UNK5 0x00000020 +#define A6XX_RB_RENDER_CONTROL1_FRAGCOORDSAMPLEMODE__MASK 0x00000030 +#define A6XX_RB_RENDER_CONTROL1_FRAGCOORDSAMPLEMODE__SHIFT 4 +static inline uint32_t A6XX_RB_RENDER_CONTROL1_FRAGCOORDSAMPLEMODE(enum a6xx_fragcoord_sample_mode val) +{ + return ((val) << A6XX_RB_RENDER_CONTROL1_FRAGCOORDSAMPLEMODE__SHIFT) & A6XX_RB_RENDER_CONTROL1_FRAGCOORDSAMPLEMODE__MASK; +} #define A6XX_RB_RENDER_CONTROL1_SIZE 0x00000040 -#define A6XX_RB_RENDER_CONTROL1_UNK7 0x00000080 -#define A6XX_RB_RENDER_CONTROL1_UNK8 0x00000100 +#define A6XX_RB_RENDER_CONTROL1_LINELENGTHEN 0x00000080 +#define A6XX_RB_RENDER_CONTROL1_FOVEATION 0x00000100 #define REG_A6XX_RB_FS_OUTPUT_CNTL0 0x0000880b #define A6XX_RB_FS_OUTPUT_CNTL0_DUAL_COLOR_IN_ENABLE 0x00000001 @@ -3299,7 +3449,7 @@ static inline uint32_t A6XX_RB_DEPTH_PLANE_CNTL_Z_MODE(enum a6xx_ztest_mode val) } #define REG_A6XX_RB_DEPTH_CNTL 0x00008871 -#define A6XX_RB_DEPTH_CNTL_Z_ENABLE 0x00000001 +#define A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE 0x00000001 #define A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE 0x00000002 #define A6XX_RB_DEPTH_CNTL_ZFUNC__MASK 0x0000001c #define A6XX_RB_DEPTH_CNTL_ZFUNC__SHIFT 2 @@ -3308,7 +3458,7 @@ static inline uint32_t A6XX_RB_DEPTH_CNTL_ZFUNC(enum adreno_compare_func val) return ((val) << A6XX_RB_DEPTH_CNTL_ZFUNC__SHIFT) & A6XX_RB_DEPTH_CNTL_ZFUNC__MASK; } #define A6XX_RB_DEPTH_CNTL_Z_CLAMP_ENABLE 0x00000020 -#define A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE 0x00000040 +#define A6XX_RB_DEPTH_CNTL_Z_READ_ENABLE 0x00000040 #define A6XX_RB_DEPTH_CNTL_Z_BOUNDS_ENABLE 0x00000080 #define REG_A6XX_RB_DEPTH_BUFFER_INFO 0x00008872 @@ -3819,6 +3969,14 @@ static inline uint32_t A6XX_RB_SAMPLE_COUNT_ADDR(uint32_t val) return ((val) << A6XX_RB_SAMPLE_COUNT_ADDR__SHIFT) & A6XX_RB_SAMPLE_COUNT_ADDR__MASK; } +#define REG_A6XX_RB_UNKNOWN_8A00 0x00008a00 + +#define REG_A6XX_RB_UNKNOWN_8A10 0x00008a10 + +#define REG_A6XX_RB_UNKNOWN_8A20 0x00008a20 + +#define REG_A6XX_RB_UNKNOWN_8A30 0x00008a30 + #define REG_A6XX_RB_2D_BLIT_CNTL 0x00008c00 #define A6XX_RB_2D_BLIT_CNTL_ROTATE__MASK 0x00000007 #define A6XX_RB_2D_BLIT_CNTL_ROTATE__SHIFT 0 @@ -3826,11 +3984,12 @@ static inline uint32_t A6XX_RB_2D_BLIT_CNTL_ROTATE(enum a6xx_rotation val) { return ((val) << A6XX_RB_2D_BLIT_CNTL_ROTATE__SHIFT) & A6XX_RB_2D_BLIT_CNTL_ROTATE__MASK; } -#define A6XX_RB_2D_BLIT_CNTL_UNK3__MASK 0x00000078 -#define A6XX_RB_2D_BLIT_CNTL_UNK3__SHIFT 3 -static inline uint32_t A6XX_RB_2D_BLIT_CNTL_UNK3(uint32_t val) +#define A6XX_RB_2D_BLIT_CNTL_OVERWRITEEN 0x00000008 +#define A6XX_RB_2D_BLIT_CNTL_UNK4__MASK 0x00000070 +#define A6XX_RB_2D_BLIT_CNTL_UNK4__SHIFT 4 +static inline uint32_t A6XX_RB_2D_BLIT_CNTL_UNK4(uint32_t val) { - return ((val) << A6XX_RB_2D_BLIT_CNTL_UNK3__SHIFT) & A6XX_RB_2D_BLIT_CNTL_UNK3__MASK; + return ((val) << A6XX_RB_2D_BLIT_CNTL_UNK4__SHIFT) & A6XX_RB_2D_BLIT_CNTL_UNK4__MASK; } #define A6XX_RB_2D_BLIT_CNTL_SOLID_COLOR 0x00000080 #define A6XX_RB_2D_BLIT_CNTL_COLOR_FORMAT__MASK 0x0000ff00 @@ -3859,11 +4018,11 @@ static inline uint32_t A6XX_RB_2D_BLIT_CNTL_IFMT(enum a6xx_2d_ifmt val) { return ((val) << A6XX_RB_2D_BLIT_CNTL_IFMT__SHIFT) & A6XX_RB_2D_BLIT_CNTL_IFMT__MASK; } -#define A6XX_RB_2D_BLIT_CNTL_UNK29__MASK 0x20000000 -#define A6XX_RB_2D_BLIT_CNTL_UNK29__SHIFT 29 -static inline uint32_t A6XX_RB_2D_BLIT_CNTL_UNK29(uint32_t val) +#define A6XX_RB_2D_BLIT_CNTL_RASTER_MODE__MASK 0x20000000 +#define A6XX_RB_2D_BLIT_CNTL_RASTER_MODE__SHIFT 29 +static inline uint32_t A6XX_RB_2D_BLIT_CNTL_RASTER_MODE(enum a6xx_raster_mode val) { - return ((val) << A6XX_RB_2D_BLIT_CNTL_UNK29__SHIFT) & A6XX_RB_2D_BLIT_CNTL_UNK29__MASK; + return ((val) << A6XX_RB_2D_BLIT_CNTL_RASTER_MODE__SHIFT) & A6XX_RB_2D_BLIT_CNTL_RASTER_MODE__MASK; } #define REG_A6XX_RB_2D_UNKNOWN_8C01 0x00008c01 @@ -3997,11 +4156,17 @@ static inline uint32_t A6XX_RB_2D_DST_FLAGS_PLANE_PITCH(uint32_t val) #define REG_A6XX_RB_ADDR_MODE_CNTL 0x00008e05 #define REG_A6XX_RB_CCU_CNTL 0x00008e07 -#define A6XX_RB_CCU_CNTL_OFFSET__MASK 0xff800000 -#define A6XX_RB_CCU_CNTL_OFFSET__SHIFT 23 -static inline uint32_t A6XX_RB_CCU_CNTL_OFFSET(uint32_t val) +#define A6XX_RB_CCU_CNTL_COLOR_OFFSET__MASK 0xff800000 +#define A6XX_RB_CCU_CNTL_COLOR_OFFSET__SHIFT 23 +static inline uint32_t A6XX_RB_CCU_CNTL_COLOR_OFFSET(uint32_t val) { - return ((val >> 12) << A6XX_RB_CCU_CNTL_OFFSET__SHIFT) & A6XX_RB_CCU_CNTL_OFFSET__MASK; + return ((val >> 12) << A6XX_RB_CCU_CNTL_COLOR_OFFSET__SHIFT) & A6XX_RB_CCU_CNTL_COLOR_OFFSET__MASK; +} +#define A6XX_RB_CCU_CNTL_DEPTH_OFFSET__MASK 0x001ff000 +#define A6XX_RB_CCU_CNTL_DEPTH_OFFSET__SHIFT 12 +static inline uint32_t A6XX_RB_CCU_CNTL_DEPTH_OFFSET(uint32_t val) +{ + return ((val >> 12) << A6XX_RB_CCU_CNTL_DEPTH_OFFSET__SHIFT) & A6XX_RB_CCU_CNTL_DEPTH_OFFSET__MASK; } #define A6XX_RB_CCU_CNTL_GMEM 0x00400000 #define A6XX_RB_CCU_CNTL_UNK2 0x00000004 @@ -4052,7 +4217,13 @@ static inline uint32_t A6XX_RB_UNKNOWN_8E51(uint32_t val) return ((val) << A6XX_RB_UNKNOWN_8E51__SHIFT) & A6XX_RB_UNKNOWN_8E51__MASK; } -#define REG_A6XX_VPC_UNKNOWN_9100 0x00009100 +#define REG_A6XX_VPC_GS_PARAM 0x00009100 +#define A6XX_VPC_GS_PARAM_LINELENGTHLOC__MASK 0x000000ff +#define A6XX_VPC_GS_PARAM_LINELENGTHLOC__SHIFT 0 +static inline uint32_t A6XX_VPC_GS_PARAM_LINELENGTHLOC(uint32_t val) +{ + return ((val) << A6XX_VPC_GS_PARAM_LINELENGTHLOC__SHIFT) & A6XX_VPC_GS_PARAM_LINELENGTHLOC__MASK; +} #define REG_A6XX_VPC_VS_CLIP_CNTL 0x00009101 #define A6XX_VPC_VS_CLIP_CNTL_CLIP_MASK__MASK 0x000000ff @@ -4448,10 +4619,16 @@ static inline uint32_t A6XX_PC_TESS_CNTL_OUTPUT(enum a6xx_tess_output val) #define REG_A6XX_PC_MODE_CNTL 0x00009804 -#define REG_A6XX_PC_UNKNOWN_9805 0x00009805 +#define REG_A6XX_PC_POWER_CNTL 0x00009805 #define REG_A6XX_PC_PRIMID_PASSTHRU 0x00009806 +#define REG_A6XX_PC_SO_STREAM_CNTL 0x00009808 +#define A6XX_PC_SO_STREAM_CNTL_STREAM_ENABLE 0x00008000 + +#define REG_A6XX_PC_DGEN_SU_CONSERVATIVE_RAS_CNTL 0x0000980a +#define A6XX_PC_DGEN_SU_CONSERVATIVE_RAS_CNTL_CONSERVATIVERASEN 0x00000001 + #define REG_A6XX_PC_DRAW_CMD 0x00009840 #define A6XX_PC_DRAW_CMD_STATE_ID__MASK 0x000000ff #define A6XX_PC_DRAW_CMD_STATE_ID__SHIFT 0 @@ -4543,7 +4720,23 @@ static inline uint32_t A6XX_PC_GS_OUT_CNTL_CLIP_MASK(uint32_t val) return ((val) << A6XX_PC_GS_OUT_CNTL_CLIP_MASK__SHIFT) & A6XX_PC_GS_OUT_CNTL_CLIP_MASK__MASK; } -#define REG_A6XX_PC_PRIMITIVE_CNTL_3 0x00009b03 +#define REG_A6XX_PC_HS_OUT_CNTL 0x00009b03 +#define A6XX_PC_HS_OUT_CNTL_STRIDE_IN_VPC__MASK 0x000000ff +#define A6XX_PC_HS_OUT_CNTL_STRIDE_IN_VPC__SHIFT 0 +static inline uint32_t A6XX_PC_HS_OUT_CNTL_STRIDE_IN_VPC(uint32_t val) +{ + return ((val) << A6XX_PC_HS_OUT_CNTL_STRIDE_IN_VPC__SHIFT) & A6XX_PC_HS_OUT_CNTL_STRIDE_IN_VPC__MASK; +} +#define A6XX_PC_HS_OUT_CNTL_PSIZE 0x00000100 +#define A6XX_PC_HS_OUT_CNTL_LAYER 0x00000200 +#define A6XX_PC_HS_OUT_CNTL_VIEW 0x00000400 +#define A6XX_PC_HS_OUT_CNTL_PRIMITIVE_ID 0x00000800 +#define A6XX_PC_HS_OUT_CNTL_CLIP_MASK__MASK 0x00ff0000 +#define A6XX_PC_HS_OUT_CNTL_CLIP_MASK__SHIFT 16 +static inline uint32_t A6XX_PC_HS_OUT_CNTL_CLIP_MASK(uint32_t val) +{ + return ((val) << A6XX_PC_HS_OUT_CNTL_CLIP_MASK__SHIFT) & A6XX_PC_HS_OUT_CNTL_CLIP_MASK__MASK; +} #define REG_A6XX_PC_DS_OUT_CNTL 0x00009b04 #define A6XX_PC_DS_OUT_CNTL_STRIDE_IN_VPC__MASK 0x000000ff @@ -4576,6 +4769,7 @@ static inline uint32_t A6XX_PC_PRIMITIVE_CNTL_5_GS_INVOCATIONS(uint32_t val) { return ((val) << A6XX_PC_PRIMITIVE_CNTL_5_GS_INVOCATIONS__SHIFT) & A6XX_PC_PRIMITIVE_CNTL_5_GS_INVOCATIONS__MASK; } +#define A6XX_PC_PRIMITIVE_CNTL_5_LINELENGTHEN 0x00008000 #define A6XX_PC_PRIMITIVE_CNTL_5_GS_OUTPUT__MASK 0x00030000 #define A6XX_PC_PRIMITIVE_CNTL_5_GS_OUTPUT__SHIFT 16 static inline uint32_t A6XX_PC_PRIMITIVE_CNTL_5_GS_OUTPUT(enum a6xx_tess_output val) @@ -4763,11 +4957,11 @@ static inline uint32_t A6XX_VFD_CONTROL_1_REGID4VIEWID(uint32_t val) } #define REG_A6XX_VFD_CONTROL_2 0x0000a002 -#define A6XX_VFD_CONTROL_2_REGID_HSPATCHID__MASK 0x000000ff -#define A6XX_VFD_CONTROL_2_REGID_HSPATCHID__SHIFT 0 -static inline uint32_t A6XX_VFD_CONTROL_2_REGID_HSPATCHID(uint32_t val) +#define A6XX_VFD_CONTROL_2_REGID_HSRELPATCHID__MASK 0x000000ff +#define A6XX_VFD_CONTROL_2_REGID_HSRELPATCHID__SHIFT 0 +static inline uint32_t A6XX_VFD_CONTROL_2_REGID_HSRELPATCHID(uint32_t val) { - return ((val) << A6XX_VFD_CONTROL_2_REGID_HSPATCHID__SHIFT) & A6XX_VFD_CONTROL_2_REGID_HSPATCHID__MASK; + return ((val) << A6XX_VFD_CONTROL_2_REGID_HSRELPATCHID__SHIFT) & A6XX_VFD_CONTROL_2_REGID_HSRELPATCHID__MASK; } #define A6XX_VFD_CONTROL_2_REGID_INVOCATIONID__MASK 0x0000ff00 #define A6XX_VFD_CONTROL_2_REGID_INVOCATIONID__SHIFT 8 @@ -4777,17 +4971,17 @@ static inline uint32_t A6XX_VFD_CONTROL_2_REGID_INVOCATIONID(uint32_t val) } #define REG_A6XX_VFD_CONTROL_3 0x0000a003 -#define A6XX_VFD_CONTROL_3_UNK0__MASK 0x000000ff -#define A6XX_VFD_CONTROL_3_UNK0__SHIFT 0 -static inline uint32_t A6XX_VFD_CONTROL_3_UNK0(uint32_t val) +#define A6XX_VFD_CONTROL_3_REGID_DSPRIMID__MASK 0x000000ff +#define A6XX_VFD_CONTROL_3_REGID_DSPRIMID__SHIFT 0 +static inline uint32_t A6XX_VFD_CONTROL_3_REGID_DSPRIMID(uint32_t val) { - return ((val) << A6XX_VFD_CONTROL_3_UNK0__SHIFT) & A6XX_VFD_CONTROL_3_UNK0__MASK; + return ((val) << A6XX_VFD_CONTROL_3_REGID_DSPRIMID__SHIFT) & A6XX_VFD_CONTROL_3_REGID_DSPRIMID__MASK; } -#define A6XX_VFD_CONTROL_3_REGID_DSPATCHID__MASK 0x0000ff00 -#define A6XX_VFD_CONTROL_3_REGID_DSPATCHID__SHIFT 8 -static inline uint32_t A6XX_VFD_CONTROL_3_REGID_DSPATCHID(uint32_t val) +#define A6XX_VFD_CONTROL_3_REGID_DSRELPATCHID__MASK 0x0000ff00 +#define A6XX_VFD_CONTROL_3_REGID_DSRELPATCHID__SHIFT 8 +static inline uint32_t A6XX_VFD_CONTROL_3_REGID_DSRELPATCHID(uint32_t val) { - return ((val) << A6XX_VFD_CONTROL_3_REGID_DSPATCHID__SHIFT) & A6XX_VFD_CONTROL_3_REGID_DSPATCHID__MASK; + return ((val) << A6XX_VFD_CONTROL_3_REGID_DSRELPATCHID__SHIFT) & A6XX_VFD_CONTROL_3_REGID_DSRELPATCHID__MASK; } #define A6XX_VFD_CONTROL_3_REGID_TESSX__MASK 0x00ff0000 #define A6XX_VFD_CONTROL_3_REGID_TESSX__SHIFT 16 @@ -4828,9 +5022,12 @@ static inline uint32_t A6XX_VFD_CONTROL_5_UNK8(uint32_t val) #define A6XX_VFD_CONTROL_6_PRIMID_PASSTHRU 0x00000001 #define REG_A6XX_VFD_MODE_CNTL 0x0000a007 -#define A6XX_VFD_MODE_CNTL_BINNING_PASS 0x00000001 -#define A6XX_VFD_MODE_CNTL_UNK1 0x00000002 -#define A6XX_VFD_MODE_CNTL_UNK2 0x00000004 +#define A6XX_VFD_MODE_CNTL_RENDER_MODE__MASK 0x00000007 +#define A6XX_VFD_MODE_CNTL_RENDER_MODE__SHIFT 0 +static inline uint32_t A6XX_VFD_MODE_CNTL_RENDER_MODE(enum a6xx_render_mode val) +{ + return ((val) << A6XX_VFD_MODE_CNTL_RENDER_MODE__SHIFT) & A6XX_VFD_MODE_CNTL_RENDER_MODE__MASK; +} #define REG_A6XX_VFD_MULTIVIEW_CNTL 0x0000a008 #define A6XX_VFD_MULTIVIEW_CNTL_ENABLE 0x00000001 @@ -4913,7 +5110,7 @@ static inline uint32_t A6XX_VFD_DEST_CNTL_INSTR_REGID(uint32_t val) return ((val) << A6XX_VFD_DEST_CNTL_INSTR_REGID__SHIFT) & A6XX_VFD_DEST_CNTL_INSTR_REGID__MASK; } -#define REG_A6XX_SP_UNKNOWN_A0F8 0x0000a0f8 +#define REG_A6XX_VFD_POWER_CNTL 0x0000a0f8 #define REG_A6XX_VFD_ADDR_MODE_CNTL 0x0000a601 @@ -5091,11 +5288,11 @@ static inline uint32_t A6XX_SP_VS_CONFIG_NIBO(uint32_t val) #define REG_A6XX_SP_VS_INSTRLEN 0x0000a824 #define REG_A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET 0x0000a825 -#define A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET__MASK 0x0007ffff -#define A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET__SHIFT 0 -static inline uint32_t A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET(uint32_t val) +#define A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK 0x0007ffff +#define A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT 0 +static inline uint32_t A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET_OFFSET(uint32_t val) { - return ((val >> 11) << A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET__SHIFT) & A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET__MASK; + return ((val >> 11) << A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT) & A6XX_SP_VS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK; } #define REG_A6XX_SP_HS_CTRL_REG0 0x0000a830 @@ -5201,11 +5398,11 @@ static inline uint32_t A6XX_SP_HS_CONFIG_NIBO(uint32_t val) #define REG_A6XX_SP_HS_INSTRLEN 0x0000a83c #define REG_A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET 0x0000a83d -#define A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET__MASK 0x0007ffff -#define A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET__SHIFT 0 -static inline uint32_t A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET(uint32_t val) +#define A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK 0x0007ffff +#define A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT 0 +static inline uint32_t A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET_OFFSET(uint32_t val) { - return ((val >> 11) << A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET__SHIFT) & A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET__MASK; + return ((val >> 11) << A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT) & A6XX_SP_HS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK; } #define REG_A6XX_SP_DS_CTRL_REG0 0x0000a840 @@ -5379,11 +5576,11 @@ static inline uint32_t A6XX_SP_DS_CONFIG_NIBO(uint32_t val) #define REG_A6XX_SP_DS_INSTRLEN 0x0000a864 #define REG_A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET 0x0000a865 -#define A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET__MASK 0x0007ffff -#define A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET__SHIFT 0 -static inline uint32_t A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET(uint32_t val) +#define A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK 0x0007ffff +#define A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT 0 +static inline uint32_t A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET_OFFSET(uint32_t val) { - return ((val >> 11) << A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET__SHIFT) & A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET__MASK; + return ((val >> 11) << A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT) & A6XX_SP_DS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK; } #define REG_A6XX_SP_GS_CTRL_REG0 0x0000a870 @@ -5559,11 +5756,11 @@ static inline uint32_t A6XX_SP_GS_CONFIG_NIBO(uint32_t val) #define REG_A6XX_SP_GS_INSTRLEN 0x0000a895 #define REG_A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET 0x0000a896 -#define A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET__MASK 0x0007ffff -#define A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET__SHIFT 0 -static inline uint32_t A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET(uint32_t val) +#define A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK 0x0007ffff +#define A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT 0 +static inline uint32_t A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET_OFFSET(uint32_t val) { - return ((val >> 11) << A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET__SHIFT) & A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET__MASK; + return ((val >> 11) << A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT) & A6XX_SP_GS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK; } #define REG_A6XX_SP_VS_TEX_SAMP 0x0000a8a0 @@ -5926,11 +6123,11 @@ static inline uint32_t A6XX_SP_FS_BINDLESS_PREFETCH_CMD_TEX_ID(uint32_t val) #define REG_A6XX_SP_UNKNOWN_A9A8 0x0000a9a8 #define REG_A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET 0x0000a9a9 -#define A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET__MASK 0x0007ffff -#define A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET__SHIFT 0 -static inline uint32_t A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET(uint32_t val) +#define A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK 0x0007ffff +#define A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT 0 +static inline uint32_t A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET_OFFSET(uint32_t val) { - return ((val >> 11) << A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET__SHIFT) & A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET__MASK; + return ((val >> 11) << A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT) & A6XX_SP_FS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK; } #define REG_A6XX_SP_CS_CTRL_REG0 0x0000a9b0 @@ -6053,12 +6250,54 @@ static inline uint32_t A6XX_SP_CS_CONFIG_NIBO(uint32_t val) #define REG_A6XX_SP_CS_INSTRLEN 0x0000a9bc #define REG_A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET 0x0000a9bd -#define A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET__MASK 0x0007ffff -#define A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET__SHIFT 0 -static inline uint32_t A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET(uint32_t val) +#define A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK 0x0007ffff +#define A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT 0 +static inline uint32_t A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET_OFFSET(uint32_t val) +{ + return ((val >> 11) << A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET_OFFSET__SHIFT) & A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET_OFFSET__MASK; +} + +#define REG_A6XX_SP_CS_CNTL_0 0x0000a9c2 +#define A6XX_SP_CS_CNTL_0_WGIDCONSTID__MASK 0x000000ff +#define A6XX_SP_CS_CNTL_0_WGIDCONSTID__SHIFT 0 +static inline uint32_t A6XX_SP_CS_CNTL_0_WGIDCONSTID(uint32_t val) +{ + return ((val) << A6XX_SP_CS_CNTL_0_WGIDCONSTID__SHIFT) & A6XX_SP_CS_CNTL_0_WGIDCONSTID__MASK; +} +#define A6XX_SP_CS_CNTL_0_WGSIZECONSTID__MASK 0x0000ff00 +#define A6XX_SP_CS_CNTL_0_WGSIZECONSTID__SHIFT 8 +static inline uint32_t A6XX_SP_CS_CNTL_0_WGSIZECONSTID(uint32_t val) +{ + return ((val) << A6XX_SP_CS_CNTL_0_WGSIZECONSTID__SHIFT) & A6XX_SP_CS_CNTL_0_WGSIZECONSTID__MASK; +} +#define A6XX_SP_CS_CNTL_0_WGOFFSETCONSTID__MASK 0x00ff0000 +#define A6XX_SP_CS_CNTL_0_WGOFFSETCONSTID__SHIFT 16 +static inline uint32_t A6XX_SP_CS_CNTL_0_WGOFFSETCONSTID(uint32_t val) { - return ((val >> 11) << A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET__SHIFT) & A6XX_SP_CS_PVT_MEM_HW_STACK_OFFSET__MASK; + return ((val) << A6XX_SP_CS_CNTL_0_WGOFFSETCONSTID__SHIFT) & A6XX_SP_CS_CNTL_0_WGOFFSETCONSTID__MASK; } +#define A6XX_SP_CS_CNTL_0_LOCALIDREGID__MASK 0xff000000 +#define A6XX_SP_CS_CNTL_0_LOCALIDREGID__SHIFT 24 +static inline uint32_t A6XX_SP_CS_CNTL_0_LOCALIDREGID(uint32_t val) +{ + return ((val) << A6XX_SP_CS_CNTL_0_LOCALIDREGID__SHIFT) & A6XX_SP_CS_CNTL_0_LOCALIDREGID__MASK; +} + +#define REG_A6XX_SP_CS_CNTL_1 0x0000a9c3 +#define A6XX_SP_CS_CNTL_1_LINEARLOCALIDREGID__MASK 0x000000ff +#define A6XX_SP_CS_CNTL_1_LINEARLOCALIDREGID__SHIFT 0 +static inline uint32_t A6XX_SP_CS_CNTL_1_LINEARLOCALIDREGID(uint32_t val) +{ + return ((val) << A6XX_SP_CS_CNTL_1_LINEARLOCALIDREGID__SHIFT) & A6XX_SP_CS_CNTL_1_LINEARLOCALIDREGID__MASK; +} +#define A6XX_SP_CS_CNTL_1_SINGLE_SP_CORE 0x00000100 +#define A6XX_SP_CS_CNTL_1_THREADSIZE__MASK 0x00000200 +#define A6XX_SP_CS_CNTL_1_THREADSIZE__SHIFT 9 +static inline uint32_t A6XX_SP_CS_CNTL_1_THREADSIZE(enum a6xx_threadsize val) +{ + return ((val) << A6XX_SP_CS_CNTL_1_THREADSIZE__SHIFT) & A6XX_SP_CS_CNTL_1_THREADSIZE__MASK; +} +#define A6XX_SP_CS_CNTL_1_THREADSIZE_SCALAR 0x00000400 #define REG_A6XX_SP_FS_TEX_SAMP 0x0000a9e0 #define A6XX_SP_FS_TEX_SAMP__MASK 0xffffffff @@ -6108,8 +6347,12 @@ static inline uint32_t A6XX_SP_CS_IBO(uint32_t val) #define REG_A6XX_SP_MODE_CONTROL 0x0000ab00 #define A6XX_SP_MODE_CONTROL_CONSTANT_DEMOTION_ENABLE 0x00000001 -#define A6XX_SP_MODE_CONTROL_UNK1 0x00000002 -#define A6XX_SP_MODE_CONTROL_UNK2 0x00000004 +#define A6XX_SP_MODE_CONTROL_ISAMMODE__MASK 0x00000006 +#define A6XX_SP_MODE_CONTROL_ISAMMODE__SHIFT 1 +static inline uint32_t A6XX_SP_MODE_CONTROL_ISAMMODE(enum a6xx_isam_mode val) +{ + return ((val) << A6XX_SP_MODE_CONTROL_ISAMMODE__SHIFT) & A6XX_SP_MODE_CONTROL_ISAMMODE__MASK; +} #define A6XX_SP_MODE_CONTROL_SHARED_CONSTS_ENABLE 0x00000008 #define REG_A6XX_SP_FS_CONFIG 0x0000ab04 @@ -6177,7 +6420,7 @@ static inline uint32_t A6XX_SP_2D_DST_FORMAT_MASK(uint32_t val) #define REG_A6XX_SP_NC_MODE_CNTL 0x0000ae02 -#define REG_A6XX_SP_UNKNOWN_AE03 0x0000ae03 +#define REG_A6XX_SP_CHICKEN_BITS 0x0000ae03 #define REG_A6XX_SP_FLOAT_CNTL 0x0000ae04 #define A6XX_SP_FLOAT_CNTL_F16_NO_INF 0x00000008 @@ -6192,6 +6435,8 @@ static inline uint32_t A6XX_SP_2D_DST_FORMAT_MASK(uint32_t val) static inline uint32_t REG_A6XX_SP_PERFCTR_SP_SEL(uint32_t i0) { return 0x0000ae10 + 0x1*i0; } +#define REG_A6XX_SP_CONTEXT_SWITCH_GFX_PREEMPTION_SAFE_MODE 0x0000be22 + #define REG_A6XX_SP_PS_TP_BORDER_COLOR_BASE_ADDR 0x0000b180 #define A6XX_SP_PS_TP_BORDER_COLOR_BASE_ADDR__MASK 0xffffffff #define A6XX_SP_PS_TP_BORDER_COLOR_BASE_ADDR__SHIFT 0 @@ -6357,7 +6602,19 @@ static inline uint32_t A6XX_SP_TP_WINDOW_OFFSET_Y(uint32_t val) return ((val) << A6XX_SP_TP_WINDOW_OFFSET_Y__SHIFT) & A6XX_SP_TP_WINDOW_OFFSET_Y__MASK; } -#define REG_A6XX_SP_TP_UNKNOWN_B309 0x0000b309 +#define REG_A6XX_SP_TP_MODE_CNTL 0x0000b309 +#define A6XX_SP_TP_MODE_CNTL_ISAMMODE__MASK 0x00000003 +#define A6XX_SP_TP_MODE_CNTL_ISAMMODE__SHIFT 0 +static inline uint32_t A6XX_SP_TP_MODE_CNTL_ISAMMODE(enum a6xx_isam_mode val) +{ + return ((val) << A6XX_SP_TP_MODE_CNTL_ISAMMODE__SHIFT) & A6XX_SP_TP_MODE_CNTL_ISAMMODE__MASK; +} +#define A6XX_SP_TP_MODE_CNTL_UNK3__MASK 0x000000fc +#define A6XX_SP_TP_MODE_CNTL_UNK3__SHIFT 2 +static inline uint32_t A6XX_SP_TP_MODE_CNTL_UNK3(uint32_t val) +{ + return ((val) << A6XX_SP_TP_MODE_CNTL_UNK3__SHIFT) & A6XX_SP_TP_MODE_CNTL_UNK3__MASK; +} #define REG_A6XX_SP_PS_2D_SRC_INFO 0x0000b4c0 #define A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT__MASK 0x000000ff @@ -6499,7 +6756,7 @@ static inline uint32_t A6XX_SP_WINDOW_OFFSET_Y(uint32_t val) return ((val) << A6XX_SP_WINDOW_OFFSET_Y__SHIFT) & A6XX_SP_WINDOW_OFFSET_Y__MASK; } -#define REG_A6XX_TPL1_UNKNOWN_B600 0x0000b600 +#define REG_A6XX_TPL1_DBG_ECO_CNTL 0x0000b600 #define REG_A6XX_TPL1_ADDR_MODE_CNTL 0x0000b601 @@ -6687,17 +6944,17 @@ static inline uint32_t A6XX_HLSQ_CONTROL_4_REG_ZWCOORDREGID(uint32_t val) } #define REG_A6XX_HLSQ_CONTROL_5_REG 0x0000b986 -#define A6XX_HLSQ_CONTROL_5_REG_UNK0__MASK 0x000000ff -#define A6XX_HLSQ_CONTROL_5_REG_UNK0__SHIFT 0 -static inline uint32_t A6XX_HLSQ_CONTROL_5_REG_UNK0(uint32_t val) +#define A6XX_HLSQ_CONTROL_5_REG_LINELENGTHREGID__MASK 0x000000ff +#define A6XX_HLSQ_CONTROL_5_REG_LINELENGTHREGID__SHIFT 0 +static inline uint32_t A6XX_HLSQ_CONTROL_5_REG_LINELENGTHREGID(uint32_t val) { - return ((val) << A6XX_HLSQ_CONTROL_5_REG_UNK0__SHIFT) & A6XX_HLSQ_CONTROL_5_REG_UNK0__MASK; + return ((val) << A6XX_HLSQ_CONTROL_5_REG_LINELENGTHREGID__SHIFT) & A6XX_HLSQ_CONTROL_5_REG_LINELENGTHREGID__MASK; } -#define A6XX_HLSQ_CONTROL_5_REG_UNK8__MASK 0x0000ff00 -#define A6XX_HLSQ_CONTROL_5_REG_UNK8__SHIFT 8 -static inline uint32_t A6XX_HLSQ_CONTROL_5_REG_UNK8(uint32_t val) +#define A6XX_HLSQ_CONTROL_5_REG_FOVEATIONQUALITYREGID__MASK 0x0000ff00 +#define A6XX_HLSQ_CONTROL_5_REG_FOVEATIONQUALITYREGID__SHIFT 8 +static inline uint32_t A6XX_HLSQ_CONTROL_5_REG_FOVEATIONQUALITYREGID(uint32_t val) { - return ((val) << A6XX_HLSQ_CONTROL_5_REG_UNK8__SHIFT) & A6XX_HLSQ_CONTROL_5_REG_UNK8__MASK; + return ((val) << A6XX_HLSQ_CONTROL_5_REG_FOVEATIONQUALITYREGID__SHIFT) & A6XX_HLSQ_CONTROL_5_REG_FOVEATIONQUALITYREGID__MASK; } #define REG_A6XX_HLSQ_CS_CNTL 0x0000b987 @@ -6847,6 +7104,16 @@ static inline uint32_t REG_A6XX_HLSQ_CS_BINDLESS_BASE(uint32_t i0) { return 0x00 static inline uint32_t REG_A6XX_HLSQ_CS_BINDLESS_BASE_ADDR(uint32_t i0) { return 0x0000b9c0 + 0x2*i0; } +#define REG_A6XX_HLSQ_CS_UNKNOWN_B9D0 0x0000b9d0 +#define A6XX_HLSQ_CS_UNKNOWN_B9D0_SHARED_SIZE__MASK 0x0000001f +#define A6XX_HLSQ_CS_UNKNOWN_B9D0_SHARED_SIZE__SHIFT 0 +static inline uint32_t A6XX_HLSQ_CS_UNKNOWN_B9D0_SHARED_SIZE(uint32_t val) +{ + return ((val) << A6XX_HLSQ_CS_UNKNOWN_B9D0_SHARED_SIZE__SHIFT) & A6XX_HLSQ_CS_UNKNOWN_B9D0_SHARED_SIZE__MASK; +} +#define A6XX_HLSQ_CS_UNKNOWN_B9D0_UNK5 0x00000020 +#define A6XX_HLSQ_CS_UNKNOWN_B9D0_UNK6 0x00000040 + #define REG_A6XX_HLSQ_DRAW_CMD 0x0000bb00 #define A6XX_HLSQ_DRAW_CMD_STATE_ID__MASK 0x000000ff #define A6XX_HLSQ_DRAW_CMD_STATE_ID__SHIFT 0 @@ -6943,6 +7210,8 @@ static inline uint32_t A6XX_HLSQ_2D_EVENT_CMD_EVENT(enum vgt_event_type val) static inline uint32_t REG_A6XX_HLSQ_PERFCTR_HLSQ_SEL(uint32_t i0) { return 0x0000be10 + 0x1*i0; } +#define REG_A6XX_HLSQ_CONTEXT_SWITCH_GFX_PREEMPTION_SAFE_MODE 0x0000be22 + #define REG_A6XX_CP_EVENT_START 0x0000d600 #define A6XX_CP_EVENT_START_STATE_ID__MASK 0x000000ff #define A6XX_CP_EVENT_START_STATE_ID__SHIFT 0 @@ -7021,7 +7290,7 @@ static inline uint32_t A6XX_TEX_SAMP_0_LOD_BIAS(float val) } #define REG_A6XX_TEX_SAMP_1 0x00000001 -#define A6XX_TEX_SAMP_1_UNK0 0x00000001 +#define A6XX_TEX_SAMP_1_CLAMPENABLE 0x00000001 #define A6XX_TEX_SAMP_1_COMPARE_FUNC__MASK 0x0000000e #define A6XX_TEX_SAMP_1_COMPARE_FUNC__SHIFT 1 static inline uint32_t A6XX_TEX_SAMP_1_COMPARE_FUNC(enum adreno_compare_func val) @@ -7135,7 +7404,7 @@ static inline uint32_t A6XX_TEX_CONST_1_HEIGHT(uint32_t val) } #define REG_A6XX_TEX_CONST_2 0x00000002 -#define A6XX_TEX_CONST_2_UNK4 0x00000010 +#define A6XX_TEX_CONST_2_BUFFER 0x00000010 #define A6XX_TEX_CONST_2_PITCHALIGN__MASK 0x0000000f #define A6XX_TEX_CONST_2_PITCHALIGN__SHIFT 0 static inline uint32_t A6XX_TEX_CONST_2_PITCHALIGN(uint32_t val) @@ -7148,13 +7417,12 @@ static inline uint32_t A6XX_TEX_CONST_2_PITCH(uint32_t val) { return ((val) << A6XX_TEX_CONST_2_PITCH__SHIFT) & A6XX_TEX_CONST_2_PITCH__MASK; } -#define A6XX_TEX_CONST_2_TYPE__MASK 0x60000000 +#define A6XX_TEX_CONST_2_TYPE__MASK 0xe0000000 #define A6XX_TEX_CONST_2_TYPE__SHIFT 29 static inline uint32_t A6XX_TEX_CONST_2_TYPE(enum a6xx_tex_type val) { return ((val) << A6XX_TEX_CONST_2_TYPE__SHIFT) & A6XX_TEX_CONST_2_TYPE__MASK; } -#define A6XX_TEX_CONST_2_UNK31 0x80000000 #define REG_A6XX_TEX_CONST_3 0x00000003 #define A6XX_TEX_CONST_3_ARRAY_PITCH__MASK 0x00003fff @@ -7256,104 +7524,6 @@ static inline uint32_t A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(uint32_t val) #define REG_A6XX_TEX_CONST_15 0x0000000f -#define REG_A6XX_IBO_0 0x00000000 -#define A6XX_IBO_0_TILE_MODE__MASK 0x00000003 -#define A6XX_IBO_0_TILE_MODE__SHIFT 0 -static inline uint32_t A6XX_IBO_0_TILE_MODE(enum a6xx_tile_mode val) -{ - return ((val) << A6XX_IBO_0_TILE_MODE__SHIFT) & A6XX_IBO_0_TILE_MODE__MASK; -} -#define A6XX_IBO_0_FMT__MASK 0x3fc00000 -#define A6XX_IBO_0_FMT__SHIFT 22 -static inline uint32_t A6XX_IBO_0_FMT(enum a6xx_format val) -{ - return ((val) << A6XX_IBO_0_FMT__SHIFT) & A6XX_IBO_0_FMT__MASK; -} - -#define REG_A6XX_IBO_1 0x00000001 -#define A6XX_IBO_1_WIDTH__MASK 0x00007fff -#define A6XX_IBO_1_WIDTH__SHIFT 0 -static inline uint32_t A6XX_IBO_1_WIDTH(uint32_t val) -{ - return ((val) << A6XX_IBO_1_WIDTH__SHIFT) & A6XX_IBO_1_WIDTH__MASK; -} -#define A6XX_IBO_1_HEIGHT__MASK 0x3fff8000 -#define A6XX_IBO_1_HEIGHT__SHIFT 15 -static inline uint32_t A6XX_IBO_1_HEIGHT(uint32_t val) -{ - return ((val) << A6XX_IBO_1_HEIGHT__SHIFT) & A6XX_IBO_1_HEIGHT__MASK; -} - -#define REG_A6XX_IBO_2 0x00000002 -#define A6XX_IBO_2_UNK4 0x00000010 -#define A6XX_IBO_2_PITCH__MASK 0x1fffff80 -#define A6XX_IBO_2_PITCH__SHIFT 7 -static inline uint32_t A6XX_IBO_2_PITCH(uint32_t val) -{ - return ((val) << A6XX_IBO_2_PITCH__SHIFT) & A6XX_IBO_2_PITCH__MASK; -} -#define A6XX_IBO_2_TYPE__MASK 0x60000000 -#define A6XX_IBO_2_TYPE__SHIFT 29 -static inline uint32_t A6XX_IBO_2_TYPE(enum a6xx_tex_type val) -{ - return ((val) << A6XX_IBO_2_TYPE__SHIFT) & A6XX_IBO_2_TYPE__MASK; -} -#define A6XX_IBO_2_UNK31 0x80000000 - -#define REG_A6XX_IBO_3 0x00000003 -#define A6XX_IBO_3_ARRAY_PITCH__MASK 0x00003fff -#define A6XX_IBO_3_ARRAY_PITCH__SHIFT 0 -static inline uint32_t A6XX_IBO_3_ARRAY_PITCH(uint32_t val) -{ - return ((val >> 12) << A6XX_IBO_3_ARRAY_PITCH__SHIFT) & A6XX_IBO_3_ARRAY_PITCH__MASK; -} -#define A6XX_IBO_3_UNK27 0x08000000 -#define A6XX_IBO_3_FLAG 0x10000000 - -#define REG_A6XX_IBO_4 0x00000004 -#define A6XX_IBO_4_BASE_LO__MASK 0xffffffff -#define A6XX_IBO_4_BASE_LO__SHIFT 0 -static inline uint32_t A6XX_IBO_4_BASE_LO(uint32_t val) -{ - return ((val) << A6XX_IBO_4_BASE_LO__SHIFT) & A6XX_IBO_4_BASE_LO__MASK; -} - -#define REG_A6XX_IBO_5 0x00000005 -#define A6XX_IBO_5_BASE_HI__MASK 0x0001ffff -#define A6XX_IBO_5_BASE_HI__SHIFT 0 -static inline uint32_t A6XX_IBO_5_BASE_HI(uint32_t val) -{ - return ((val) << A6XX_IBO_5_BASE_HI__SHIFT) & A6XX_IBO_5_BASE_HI__MASK; -} -#define A6XX_IBO_5_DEPTH__MASK 0x3ffe0000 -#define A6XX_IBO_5_DEPTH__SHIFT 17 -static inline uint32_t A6XX_IBO_5_DEPTH(uint32_t val) -{ - return ((val) << A6XX_IBO_5_DEPTH__SHIFT) & A6XX_IBO_5_DEPTH__MASK; -} - -#define REG_A6XX_IBO_6 0x00000006 - -#define REG_A6XX_IBO_7 0x00000007 - -#define REG_A6XX_IBO_8 0x00000008 - -#define REG_A6XX_IBO_9 0x00000009 -#define A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH__MASK 0x0001ffff -#define A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH__SHIFT 0 -static inline uint32_t A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH(uint32_t val) -{ - return ((val >> 4) << A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH__SHIFT) & A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH__MASK; -} - -#define REG_A6XX_IBO_10 0x0000000a -#define A6XX_IBO_10_FLAG_BUFFER_PITCH__MASK 0x0000007f -#define A6XX_IBO_10_FLAG_BUFFER_PITCH__SHIFT 0 -static inline uint32_t A6XX_IBO_10_FLAG_BUFFER_PITCH(uint32_t val) -{ - return ((val >> 6) << A6XX_IBO_10_FLAG_BUFFER_PITCH__SHIFT) & A6XX_IBO_10_FLAG_BUFFER_PITCH__MASK; -} - #define REG_A6XX_UBO_0 0x00000000 #define A6XX_UBO_0_BASE_LO__MASK 0xffffffff #define A6XX_UBO_0_BASE_LO__SHIFT 0 diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h index 811589215834..4a3230978c0e 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-06-21 15:24:24) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14609 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 69086 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84231 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a4xx.xml ( 113358 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a5xx.xml ( 149512 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx.xml ( 184954 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-07-22 15:21:56) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 17cfad6424db..83c31b2ad865 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -10,7 +10,6 @@ #include <linux/bitfield.h> #include <linux/devfreq.h> -#include <linux/nvmem-consumer.h> #include <linux/soc/qcom/llcc-qcom.h> #define GPU_PAS_ID 13 @@ -102,6 +101,7 @@ static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter, static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, struct msm_ringbuffer *ring, struct msm_file_private *ctx) { + bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1; phys_addr_t ttbr; u32 asid; u64 memptr = rbmemptr(ring, ttbr0); @@ -112,6 +112,15 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid)) return; + if (!sysprof) { + /* Turn off protected mode to write to special registers */ + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 0); + + OUT_PKT4(ring, REG_A6XX_RBBM_PERFCTR_SRAM_INIT_CMD, 1); + OUT_RING(ring, 1); + } + /* Execute the table update */ OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 4); OUT_RING(ring, CP_SMMU_TABLE_UPDATE_0_TTBR0_LO(lower_32_bits(ttbr))); @@ -138,6 +147,25 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, OUT_PKT7(ring, CP_EVENT_WRITE, 1); OUT_RING(ring, 0x31); + + if (!sysprof) { + /* + * Wait for SRAM clear after the pgtable update, so the + * two can happen in parallel: + */ + OUT_PKT7(ring, CP_WAIT_REG_MEM, 6); + OUT_RING(ring, CP_WAIT_REG_MEM_0_FUNCTION(WRITE_EQ)); + OUT_RING(ring, CP_WAIT_REG_MEM_1_POLL_ADDR_LO( + REG_A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS)); + OUT_RING(ring, CP_WAIT_REG_MEM_2_POLL_ADDR_HI(0)); + OUT_RING(ring, CP_WAIT_REG_MEM_3_REF(0x1)); + OUT_RING(ring, CP_WAIT_REG_MEM_4_MASK(0x1)); + OUT_RING(ring, CP_WAIT_REG_MEM_5_DELAY_LOOP_CYCLES(0)); + + /* Re-enable protected mode: */ + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 1); + } } static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) @@ -655,19 +683,23 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); const u32 *regs = a6xx_protect; - unsigned i, count = ARRAY_SIZE(a6xx_protect), count_max = 32; - - BUILD_BUG_ON(ARRAY_SIZE(a6xx_protect) > 32); - BUILD_BUG_ON(ARRAY_SIZE(a650_protect) > 48); + unsigned i, count, count_max; if (adreno_is_a650(adreno_gpu)) { regs = a650_protect; count = ARRAY_SIZE(a650_protect); count_max = 48; + BUILD_BUG_ON(ARRAY_SIZE(a650_protect) > 48); } else if (adreno_is_a660_family(adreno_gpu)) { regs = a660_protect; count = ARRAY_SIZE(a660_protect); count_max = 48; + BUILD_BUG_ON(ARRAY_SIZE(a660_protect) > 48); + } else { + regs = a6xx_protect; + count = ARRAY_SIZE(a6xx_protect); + count_max = 32; + BUILD_BUG_ON(ARRAY_SIZE(a6xx_protect) > 32); } /* @@ -1506,7 +1538,7 @@ static void a6xx_llc_slices_init(struct platform_device *pdev, if (a6xx_gpu->have_mmu500) a6xx_gpu->llc_mmio = NULL; else - a6xx_gpu->llc_mmio = msm_ioremap(pdev, "cx_mem", "gpu_cx"); + a6xx_gpu->llc_mmio = msm_ioremap(pdev, "cx_mem"); a6xx_gpu->llc_slice = llcc_slice_getd(LLCC_GPU); a6xx_gpu->htw_llc_slice = llcc_slice_getd(LLCC_GPUHTW); @@ -1736,6 +1768,18 @@ static u32 a618_get_speed_bin(u32 fuse) return UINT_MAX; } +static u32 adreno_7c3_get_speed_bin(u32 fuse) +{ + if (fuse == 0) + return 0; + else if (fuse == 117) + return 0; + else if (fuse == 190) + return 1; + + return UINT_MAX; +} + static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) { u32 val = UINT_MAX; @@ -1743,6 +1787,9 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) if (adreno_cmp_rev(ADRENO_REV(6, 1, 8, ANY_ID), rev)) val = a618_get_speed_bin(fuse); + if (adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), rev)) + val = adreno_7c3_get_speed_bin(fuse); + if (val == UINT_MAX) { DRM_DEV_ERROR(dev, "missing support for speed-bin: %u. Some OPPs may not be supported by hardware", @@ -1759,7 +1806,7 @@ static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) u32 speedbin; int ret; - ret = nvmem_cell_read_variable_le_u32(dev, "speed_bin", &speedbin); + ret = adreno_read_speedbin(dev, &speedbin); /* * -ENOENT means that the platform doesn't support speedbin which is * fine @@ -1786,6 +1833,7 @@ done: static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, + .set_param = adreno_set_param, .hw_init = a6xx_hw_init, .pm_suspend = a6xx_pm_suspend, .pm_resume = a6xx_pm_resume, diff --git a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h index c9389d9fb599..abb037ccc02b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h @@ -8,19 +8,19 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-06-21 15:24:24) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14609 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 69086 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84231 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a4xx.xml ( 113358 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a5xx.xml ( 149512 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx.xml ( 184954 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-07-22 15:21:56) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) @@ -205,6 +205,11 @@ enum a5xx_address_mode { ADDR_64B = 1, }; +enum a5xx_line_mode { + BRESENHAM = 0, + RECTANGULAR = 1, +}; + #define REG_AXXX_CP_RB_BASE 0x000001c0 #define REG_AXXX_CP_RB_CNTL 0x000001c1 diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index fb261930ad1c..89cfd84760d7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -318,7 +318,6 @@ static const struct adreno_info gpulist[] = { .hwcg = a660_hwcg, }, { .rev = ADRENO_REV(6, 3, 5, ANY_ID), - .name = "Adreno 7c Gen 3", .fw = { [ADRENO_FW_SQE] = "a660_sqe.fw", [ADRENO_FW_GMU] = "a660_gmu.bin", diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index f33cfa4ef1c8..9efc84929be0 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -14,6 +14,7 @@ #include <linux/pm_opp.h> #include <linux/slab.h> #include <linux/soc/qcom/mdt_loader.h> +#include <linux/nvmem-consumer.h> #include <soc/qcom/ocmem.h> #include "adreno_gpu.h" #include "a6xx_gpu.h" @@ -227,7 +228,8 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu, return aspace; } -int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) +int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, + uint32_t param, uint64_t *value) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -242,10 +244,12 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) *value = !adreno_is_a650_family(adreno_gpu) ? 0x100000 : 0; return 0; case MSM_PARAM_CHIP_ID: - *value = adreno_gpu->rev.patchid | - (adreno_gpu->rev.minor << 8) | - (adreno_gpu->rev.major << 16) | - (adreno_gpu->rev.core << 24); + *value = (uint64_t)adreno_gpu->rev.patchid | + ((uint64_t)adreno_gpu->rev.minor << 8) | + ((uint64_t)adreno_gpu->rev.major << 16) | + ((uint64_t)adreno_gpu->rev.core << 24); + if (!adreno_gpu->info->revn) + *value |= ((uint64_t) adreno_gpu->speedbin) << 32; return 0; case MSM_PARAM_MAX_FREQ: *value = adreno_gpu->base.fast_rate; @@ -268,7 +272,7 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) *value = 0; return 0; case MSM_PARAM_FAULTS: - *value = gpu->global_faults; + *value = gpu->global_faults + ctx->aspace->faults; return 0; case MSM_PARAM_SUSPENDS: *value = gpu->suspend_count; @@ -279,6 +283,20 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) } } +int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx, + uint32_t param, uint64_t value) +{ + switch (param) { + case MSM_PARAM_SYSPROF: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + return msm_file_private_set_sysprof(ctx, gpu, value); + default: + DBG("%s: invalid param: %u", gpu->name, param); + return -EINVAL; + } +} + const struct firmware * adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname) { @@ -921,6 +939,11 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem) adreno_ocmem->hdl); } +int adreno_read_speedbin(struct device *dev, u32 *speedbin) +{ + return nvmem_cell_read_variable_le_u32(dev, "speed_bin", speedbin); +} + int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs, int nr_rings) @@ -929,12 +952,28 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_platform_config *config = dev->platform_data; struct msm_gpu_config adreno_gpu_config = { 0 }; struct msm_gpu *gpu = &adreno_gpu->base; + struct adreno_rev *rev = &config->rev; + const char *gpu_name; + u32 speedbin; adreno_gpu->funcs = funcs; adreno_gpu->info = adreno_info(config->rev); adreno_gpu->gmem = adreno_gpu->info->gmem; adreno_gpu->revn = adreno_gpu->info->revn; - adreno_gpu->rev = config->rev; + adreno_gpu->rev = *rev; + + if (adreno_read_speedbin(dev, &speedbin) || !speedbin) + speedbin = 0xffff; + adreno_gpu->speedbin = (uint16_t) (0xffff & speedbin); + + gpu_name = adreno_gpu->info->name; + if (!gpu_name) { + gpu_name = devm_kasprintf(dev, GFP_KERNEL, "%d.%d.%d.%d", + rev->core, rev->major, rev->minor, + rev->patchid); + if (!gpu_name) + return -ENOMEM; + } adreno_gpu_config.ioname = "kgsl_3d0_reg_memory"; @@ -948,7 +987,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, pm_runtime_enable(dev); return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, - adreno_gpu->info->name, &adreno_gpu_config); + gpu_name, &adreno_gpu_config); } void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index cffabe7d33c1..0490c5fbb780 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -80,6 +80,7 @@ struct adreno_gpu { const struct adreno_info *info; uint32_t gmem; /* actual gmem size */ uint32_t revn; /* numeric revision name */ + uint16_t speedbin; const struct adreno_gpu_funcs *funcs; /* interesting register offsets to dump: */ @@ -279,7 +280,10 @@ static inline int adreno_is_a650_family(struct adreno_gpu *gpu) adreno_is_a660_family(gpu); } -int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value); +int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, + uint32_t param, uint64_t *value); +int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx, + uint32_t param, uint64_t value); const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname); struct drm_gem_object *adreno_fw_create_bo(struct msm_gpu *gpu, @@ -324,6 +328,8 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu, void adreno_set_llc_attributes(struct iommu_domain *iommu); +int adreno_read_speedbin(struct device *dev, u32 *speedbin); + /* * For a5xx and a6xx targets load the zap shader that is used to pull the GPU * out of secure mode diff --git a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h index e832ae4b937a..7aecf920f9b9 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h @@ -8,21 +8,21 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13) - -Copyright (C) 2013-2021 by the following authors: +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-06-21 15:24:24) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14609 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 69086 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84231 bytes, from 2021-11-24 23:05:10) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a4xx.xml ( 113358 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a5xx.xml ( 149512 bytes, from 2022-01-31 23:06:21) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx.xml ( 184954 bytes, from 2022-03-03 16:41:33) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-07-22 15:21:56) + +Copyright (C) 2013-2022 by the following authors: - Rob Clark <[email protected]> (robclark) - Ilia Mirkin <[email protected]> (imirkin) @@ -299,6 +299,8 @@ enum adreno_pm4_type3_packets { CP_SET_BIN_DATA5_OFFSET = 46, CP_SET_CTXSWITCH_IB = 85, CP_REG_WRITE = 109, + CP_START_BIN = 80, + CP_END_BIN = 81, }; enum adreno_state_block { @@ -438,7 +440,7 @@ enum cp_blit_cmd { BLIT_OP_SCALE = 3, }; -enum a6xx_render_mode { +enum a6xx_marker { RM6_BYPASS = 1, RM6_BINNING = 2, RM6_GMEM = 4, @@ -2150,13 +2152,13 @@ static inline uint32_t A5XX_CP_EXEC_CS_INDIRECT_3_LOCALSIZEZ(uint32_t val) #define REG_A6XX_CP_SET_MARKER_0 0x00000000 #define A6XX_CP_SET_MARKER_0_MODE__MASK 0x000001ff #define A6XX_CP_SET_MARKER_0_MODE__SHIFT 0 -static inline uint32_t A6XX_CP_SET_MARKER_0_MODE(enum a6xx_render_mode val) +static inline uint32_t A6XX_CP_SET_MARKER_0_MODE(enum a6xx_marker val) { return ((val) << A6XX_CP_SET_MARKER_0_MODE__SHIFT) & A6XX_CP_SET_MARKER_0_MODE__MASK; } #define A6XX_CP_SET_MARKER_0_MARKER__MASK 0x0000000f #define A6XX_CP_SET_MARKER_0_MARKER__SHIFT 0 -static inline uint32_t A6XX_CP_SET_MARKER_0_MARKER(enum a6xx_render_mode val) +static inline uint32_t A6XX_CP_SET_MARKER_0_MARKER(enum a6xx_marker val) { return ((val) << A6XX_CP_SET_MARKER_0_MARKER__SHIFT) & A6XX_CP_SET_MARKER_0_MARKER__MASK; } @@ -2351,5 +2353,13 @@ static inline uint32_t CP_SMMU_TABLE_UPDATE_3_CONTEXTBANK(uint32_t val) return ((val) << CP_SMMU_TABLE_UPDATE_3_CONTEXTBANK__SHIFT) & CP_SMMU_TABLE_UPDATE_3_CONTEXTBANK__MASK; } +#define REG_CP_START_BIN_BIN_COUNT 0x00000000 + +#define REG_CP_START_BIN_PREFIX_ADDR 0x00000001 + +#define REG_CP_START_BIN_PREFIX_DWORDS 0x00000003 + +#define REG_CP_START_BIN_BODY_DWORDS 0x00000004 + #endif /* ADRENO_PM4_XML */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index 60fe06018581..a7492dd6ed65 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -284,17 +284,6 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc) } } -static int _dpu_core_perf_set_core_clk_rate(struct dpu_kms *kms, u64 rate) -{ - struct dss_clk *core_clk = kms->perf.core_clk; - - if (core_clk->max_rate && (rate > core_clk->max_rate)) - rate = core_clk->max_rate; - - core_clk->rate = rate; - return dev_pm_opp_set_rate(&kms->pdev->dev, core_clk->rate); -} - static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms) { u64 clk_rate = kms->perf.perf_tune.min_core_clk; @@ -306,7 +295,7 @@ static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms) dpu_cstate = to_dpu_crtc_state(crtc->state); clk_rate = max(dpu_cstate->new_perf.core_clk_rate, clk_rate); - clk_rate = clk_round_rate(kms->perf.core_clk->clk, + clk_rate = clk_round_rate(kms->perf.core_clk, clk_rate); } } @@ -405,10 +394,10 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc, trace_dpu_core_perf_update_clk(kms->dev, stop_req, clk_rate); - ret = _dpu_core_perf_set_core_clk_rate(kms, clk_rate); + clk_rate = min(clk_rate, kms->perf.max_core_clk_rate); + ret = dev_pm_opp_set_rate(&kms->pdev->dev, clk_rate); if (ret) { - DPU_ERROR("failed to set %s clock rate %llu\n", - kms->perf.core_clk->clk_name, clk_rate); + DPU_ERROR("failed to set core clock rate %llu\n", clk_rate); return ret; } @@ -529,13 +518,13 @@ void dpu_core_perf_destroy(struct dpu_core_perf *perf) int dpu_core_perf_init(struct dpu_core_perf *perf, struct drm_device *dev, struct dpu_mdss_cfg *catalog, - struct dss_clk *core_clk) + struct clk *core_clk) { perf->dev = dev; perf->catalog = catalog; perf->core_clk = core_clk; - perf->max_core_clk_rate = core_clk->max_rate; + perf->max_core_clk_rate = clk_get_rate(core_clk); if (!perf->max_core_clk_rate) { DPU_DEBUG("optional max core clk rate, use default\n"); perf->max_core_clk_rate = DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h index cf4b9b5964c6..8dfcc6db7176 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h @@ -56,7 +56,7 @@ struct dpu_core_perf_tune { * @dev: Pointer to drm device * @debugfs_root: top level debug folder * @catalog: Pointer to catalog configuration - * @core_clk: Pointer to core clock structure + * @core_clk: Pointer to the core clock * @core_clk_rate: current core clock rate * @max_core_clk_rate: maximum allowable core clock rate * @perf_tune: debug control for performance tuning @@ -69,7 +69,7 @@ struct dpu_core_perf { struct drm_device *dev; struct dentry *debugfs_root; struct dpu_mdss_cfg *catalog; - struct dss_clk *core_clk; + struct clk *core_clk; u64 core_clk_rate; u64 max_core_clk_rate; struct dpu_core_perf_tune perf_tune; @@ -120,7 +120,7 @@ void dpu_core_perf_destroy(struct dpu_core_perf *perf); int dpu_core_perf_init(struct dpu_core_perf *perf, struct drm_device *dev, struct dpu_mdss_cfg *catalog, - struct dss_clk *core_clk); + struct clk *core_clk); struct dpu_kms; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index e7c9fe1a250f..7763558ef566 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -408,7 +408,7 @@ 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); - _dpu_crtc_program_lm_output_roi(crtc); + _dpu_crtc_program_lm_output_roi(crtc); } /** @@ -1046,6 +1046,20 @@ struct plane_state { u32 pipe_id; }; +static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate) +{ + struct drm_crtc *crtc = cstate->crtc; + struct drm_encoder *encoder; + + drm_for_each_encoder_mask (encoder, crtc->dev, cstate->encoder_mask) { + if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_CMD) { + return true; + } + } + + return false; +} + static int dpu_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { @@ -1066,6 +1080,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, const struct drm_plane_state *pipe_staged[SSPP_MAX]; int left_zpos_cnt = 0, right_zpos_cnt = 0; struct drm_rect crtc_rect = { 0 }; + bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state); pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL); @@ -1097,6 +1112,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, /* get plane state for all drm planes associated with crtc state */ drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { + struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate); struct drm_rect dst, clip = crtc_rect; if (IS_ERR_OR_NULL(pstate)) { @@ -1108,11 +1124,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, if (cnt >= DPU_STAGE_MAX * 4) continue; - pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate); + pstates[cnt].dpu_pstate = dpu_pstate; pstates[cnt].drm_pstate = pstate; pstates[cnt].stage = pstate->normalized_zpos; pstates[cnt].pipe_id = dpu_plane_pipe(plane); + dpu_pstate->needs_dirtyfb = needs_dirtyfb; + if (pipe_staged[pstates[cnt].pipe_id]) { multirect_plane[multirect_count].r0 = pipe_staged[pstates[cnt].pipe_id]; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 1e648db439f9..3940b9c6323b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -127,7 +127,6 @@ enum dpu_enc_rc_states { * Virtual encoder registers itself with the DRM Framework as the encoder. * @base: drm_encoder base class for registration with DRM * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes - * @bus_scaling_client: Client handle to the bus scaling interface * @enabled: True if the encoder is active, protected by enc_lock * @num_phys_encs: Actual number of physical encoders contained. * @phys_encs: Container of physical encoders managed. @@ -144,6 +143,7 @@ enum dpu_enc_rc_states { * link between encoder/crtc. However in this case we need * to track crtc in the disable() hook which is called * _after_ encoder_mask is cleared. + * @connector: If a mode is set, cached pointer to the active connector * @crtc_kickoff_cb: Callback into CRTC that will flush & start * all CTL paths * @crtc_kickoff_cb_data: Opaque user data given to crtc_kickoff_cb @@ -168,12 +168,10 @@ enum dpu_enc_rc_states { * @vsync_event_work: worker to handle vsync event for autorefresh * @topology: topology of the display * @idle_timeout: idle timeout duration in milliseconds - * @dp: msm_dp pointer, for DP encoders */ struct dpu_encoder_virt { struct drm_encoder base; spinlock_t enc_spinlock; - uint32_t bus_scaling_client; bool enabled; @@ -186,6 +184,7 @@ struct dpu_encoder_virt { bool intfs_swapped; struct drm_crtc *crtc; + struct drm_connector *connector; struct dentry *debugfs_root; struct mutex enc_lock; @@ -207,8 +206,6 @@ struct dpu_encoder_virt { struct msm_display_topology topology; u32 idle_timeout; - - struct msm_dp *dp; }; #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base) @@ -420,26 +417,6 @@ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc) return linecount; } -void dpu_encoder_get_hw_resources(struct drm_encoder *drm_enc, - struct dpu_encoder_hw_resources *hw_res) -{ - struct dpu_encoder_virt *dpu_enc = NULL; - int i = 0; - - dpu_enc = to_dpu_encoder_virt(drm_enc); - DPU_DEBUG_ENC(dpu_enc, "\n"); - - /* Query resources used by phys encs, expected to be without overlap */ - memset(hw_res, 0, sizeof(*hw_res)); - - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; - - if (phys->ops.get_hw_resources) - phys->ops.get_hw_resources(phys, hw_res); - } -} - static void dpu_encoder_destroy(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc = NULL; @@ -607,10 +584,6 @@ static int dpu_encoder_virt_atomic_check( if (phys->ops.atomic_check) ret = phys->ops.atomic_check(phys, crtc_state, conn_state); - else if (phys->ops.mode_fixup) - if (!phys->ops.mode_fixup(phys, mode, adj_mode)) - ret = -EINVAL; - if (ret) { DPU_ERROR_ENC(dpu_enc, "mode unsupported, phys idx %d\n", i); @@ -956,16 +929,13 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, return 0; } -static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, - struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) +static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) { struct dpu_encoder_virt *dpu_enc; struct msm_drm_private *priv; struct dpu_kms *dpu_kms; - struct list_head *connector_list; - struct drm_connector *conn = NULL, *conn_iter; - struct drm_crtc *drm_crtc; struct dpu_crtc_state *cstate; struct dpu_global_state *global_state; struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; @@ -973,7 +943,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL }; int num_lm, num_ctl, num_pp; - int i, j; + int i; if (!drm_enc) { DPU_ERROR("invalid encoder\n"); @@ -985,7 +955,6 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, priv = drm_enc->dev->dev_private; dpu_kms = to_dpu_kms(priv->kms); - connector_list = &dpu_kms->dev->mode_config.connector_list; global_state = dpu_kms_get_existing_global_state(dpu_kms); if (IS_ERR_OR_NULL(global_state)) { @@ -995,22 +964,6 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, trace_dpu_enc_mode_set(DRMID(drm_enc)); - list_for_each_entry(conn_iter, connector_list, head) - if (conn_iter->encoder == drm_enc) - conn = conn_iter; - - if (!conn) { - DPU_ERROR_ENC(dpu_enc, "failed to find attached connector\n"); - return; - } else if (!conn->state) { - DPU_ERROR_ENC(dpu_enc, "invalid connector state\n"); - return; - } - - drm_for_each_crtc(drm_crtc, drm_enc->dev) - if (drm_crtc->state->encoder_mask & drm_encoder_mask(drm_enc)) - break; - /* Query resource that have been reserved in atomic check step. */ num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, drm_enc->base.id, DPU_HW_BLK_PINGPONG, hw_pp, @@ -1027,7 +980,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) : NULL; - cstate = to_dpu_crtc_state(drm_crtc->state); + cstate = to_dpu_crtc_state(crtc_state); for (i = 0; i < num_lm; i++) { int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); @@ -1039,9 +992,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, cstate->num_mixers = num_lm; + dpu_enc->connector = conn_state->connector; + for (i = 0; i < dpu_enc->num_phys_encs; i++) { - int num_blk; - struct dpu_hw_blk *hw_blk[MAX_CHANNELS_PER_ENC]; struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; if (!dpu_enc->hw_pp[i]) { @@ -1059,16 +1012,8 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); - num_blk = dpu_rm_get_assigned_resources(&dpu_kms->rm, - global_state, drm_enc->base.id, DPU_HW_BLK_INTF, - hw_blk, ARRAY_SIZE(hw_blk)); - for (j = 0; j < num_blk; j++) { - struct dpu_hw_intf *hw_intf; - - hw_intf = to_dpu_hw_intf(hw_blk[i]); - if (hw_intf->idx == phys->intf_idx) - phys->hw_intf = hw_intf; - } + if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) + phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); if (!phys->hw_intf) { DPU_ERROR_ENC(dpu_enc, @@ -1076,9 +1021,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, return; } - phys->connector = conn->state->connector; - if (phys->ops.mode_set) - phys->ops.mode_set(phys, mode, adj_mode); + phys->cached_mode = crtc_state->adjusted_mode; + if (phys->ops.atomic_mode_set) + phys->ops.atomic_mode_set(phys, crtc_state, conn_state); } } @@ -1099,7 +1044,7 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) } - if (dpu_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DisplayPort && + if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_TMDS && dpu_enc->cur_master->hw_mdptop && dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select) dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select( @@ -1109,7 +1054,7 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI && !WARN_ON(dpu_enc->num_phys_encs == 0)) { - unsigned bpc = dpu_enc->phys_encs[0]->connector->display_info.bpc; + unsigned bpc = dpu_enc->connector->display_info.bpc; for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { if (!dpu_enc->hw_pp[i]) continue; @@ -1142,14 +1087,12 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc = NULL; int ret = 0; - struct msm_drm_private *priv; struct drm_display_mode *cur_mode = NULL; dpu_enc = to_dpu_encoder_virt(drm_enc); mutex_lock(&dpu_enc->enc_lock); cur_mode = &dpu_enc->base.crtc->state->adjusted_mode; - priv = drm_enc->dev->dev_private; trace_dpu_enc_enable(DRMID(drm_enc), cur_mode->hdisplay, cur_mode->vdisplay); @@ -1179,7 +1122,6 @@ out: static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc = NULL; - struct msm_drm_private *priv; int i = 0; dpu_enc = to_dpu_encoder_virt(drm_enc); @@ -1188,8 +1130,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) mutex_lock(&dpu_enc->enc_lock); dpu_enc->enabled = false; - priv = drm_enc->dev->dev_private; - trace_dpu_enc_disable(DRMID(drm_enc)); /* wait for idle */ @@ -1213,9 +1153,7 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_STOP); - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - dpu_enc->phys_encs[i]->connector = NULL; - } + dpu_enc->connector = NULL; DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n"); @@ -2093,7 +2031,7 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t) } static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = { - .mode_set = dpu_encoder_virt_mode_set, + .atomic_mode_set = dpu_encoder_virt_atomic_mode_set, .disable = dpu_encoder_virt_disable, .enable = dpu_encoder_virt_enable, .atomic_check = dpu_encoder_virt_atomic_check, @@ -2128,8 +2066,6 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, timer_setup(&dpu_enc->vsync_event_timer, dpu_encoder_vsync_event_handler, 0); - else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS) - dpu_enc->dp = priv->dp[disp_info->h_tile_instance[0]]; INIT_DELAYED_WORK(&dpu_enc->delayed_off_work, dpu_encoder_off_work); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index e241914a9677..42db6ce12caf 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -19,22 +19,24 @@ #define IDLE_TIMEOUT (66 - 16/2) /** - * Encoder functions and data types - * @intfs: Interfaces this encoder is using, INTF_MODE_NONE if unused - */ -struct dpu_encoder_hw_resources { - enum dpu_intf_mode intfs[INTF_MAX]; + * struct msm_display_info - defines display properties + * @intf_type: DRM_MODE_ENCODER_ type + * @capabilities: Bitmask of display flags + * @num_of_h_tiles: Number of horizontal tiles in case of split interface + * @h_tile_instance: Controller instance used per tile. Number of elements is + * based on num_of_h_tiles + * @is_te_using_watchdog_timer: Boolean to indicate watchdog TE is + * used instead of panel TE in cmd mode panels + */ +struct msm_display_info { + int intf_type; + uint32_t capabilities; + uint32_t num_of_h_tiles; + uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY]; + bool is_te_using_watchdog_timer; }; /** - * dpu_encoder_get_hw_resources - Populate table of required hardware resources - * @encoder: encoder pointer - * @hw_res: resource table to populate with encoder required resources - */ -void dpu_encoder_get_hw_resources(struct drm_encoder *encoder, - struct dpu_encoder_hw_resources *hw_res); - -/** * dpu_encoder_assign_crtc - Link the encoder to the crtc it's assigned to * @encoder: encoder pointer * @crtc: crtc pointer diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index e7270eb6b84b..fa8493ac0340 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -84,16 +84,12 @@ struct dpu_encoder_virt_ops { * @is_master: Whether this phys_enc is the current master * encoder. Can be switched at enable time. Based * on split_role and current mode (CMD/VID). - * @mode_fixup: DRM Call. Fixup a DRM mode. - * @mode_set: DRM Call. Set a DRM mode. + * @atomic_mode_set: DRM Call. Set a DRM mode. * This likely caches the mode, for use at enable. * @enable: DRM Call. Enable a DRM mode. * @disable: DRM Call. Disable mode. * @atomic_check: DRM Call. Atomic check new DRM state. * @destroy: DRM Call. Destroy and release resources. - * @get_hw_resources: Populate the structure with the hardware - * resources that this phys_enc is using. - * Expect no overlap between phys_encs. * @control_vblank_irq Register/Deregister for VBLANK IRQ * @wait_for_commit_done: Wait for hardware to have flushed the * current pending frames to hardware @@ -117,20 +113,15 @@ struct dpu_encoder_phys_ops { struct dentry *debugfs_root); void (*prepare_commit)(struct dpu_encoder_phys *encoder); bool (*is_master)(struct dpu_encoder_phys *encoder); - bool (*mode_fixup)(struct dpu_encoder_phys *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - void (*mode_set)(struct dpu_encoder_phys *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); + void (*atomic_mode_set)(struct dpu_encoder_phys *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state); void (*enable)(struct dpu_encoder_phys *encoder); void (*disable)(struct dpu_encoder_phys *encoder); int (*atomic_check)(struct dpu_encoder_phys *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state); void (*destroy)(struct dpu_encoder_phys *encoder); - void (*get_hw_resources)(struct dpu_encoder_phys *encoder, - struct dpu_encoder_hw_resources *hw_res); int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable); int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc); int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc); @@ -182,7 +173,6 @@ struct dpu_encoder_irq { * tied to a specific panel / sub-panel. Abstract type, sub-classed by * phys_vid or phys_cmd for video mode or command mode encs respectively. * @parent: Pointer to the containing virtual encoder - * @connector: If a mode is set, cached pointer to the active connector * @ops: Operations exposed to the virtual encoder * @parent_ops: Callbacks exposed by the parent to the phys_enc * @hw_mdptop: Hardware interface to the top registers @@ -211,7 +201,6 @@ struct dpu_encoder_irq { */ struct dpu_encoder_phys { struct drm_encoder *parent; - struct drm_connector *connector; struct dpu_encoder_phys_ops ops; const struct dpu_encoder_virt_ops *parent_ops; struct dpu_hw_mdp *hw_mdptop; 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 34a6940d12c5..d59802b67d15 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 @@ -45,15 +45,6 @@ static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc) return (phys_enc->split_role != ENC_ROLE_SLAVE); } -static bool dpu_encoder_phys_cmd_mode_fixup( - struct dpu_encoder_phys *phys_enc, - const struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) -{ - DPU_DEBUG_CMDENC(to_dpu_encoder_phys_cmd(phys_enc), "\n"); - return true; -} - static void _dpu_encoder_phys_cmd_update_intf_cfg( struct dpu_encoder_phys *phys_enc) { @@ -144,23 +135,13 @@ static void dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx) phys_enc); } -static void dpu_encoder_phys_cmd_mode_set( +static void dpu_encoder_phys_cmd_atomic_mode_set( struct dpu_encoder_phys *phys_enc, - struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) { - struct dpu_encoder_phys_cmd *cmd_enc = - to_dpu_encoder_phys_cmd(phys_enc); struct dpu_encoder_irq *irq; - if (!mode || !adj_mode) { - DPU_ERROR("invalid args\n"); - return; - } - phys_enc->cached_mode = *adj_mode; - DPU_DEBUG_CMDENC(cmd_enc, "caching mode:\n"); - drm_mode_debug_printmodeline(adj_mode); - irq = &phys_enc->irq[INTR_IDX_CTL_START]; irq->irq_idx = phys_enc->hw_ctl->caps->intr_start; @@ -534,13 +515,6 @@ static void dpu_encoder_phys_cmd_destroy(struct dpu_encoder_phys *phys_enc) kfree(cmd_enc); } -static void dpu_encoder_phys_cmd_get_hw_resources( - struct dpu_encoder_phys *phys_enc, - struct dpu_encoder_hw_resources *hw_res) -{ - hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_CMD; -} - static void dpu_encoder_phys_cmd_prepare_for_kickoff( struct dpu_encoder_phys *phys_enc) { @@ -682,6 +656,9 @@ static int dpu_encoder_phys_cmd_wait_for_commit_done( if (!dpu_encoder_phys_cmd_is_master(phys_enc)) return 0; + if (phys_enc->hw_ctl->ops.is_started(phys_enc->hw_ctl)) + return dpu_encoder_phys_cmd_wait_for_tx_complete(phys_enc); + return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc); } @@ -731,12 +708,10 @@ static void dpu_encoder_phys_cmd_init_ops( { ops->prepare_commit = dpu_encoder_phys_cmd_prepare_commit; ops->is_master = dpu_encoder_phys_cmd_is_master; - ops->mode_set = dpu_encoder_phys_cmd_mode_set; - ops->mode_fixup = dpu_encoder_phys_cmd_mode_fixup; + ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set; ops->enable = dpu_encoder_phys_cmd_enable; ops->disable = dpu_encoder_phys_cmd_disable; ops->destroy = dpu_encoder_phys_cmd_destroy; - ops->get_hw_resources = dpu_encoder_phys_cmd_get_hw_resources; ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq; ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done; ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff; 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 ddd9d89cd456..f49f42e70b29 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 @@ -225,19 +225,6 @@ static void programmable_fetch_config(struct dpu_encoder_phys *phys_enc, spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); } -static bool dpu_encoder_phys_vid_mode_fixup( - struct dpu_encoder_phys *phys_enc, - const struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) -{ - DPU_DEBUG_VIDENC(phys_enc, "\n"); - - /* - * Modifying mode has consequences when the mode comes back to us - */ - return true; -} - static void dpu_encoder_phys_vid_setup_timing_engine( struct dpu_encoder_phys *phys_enc) { @@ -361,19 +348,13 @@ static bool dpu_encoder_phys_vid_needs_single_flush( return phys_enc->split_role != ENC_ROLE_SOLO; } -static void dpu_encoder_phys_vid_mode_set( +static void dpu_encoder_phys_vid_atomic_mode_set( struct dpu_encoder_phys *phys_enc, - struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) { struct dpu_encoder_irq *irq; - if (adj_mode) { - phys_enc->cached_mode = *adj_mode; - drm_mode_debug_printmodeline(adj_mode); - DPU_DEBUG_VIDENC(phys_enc, "caching mode:\n"); - } - irq = &phys_enc->irq[INTR_IDX_VSYNC]; irq->irq_idx = phys_enc->hw_intf->cap->intr_vsync; @@ -465,13 +446,6 @@ static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc) kfree(phys_enc); } -static void dpu_encoder_phys_vid_get_hw_resources( - struct dpu_encoder_phys *phys_enc, - struct dpu_encoder_hw_resources *hw_res) -{ - hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_VIDEO; -} - static int dpu_encoder_phys_vid_wait_for_vblank( struct dpu_encoder_phys *phys_enc) { @@ -675,12 +649,10 @@ static int dpu_encoder_phys_vid_get_frame_count( static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops) { ops->is_master = dpu_encoder_phys_vid_is_master; - ops->mode_set = dpu_encoder_phys_vid_mode_set; - ops->mode_fixup = dpu_encoder_phys_vid_mode_fixup; + ops->atomic_mode_set = dpu_encoder_phys_vid_atomic_mode_set; ops->enable = dpu_encoder_phys_vid_enable; ops->disable = dpu_encoder_phys_vid_disable; ops->destroy = dpu_encoder_phys_vid_destroy; - ops->get_hw_resources = dpu_encoder_phys_vid_get_hw_resources; ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq; ops->wait_for_commit_done = dpu_encoder_phys_vid_wait_for_commit_done; ops->wait_for_vblank = dpu_encoder_phys_vid_wait_for_vblank; 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 aa75991903a6..a4fe77cddfea 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -16,6 +16,9 @@ BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\ BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT)) +#define VIG_MSM8998_MASK \ + (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3)) + #define VIG_SDM845_MASK \ (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3)) @@ -25,6 +28,13 @@ #define VIG_SM8250_MASK \ (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE)) +#define VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL)) + +#define DMA_MSM8998_MASK \ + (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\ + BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ + BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) + #define DMA_SDM845_MASK \ (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\ BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ @@ -33,6 +43,9 @@ #define DMA_CURSOR_SDM845_MASK \ (DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR)) +#define DMA_CURSOR_MSM8998_MASK \ + (DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR)) + #define MIXER_SDM845_MASK \ (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER)) @@ -49,6 +62,8 @@ #define MERGE_3D_SM8150_MASK (0) +#define DSPP_MSM8998_MASK BIT(DPU_DSPP_PCC) | BIT(DPU_DSPP_GC) + #define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC) #define INTF_SDM845_MASK (0) @@ -90,6 +105,17 @@ BIT(MDP_INTF3_INTR) | \ BIT(MDP_INTF4_INTR)) +#define IRQ_SC8180X_MASK (BIT(MDP_SSPP_TOP0_INTR) | \ + BIT(MDP_SSPP_TOP0_INTR2) | \ + BIT(MDP_SSPP_TOP0_HIST_INTR) | \ + BIT(MDP_INTF0_INTR) | \ + BIT(MDP_INTF1_INTR) | \ + BIT(MDP_INTF2_INTR) | \ + BIT(MDP_INTF3_INTR) | \ + BIT(MDP_INTF4_INTR) | \ + BIT(MDP_INTF5_INTR) | \ + BIT(MDP_AD4_0_INTR) | \ + BIT(MDP_AD4_1_INTR)) #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024) #define DEFAULT_DPU_LINE_WIDTH 2048 @@ -181,6 +207,22 @@ static const uint32_t plane_formats_yuv[] = { * DPU sub blocks config *************************************************************/ /* DPU top level caps */ +static const struct dpu_caps msm8998_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0x7, + .qseed_type = DPU_SSPP_SCALER_QSEED3, + .smart_dma_rev = DPU_SSPP_SMART_DMA_V1, + .ubwc_version = DPU_HW_UBWC_VER_10, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + static const struct dpu_caps sdm845_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, @@ -225,6 +267,22 @@ static const struct dpu_caps sm8150_dpu_caps = { .max_vdeci_exp = MAX_VERT_DECIMATION, }; +static const struct dpu_caps sc8180x_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .qseed_type = DPU_SSPP_SCALER_QSEED3, + .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */ + .ubwc_version = DPU_HW_UBWC_VER_30, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 4096, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + static const struct dpu_caps sm8250_dpu_caps = { .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .max_mixer_blendstages = 0xb, @@ -251,11 +309,51 @@ static const struct dpu_caps sc7280_dpu_caps = { .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, }; +static const struct dpu_mdp_cfg msm8998_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x458, + .features = 0, + .highest_bank_bit = 0x2, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { + .reg_off = 0x2AC, .bit_off = 0}, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { + .reg_off = 0x2B4, .bit_off = 0}, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { + .reg_off = 0x2BC, .bit_off = 0}, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { + .reg_off = 0x2C4, .bit_off = 0}, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { + .reg_off = 0x2AC, .bit_off = 8}, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { + .reg_off = 0x2B4, .bit_off = 8}, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { + .reg_off = 0x2C4, .bit_off = 8}, + .clk_ctrls[DPU_CLK_CTRL_DMA3] = { + .reg_off = 0x2C4, .bit_off = 12}, + .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { + .reg_off = 0x3A8, .bit_off = 15}, + .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { + .reg_off = 0x3B0, .bit_off = 15}, + }, +}; + +static const struct dpu_caps qcm2290_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0x4, + .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, + .ubwc_version = DPU_HW_UBWC_VER_20, + .has_dim_layer = true, + .has_idle_pc = true, + .max_linewidth = 2160, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + static const struct dpu_mdp_cfg sdm845_mdp[] = { { .name = "top_0", .id = MDP_TOP, .base = 0x0, .len = 0x45C, - .features = 0, + .features = BIT(DPU_MDP_AUDIO_SELECT), .highest_bank_bit = 0x2, .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2AC, .bit_off = 0}, @@ -293,6 +391,31 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = { }, }; +static const struct dpu_mdp_cfg sc8180x_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x45C, + .features = 0, + .highest_bank_bit = 0x3, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { + .reg_off = 0x2AC, .bit_off = 0}, + .clk_ctrls[DPU_CLK_CTRL_VIG1] = { + .reg_off = 0x2B4, .bit_off = 0}, + .clk_ctrls[DPU_CLK_CTRL_VIG2] = { + .reg_off = 0x2BC, .bit_off = 0}, + .clk_ctrls[DPU_CLK_CTRL_VIG3] = { + .reg_off = 0x2C4, .bit_off = 0}, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { + .reg_off = 0x2AC, .bit_off = 8}, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { + .reg_off = 0x2B4, .bit_off = 8}, + .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { + .reg_off = 0x2BC, .bit_off = 8}, + .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { + .reg_off = 0x2C4, .bit_off = 8}, + }, +}; + static const struct dpu_mdp_cfg sm8250_mdp[] = { { .name = "top_0", .id = MDP_TOP, @@ -336,9 +459,55 @@ static const struct dpu_mdp_cfg sc7280_mdp[] = { }, }; +static const struct dpu_mdp_cfg qcm2290_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x494, + .features = 0, + .highest_bank_bit = 0x2, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { + .reg_off = 0x2AC, .bit_off = 0}, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { + .reg_off = 0x2AC, .bit_off = 8}, + }, +}; + /************************************************************* * CTL sub blocks config *************************************************************/ +static const struct dpu_ctl_cfg msm8998_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x94, + .features = BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x94, + .features = 0, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x94, + .features = BIT(DPU_CTL_SPLIT_DISPLAY), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x1600, .len = 0x94, + .features = 0, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, + { + .name = "ctl_4", .id = CTL_4, + .base = 0x1800, .len = 0x94, + .features = 0, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, +}; + static const struct dpu_ctl_cfg sdm845_ctl[] = { { .name = "ctl_0", .id = CTL_0, @@ -459,6 +628,15 @@ static const struct dpu_ctl_cfg sc7280_ctl[] = { }, }; +static const struct dpu_ctl_cfg qcm2290_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, +}; + /************************************************************* * SSPP sub blocks config *************************************************************/ @@ -497,6 +675,15 @@ static const struct dpu_ctl_cfg sc7280_ctl[] = { .virt_num_formats = ARRAY_SIZE(plane_formats), \ } +static const struct dpu_sspp_sub_blks msm8998_vig_sblk_0 = + _VIG_SBLK("0", 0, DPU_SSPP_SCALER_QSEED3); +static const struct dpu_sspp_sub_blks msm8998_vig_sblk_1 = + _VIG_SBLK("1", 0, DPU_SSPP_SCALER_QSEED3); +static const struct dpu_sspp_sub_blks msm8998_vig_sblk_2 = + _VIG_SBLK("2", 0, DPU_SSPP_SCALER_QSEED3); +static const struct dpu_sspp_sub_blks msm8998_vig_sblk_3 = + _VIG_SBLK("3", 0, DPU_SSPP_SCALER_QSEED3); + static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = @@ -523,6 +710,25 @@ static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4); .clk_ctrl = _clkctrl \ } +static const struct dpu_sspp_cfg msm8998_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_MSM8998_MASK, + msm8998_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_MSM8998_MASK, + msm8998_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_MSM8998_MASK, + msm8998_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_MSM8998_MASK, + msm8998_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_MSM8998_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_MSM8998_MASK, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_MSM8998_MASK, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_MSM8998_MASK, + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1), +}; + static const struct dpu_sspp_cfg sdm845_sspp[] = { SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK, sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), @@ -595,21 +801,34 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1), }; -/************************************************************* - * MIXER sub blocks config - *************************************************************/ -/* SDM845 */ +#define _VIG_SBLK_NOSCALE(num, sdma_pri) \ + { \ + .maxdwnscale = SSPP_UNITY_SCALE, \ + .maxupscale = SSPP_UNITY_SCALE, \ + .smart_dma_priority = sdma_pri, \ + .src_blk = {.name = STRCAT("sspp_src_", num), \ + .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \ + .format_list = plane_formats_yuv, \ + .num_formats = ARRAY_SIZE(plane_formats_yuv), \ + .virt_format_list = plane_formats, \ + .virt_num_formats = ARRAY_SIZE(plane_formats), \ + } -static const struct dpu_lm_sub_blks sdm845_lm_sblk = { - .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, - .maxblendstages = 11, /* excluding base layer */ - .blendstage_base = { /* offsets relative to mixer base */ - 0x20, 0x38, 0x50, 0x68, 0x80, 0x98, - 0xb0, 0xc8, 0xe0, 0xf8, 0x110 - }, +static const struct dpu_sspp_sub_blks qcm2290_vig_sblk_0 = _VIG_SBLK_NOSCALE("0", 2); +static const struct dpu_sspp_sub_blks qcm2290_dma_sblk_0 = _DMA_SBLK("8", 1); + +static const struct dpu_sspp_cfg qcm2290_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_QCM2290_MASK, + qcm2290_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK, + qcm2290_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), }; +/************************************************************* + * MIXER sub blocks config + *************************************************************/ + #define LM_BLK(_name, _id, _base, _fmask, _sblk, _pp, _lmpair, _dspp) \ { \ .name = _name, .id = _id, \ @@ -621,6 +840,43 @@ static const struct dpu_lm_sub_blks sdm845_lm_sblk = { .dspp = _dspp \ } +/* MSM8998 */ + +static const struct dpu_lm_sub_blks msm8998_lm_sblk = { + .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .maxblendstages = 7, /* excluding base layer */ + .blendstage_base = { /* offsets relative to mixer base */ + 0x20, 0x50, 0x80, 0xb0, 0x230, + 0x260, 0x290 + }, +}; + +static const struct dpu_lm_cfg msm8998_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, + &msm8998_lm_sblk, PINGPONG_0, LM_2, DSPP_0), + LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, + &msm8998_lm_sblk, PINGPONG_1, LM_5, DSPP_1), + LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, + &msm8998_lm_sblk, PINGPONG_2, LM_0, 0), + LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, + &msm8998_lm_sblk, PINGPONG_MAX, 0, 0), + LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK, + &msm8998_lm_sblk, PINGPONG_MAX, 0, 0), + LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, + &msm8998_lm_sblk, PINGPONG_3, LM_1, 0), +}; + +/* SDM845 */ + +static const struct dpu_lm_sub_blks sdm845_lm_sblk = { + .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .maxblendstages = 11, /* excluding base layer */ + .blendstage_base = { /* offsets relative to mixer base */ + 0x20, 0x38, 0x50, 0x68, 0x80, 0x98, + 0xb0, 0xc8, 0xe0, 0xf8, 0x110 + }, +}; + static const struct dpu_lm_cfg sdm845_lm[] = { LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_0, LM_1, 0), @@ -679,9 +935,31 @@ static const struct dpu_lm_cfg sc7280_lm[] = { &sc7180_lm_sblk, PINGPONG_3, LM_2, 0), }; +/* QCM2290 */ + +static const struct dpu_lm_sub_blks qcm2290_lm_sblk = { + .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .maxblendstages = 4, /* excluding base layer */ + .blendstage_base = { /* offsets relative to mixer base */ + 0x20, 0x38, 0x50, 0x68 + }, +}; + +static const struct dpu_lm_cfg qcm2290_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SC7180_MASK, + &qcm2290_lm_sblk, PINGPONG_0, 0, DSPP_0), +}; + /************************************************************* * DSPP sub blocks config *************************************************************/ +static const struct dpu_dspp_sub_blks msm8998_dspp_sblk = { + .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700, + .len = 0x90, .version = 0x10007}, + .gc = { .id = DPU_DSPP_GC, .base = 0x17c0, + .len = 0x90, .version = 0x10007}, +}; + static const struct dpu_dspp_sub_blks sc7180_dspp_sblk = { .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700, .len = 0x90, .version = 0x10000}, @@ -700,6 +978,13 @@ static const struct dpu_dspp_sub_blks sm8150_dspp_sblk = { .sblk = _sblk \ } +static const struct dpu_dspp_cfg msm8998_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK, + &msm8998_dspp_sblk), + DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_MSM8998_MASK, + &msm8998_dspp_sblk), +}; + static const struct dpu_dspp_cfg sc7180_dspp[] = { DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, &sc7180_dspp_sblk), @@ -716,6 +1001,11 @@ static const struct dpu_dspp_cfg sm8150_dspp[] = { &sm8150_dspp_sblk), }; +static const struct dpu_dspp_cfg qcm2290_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), +}; + /************************************************************* * PINGPONG sub blocks config *************************************************************/ @@ -798,6 +1088,12 @@ static const struct dpu_pingpong_cfg sm8150_pp[] = { -1), }; +static struct dpu_pingpong_cfg qcm2290_pp[] = { + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), +}; + /************************************************************* * MERGE_3D sub blocks config *************************************************************/ @@ -836,6 +1132,13 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { .intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \ } +static const struct dpu_intf_cfg msm8998_intf[] = { + INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29), + INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31), +}; + static const struct dpu_intf_cfg sdm845_intf[] = { INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), @@ -861,13 +1164,74 @@ static const struct dpu_intf_cfg sc7280_intf[] = { INTF_BLK("intf_5", INTF_5, 0x39000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23), }; +static const struct dpu_intf_cfg sc8180x_intf[] = { + INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29), + /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this is supported */ + INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21), + INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23), +}; + +static const struct dpu_intf_cfg qcm2290_intf[] = { + INTF_BLK("intf_0", INTF_0, 0x00000, INTF_NONE, 0, 0, 0, 0, 0, 0), + INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), +}; + /************************************************************* * VBIF sub blocks config *************************************************************/ /* VBIF QOS remap */ +static const u32 msm8998_rt_pri_lvl[] = {1, 2, 2, 2}; +static const u32 msm8998_nrt_pri_lvl[] = {1, 1, 1, 1}; static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6}; static const u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3}; +static const struct dpu_vbif_dynamic_ot_cfg msm8998_ot_rdwr_cfg[] = { + { + .pps = 1088 * 1920 * 30, + .ot_limit = 2, + }, + { + .pps = 1088 * 1920 * 60, + .ot_limit = 6, + }, + { + .pps = 3840 * 2160 * 30, + .ot_limit = 16, + }, +}; + +static const struct dpu_vbif_cfg msm8998_vbif[] = { + { + .name = "vbif_0", .id = VBIF_0, + .base = 0, .len = 0x1040, + .default_ot_rd_limit = 32, + .default_ot_wr_limit = 32, + .features = BIT(DPU_VBIF_QOS_REMAP) | BIT(DPU_VBIF_QOS_OTLIM), + .xin_halt_timeout = 0x4000, + .dynamic_ot_rd_tbl = { + .count = ARRAY_SIZE(msm8998_ot_rdwr_cfg), + .cfg = msm8998_ot_rdwr_cfg, + }, + .dynamic_ot_wr_tbl = { + .count = ARRAY_SIZE(msm8998_ot_rdwr_cfg), + .cfg = msm8998_ot_rdwr_cfg, + }, + .qos_rt_tbl = { + .npriority_lvl = ARRAY_SIZE(msm8998_rt_pri_lvl), + .priority_lvl = msm8998_rt_pri_lvl, + }, + .qos_nrt_tbl = { + .npriority_lvl = ARRAY_SIZE(msm8998_nrt_pri_lvl), + .priority_lvl = msm8998_nrt_pri_lvl, + }, + .memtype_count = 14, + .memtype = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, + }, +}; + static const struct dpu_vbif_cfg sdm845_vbif[] = { { .name = "vbif_0", .id = VBIF_0, @@ -908,6 +1272,22 @@ static const struct dpu_reg_dma_cfg sm8250_regdma = { *************************************************************/ /* SSPP QOS LUTs */ +static const struct dpu_qos_lut_entry msm8998_qos_linear[] = { + {.fl = 4, .lut = 0x1b}, + {.fl = 5, .lut = 0x5b}, + {.fl = 6, .lut = 0x15b}, + {.fl = 7, .lut = 0x55b}, + {.fl = 8, .lut = 0x155b}, + {.fl = 9, .lut = 0x555b}, + {.fl = 10, .lut = 0x1555b}, + {.fl = 11, .lut = 0x5555b}, + {.fl = 12, .lut = 0x15555b}, + {.fl = 13, .lut = 0x55555b}, + {.fl = 14, .lut = 0}, + {.fl = 1, .lut = 0x1b}, + {.fl = 0, .lut = 0} +}; + static const struct dpu_qos_lut_entry sdm845_qos_linear[] = { {.fl = 4, .lut = 0x357}, {.fl = 5, .lut = 0x3357}, @@ -923,6 +1303,15 @@ static const struct dpu_qos_lut_entry sdm845_qos_linear[] = { {.fl = 0, .lut = 0x11222222223357} }; +static const struct dpu_qos_lut_entry msm8998_qos_macrotile[] = { + {.fl = 10, .lut = 0x1aaff}, + {.fl = 11, .lut = 0x5aaff}, + {.fl = 12, .lut = 0x15aaff}, + {.fl = 13, .lut = 0x55aaff}, + {.fl = 1, .lut = 0x1aaff}, + {.fl = 0, .lut = 0}, +}; + static const struct dpu_qos_lut_entry sc7180_qos_linear[] = { {.fl = 0, .lut = 0x0011222222335777}, }; @@ -931,6 +1320,14 @@ static const struct dpu_qos_lut_entry sm8150_qos_linear[] = { {.fl = 0, .lut = 0x0011222222223357 }, }; +static const struct dpu_qos_lut_entry sc8180x_qos_linear[] = { + {.fl = 4, .lut = 0x0000000000000357 }, +}; + +static const struct dpu_qos_lut_entry qcm2290_qos_linear[] = { + {.fl = 0, .lut = 0x0011222222335777}, +}; + static const struct dpu_qos_lut_entry sdm845_qos_macrotile[] = { {.fl = 10, .lut = 0x344556677}, {.fl = 11, .lut = 0x3344556677}, @@ -944,6 +1341,14 @@ static const struct dpu_qos_lut_entry sc7180_qos_macrotile[] = { {.fl = 0, .lut = 0x0011223344556677}, }; +static const struct dpu_qos_lut_entry sc8180x_qos_macrotile[] = { + {.fl = 10, .lut = 0x0000000344556677}, +}; + +static const struct dpu_qos_lut_entry msm8998_qos_nrt[] = { + {.fl = 0, .lut = 0x0}, +}; + static const struct dpu_qos_lut_entry sdm845_qos_nrt[] = { {.fl = 0, .lut = 0x0}, }; @@ -952,6 +1357,42 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { {.fl = 0, .lut = 0x0}, }; +static const struct dpu_perf_cfg msm8998_perf_data = { + .max_bw_low = 6700000, + .max_bw_high = 6700000, + .min_core_ib = 2400000, + .min_llcc_ib = 800000, + .min_dram_ib = 800000, + .undersized_prefill_lines = 2, + .xtra_prefill_lines = 2, + .dest_scale_prefill_lines = 3, + .macrotile_prefill_lines = 4, + .yuv_nv12_prefill_lines = 8, + .linear_prefill_lines = 1, + .downscaling_prefill_lines = 1, + .amortizable_threshold = 25, + .min_prefill_lines = 25, + .danger_lut_tbl = {0xf, 0xffff, 0x0}, + .safe_lut_tbl = {0xfffc, 0xff00, 0xffff}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(msm8998_qos_linear), + .entries = msm8998_qos_linear + }, + {.nentry = ARRAY_SIZE(msm8998_qos_macrotile), + .entries = msm8998_qos_macrotile + }, + {.nentry = ARRAY_SIZE(msm8998_qos_nrt), + .entries = msm8998_qos_nrt + }, + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 200, + .bw_inefficiency_factor = 120, +}; + static const struct dpu_perf_cfg sdm845_perf_data = { .max_bw_low = 6800000, .max_bw_high = 6800000, @@ -1045,6 +1486,33 @@ static const struct dpu_perf_cfg sm8150_perf_data = { .bw_inefficiency_factor = 120, }; +static const struct dpu_perf_cfg sc8180x_perf_data = { + .max_bw_low = 9600000, + .max_bw_high = 9600000, + .min_core_ib = 2400000, + .min_llcc_ib = 800000, + .min_dram_ib = 800000, + .danger_lut_tbl = {0xf, 0xffff, 0x0}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sc8180x_qos_linear), + .entries = sc8180x_qos_linear + }, + {.nentry = ARRAY_SIZE(sc8180x_qos_macrotile), + .entries = sc8180x_qos_macrotile + }, + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), + .entries = sc7180_qos_nrt + }, + /* TODO: macrotile-qseed is different from macrotile */ + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + static const struct dpu_perf_cfg sm8250_perf_data = { .max_bw_low = 13700000, .max_bw_high = 16600000, @@ -1102,11 +1570,62 @@ static const struct dpu_perf_cfg sc7280_perf_data = { .bw_inefficiency_factor = 120, }; +static const struct dpu_perf_cfg qcm2290_perf_data = { + .max_bw_low = 2700000, + .max_bw_high = 2700000, + .min_core_ib = 1300000, + .min_llcc_ib = 0, + .min_dram_ib = 1600000, + .min_prefill_lines = 24, + .danger_lut_tbl = {0xff, 0x0, 0x0}, + .safe_lut_tbl = {0xfff0, 0x0, 0x0}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(qcm2290_qos_linear), + .entries = qcm2290_qos_linear + }, + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; /************************************************************* * Hardware catalog init *************************************************************/ /* + * msm8998_cfg_init(): populate sdm845 dpu sub-blocks reg offsets + * and instance counts. + */ +static void msm8998_cfg_init(struct dpu_mdss_cfg *dpu_cfg) +{ + *dpu_cfg = (struct dpu_mdss_cfg){ + .caps = &msm8998_dpu_caps, + .mdp_count = ARRAY_SIZE(msm8998_mdp), + .mdp = msm8998_mdp, + .ctl_count = ARRAY_SIZE(msm8998_ctl), + .ctl = msm8998_ctl, + .sspp_count = ARRAY_SIZE(msm8998_sspp), + .sspp = msm8998_sspp, + .mixer_count = ARRAY_SIZE(msm8998_lm), + .mixer = msm8998_lm, + .dspp_count = ARRAY_SIZE(msm8998_dspp), + .dspp = msm8998_dspp, + .pingpong_count = ARRAY_SIZE(sdm845_pp), + .pingpong = sdm845_pp, + .intf_count = ARRAY_SIZE(msm8998_intf), + .intf = msm8998_intf, + .vbif_count = ARRAY_SIZE(msm8998_vbif), + .vbif = msm8998_vbif, + .reg_dma_count = 0, + .perf = msm8998_perf_data, + .mdss_irqs = IRQ_SM8250_MASK, + }; +} + +/* * sdm845_cfg_init(): populate sdm845 dpu sub-blocks reg offsets * and instance counts. */ @@ -1200,6 +1719,37 @@ static void sm8150_cfg_init(struct dpu_mdss_cfg *dpu_cfg) } /* + * sc8180x_cfg_init(): populate sc8180 dpu sub-blocks reg offsets + * and instance counts. + */ +static void sc8180x_cfg_init(struct dpu_mdss_cfg *dpu_cfg) +{ + *dpu_cfg = (struct dpu_mdss_cfg){ + .caps = &sc8180x_dpu_caps, + .mdp_count = ARRAY_SIZE(sc8180x_mdp), + .mdp = sc8180x_mdp, + .ctl_count = ARRAY_SIZE(sm8150_ctl), + .ctl = sm8150_ctl, + .sspp_count = ARRAY_SIZE(sdm845_sspp), + .sspp = sdm845_sspp, + .mixer_count = ARRAY_SIZE(sm8150_lm), + .mixer = sm8150_lm, + .pingpong_count = ARRAY_SIZE(sm8150_pp), + .pingpong = sm8150_pp, + .merge_3d_count = ARRAY_SIZE(sm8150_merge_3d), + .merge_3d = sm8150_merge_3d, + .intf_count = ARRAY_SIZE(sc8180x_intf), + .intf = sc8180x_intf, + .vbif_count = ARRAY_SIZE(sdm845_vbif), + .vbif = sdm845_vbif, + .reg_dma_count = 1, + .dma_cfg = sm8150_regdma, + .perf = sc8180x_perf_data, + .mdss_irqs = IRQ_SC8180X_MASK, + }; +} + +/* * sm8250_cfg_init(): populate sm8250 dpu sub-blocks reg offsets * and instance counts. */ @@ -1255,13 +1805,49 @@ static void sc7280_cfg_init(struct dpu_mdss_cfg *dpu_cfg) }; } + +/* + * qcm2290_cfg_init(): populate qcm2290 dpu sub-blocks reg offsets + * and instance counts. + */ +static void qcm2290_cfg_init(struct dpu_mdss_cfg *dpu_cfg) +{ + *dpu_cfg = (struct dpu_mdss_cfg){ + .caps = &qcm2290_dpu_caps, + .mdp_count = ARRAY_SIZE(qcm2290_mdp), + .mdp = qcm2290_mdp, + .ctl_count = ARRAY_SIZE(qcm2290_ctl), + .ctl = qcm2290_ctl, + .sspp_count = ARRAY_SIZE(qcm2290_sspp), + .sspp = qcm2290_sspp, + .mixer_count = ARRAY_SIZE(qcm2290_lm), + .mixer = qcm2290_lm, + .dspp_count = ARRAY_SIZE(qcm2290_dspp), + .dspp = qcm2290_dspp, + .pingpong_count = ARRAY_SIZE(qcm2290_pp), + .pingpong = qcm2290_pp, + .intf_count = ARRAY_SIZE(qcm2290_intf), + .intf = qcm2290_intf, + .vbif_count = ARRAY_SIZE(sdm845_vbif), + .vbif = sdm845_vbif, + .reg_dma_count = 1, + .dma_cfg = sdm845_regdma, + .perf = qcm2290_perf_data, + .mdss_irqs = IRQ_SC7180_MASK, + }; +} + static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = { + { .hw_rev = DPU_HW_VER_300, .cfg_init = msm8998_cfg_init}, + { .hw_rev = DPU_HW_VER_301, .cfg_init = msm8998_cfg_init}, { .hw_rev = DPU_HW_VER_400, .cfg_init = sdm845_cfg_init}, { .hw_rev = DPU_HW_VER_401, .cfg_init = sdm845_cfg_init}, { .hw_rev = DPU_HW_VER_500, .cfg_init = sm8150_cfg_init}, { .hw_rev = DPU_HW_VER_501, .cfg_init = sm8150_cfg_init}, + { .hw_rev = DPU_HW_VER_510, .cfg_init = sc8180x_cfg_init}, { .hw_rev = DPU_HW_VER_600, .cfg_init = sm8250_cfg_init}, { .hw_rev = DPU_HW_VER_620, .cfg_init = sc7180_cfg_init}, + { .hw_rev = DPU_HW_VER_650, .cfg_init = qcm2290_cfg_init}, { .hw_rev = DPU_HW_VER_720, .cfg_init = sc7280_cfg_init}, }; 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 31af04afda7d..b85b24bd3f53 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -39,8 +39,10 @@ #define DPU_HW_VER_410 DPU_HW_VER(4, 1, 0) /* sdm670 v1.0 */ #define DPU_HW_VER_500 DPU_HW_VER(5, 0, 0) /* sm8150 v1.0 */ #define DPU_HW_VER_501 DPU_HW_VER(5, 0, 1) /* sm8150 v2.0 */ +#define DPU_HW_VER_510 DPU_HW_VER(5, 1, 1) /* sc8180 */ #define DPU_HW_VER_600 DPU_HW_VER(6, 0, 0) /* sm8250 */ #define DPU_HW_VER_620 DPU_HW_VER(6, 2, 0) /* sc7180 v1.0 */ +#define DPU_HW_VER_650 DPU_HW_VER(6, 5, 0) /* qcm2290|sm4125 */ #define DPU_HW_VER_720 DPU_HW_VER(7, 2, 0) /* sc7280 */ #define IS_MSM8996_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_170) @@ -87,6 +89,7 @@ enum { DPU_MDP_BWC, DPU_MDP_UBWC_1_0, DPU_MDP_UBWC_1_5, + DPU_MDP_AUDIO_SELECT, DPU_MDP_MAX }; @@ -435,6 +438,8 @@ enum dpu_clk_ctrl_type { DPU_CLK_CTRL_RGB3, DPU_CLK_CTRL_DMA0, DPU_CLK_CTRL_DMA1, + DPU_CLK_CTRL_DMA2, + DPU_CLK_CTRL_DMA3, DPU_CLK_CTRL_CURSOR0, DPU_CLK_CTRL_CURSOR1, DPU_CLK_CTRL_INLINE_ROT0_SSPP, @@ -781,22 +786,6 @@ struct dpu_mdss_hw_cfg_handler { void (*cfg_init)(struct dpu_mdss_cfg *dpu_cfg); }; -/* - * Access Macros - */ -#define BLK_MDP(s) ((s)->mdp) -#define BLK_CTL(s) ((s)->ctl) -#define BLK_VIG(s) ((s)->vig) -#define BLK_RGB(s) ((s)->rgb) -#define BLK_DMA(s) ((s)->dma) -#define BLK_CURSOR(s) ((s)->cursor) -#define BLK_MIXER(s) ((s)->mixer) -#define BLK_PINGPONG(s) ((s)->pingpong) -#define BLK_INTF(s) ((s)->intf) -#define BLK_AD(s) ((s)->ad) -#define BLK_DSPP(s) ((s)->dspp) -#define BLK_MERGE3d(s) ((s)->merge_3d) - /** * dpu_hw_catalog_init - dpu hardware catalog init API retrieves * hardcoded target specific catalog information in config structure 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 02da9ecf71f1..3584f5ee6bb3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -92,6 +92,11 @@ static inline void dpu_hw_ctl_trigger_start(struct dpu_hw_ctl *ctx) DPU_REG_WRITE(&ctx->hw, CTL_START, 0x1); } +static inline bool dpu_hw_ctl_is_started(struct dpu_hw_ctl *ctx) +{ + return !!(DPU_REG_READ(&ctx->hw, CTL_START) & BIT(0)); +} + static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx) { trace_dpu_hw_ctl_trigger_prepare(ctx->pending_flush_mask, @@ -587,6 +592,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->get_pending_flush = dpu_hw_ctl_get_pending_flush; ops->get_flush_register = dpu_hw_ctl_get_flush_register; ops->trigger_start = dpu_hw_ctl_trigger_start; + ops->is_started = dpu_hw_ctl_is_started; ops->trigger_pending = dpu_hw_ctl_trigger_pending; ops->reset = dpu_hw_ctl_reset_control; ops->wait_reset_status = dpu_hw_ctl_wait_reset_status; 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 806c171e5df2..ac1544474022 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -62,6 +62,13 @@ struct dpu_hw_ctl_ops { void (*trigger_start)(struct dpu_hw_ctl *ctx); /** + * check if the ctl is started + * @ctx : ctl path ctx pointer + * @Return: true if started, false if stopped + */ + bool (*is_started)(struct dpu_hw_ctl *ctx); + + /** * kickoff prepare is in progress hw operation for sw * controlled interfaces: DSI cmd mode and WB interface * are SW controlled diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index a77a5eaa78ad..c515b7cf922c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -13,7 +13,7 @@ #include "dpu_hw_mdss.h" #include "dpu_trace.h" -/** +/* * Register offsets in MDSS register file for the interrupt registers * w.r.t. to the MDP base */ @@ -23,6 +23,7 @@ #define MDP_INTF_2_OFF 0x6B000 #define MDP_INTF_3_OFF 0x6B800 #define MDP_INTF_4_OFF 0x6C000 +#define MDP_INTF_5_OFF 0x6C800 #define MDP_AD4_0_OFF 0x7C000 #define MDP_AD4_1_OFF 0x7D000 #define MDP_AD4_INTR_EN_OFF 0x41c @@ -94,6 +95,11 @@ static const struct dpu_intr_reg dpu_intr_set[] = { MDP_INTF_4_OFF+INTF_INTR_STATUS }, { + MDP_INTF_5_OFF+INTF_INTR_CLEAR, + MDP_INTF_5_OFF+INTF_INTR_EN, + MDP_INTF_5_OFF+INTF_INTR_STATUS + }, + { MDP_AD4_0_OFF + MDP_AD4_INTR_CLEAR_OFF, MDP_AD4_0_OFF + MDP_AD4_INTR_EN_OFF, MDP_AD4_0_OFF + MDP_AD4_INTR_STATUS_OFF, @@ -140,7 +146,7 @@ static const struct dpu_intr_reg dpu_intr_set[] = { /** * dpu_core_irq_callback_handler - dispatch core interrupts - * @arg: private data of callback handler + * @dpu_kms: Pointer to DPU's KMS structure * @irq_idx: interrupt index */ static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, int irq_idx) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h index 1ab75cccd145..37379966d8ec 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h @@ -22,6 +22,7 @@ enum dpu_hw_intr_reg { MDP_INTF2_INTR, MDP_INTF3_INTR, MDP_INTF4_INTR, + MDP_INTF5_INTR, MDP_AD4_0_INTR, MDP_AD4_1_INTR, MDP_INTF0_7xxx_INTR, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 3568be80dab5..230d122fa43b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -78,7 +78,6 @@ struct dpu_hw_intf_ops { }; struct dpu_hw_intf { - struct dpu_hw_blk base; struct dpu_hw_blk_reg_map hw; /* intf */ @@ -91,16 +90,6 @@ struct dpu_hw_intf { }; /** - * to_dpu_hw_intf - convert base object dpu_hw_base to container - * @hw: Pointer to base hardware block - * return: Pointer to hardware block container - */ -static inline struct dpu_hw_intf *to_dpu_hw_intf(struct dpu_hw_blk *hw) -{ - return container_of(hw, struct dpu_hw_intf, base); -} - -/** * dpu_hw_intf_init(): Initializes the intf driver for the passed * interface idx. * @idx: interface index for which driver object is required diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c index 282e3c6c6d48..ab3ef162b666 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -268,7 +268,9 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, ops->get_danger_status = dpu_hw_get_danger_status; ops->setup_vsync_source = dpu_hw_setup_vsync_source; ops->get_safe_status = dpu_hw_get_safe_status; - ops->intf_audio_select = dpu_hw_intf_audio_select; + + if (cap & BIT(DPU_MDP_AUDIO_SELECT)) + ops->intf_audio_select = dpu_hw_intf_audio_select; } static const struct dpu_mdp_cfg *_top_offset(enum dpu_mdp mdp, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 47fe11a84a77..e29796c4f27b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -271,6 +271,10 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) if (!p) return -EINVAL; + /* Only create a set of debugfs for the primary node, ignore render nodes */ + if (minor->type != DRM_MINOR_PRIMARY) + return 0; + dev = dpu_kms->dev; priv = dev->dev_private; @@ -774,12 +778,6 @@ fail: return ret; } -static long dpu_kms_round_pixclk(struct msm_kms *kms, unsigned long rate, - struct drm_encoder *encoder) -{ - return rate; -} - static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) { int i; @@ -948,7 +946,6 @@ static const struct msm_kms_funcs kms_funcs = { .disable_vblank = dpu_kms_disable_vblank, .check_modified_format = dpu_format_check_modified_format, .get_format = dpu_get_msm_format, - .round_pixclk = dpu_kms_round_pixclk, .destroy = dpu_kms_destroy, .snapshot = dpu_kms_mdp_snapshot, #ifdef CONFIG_DEBUG_FS @@ -998,29 +995,15 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms) return 0; } -static struct dss_clk *_dpu_kms_get_clk(struct dpu_kms *dpu_kms, - char *clock_name) -{ - struct dss_module_power *mp = &dpu_kms->mp; - int i; - - for (i = 0; i < mp->num_clk; i++) { - if (!strcmp(mp->clk_config[i].clk_name, clock_name)) - return &mp->clk_config[i]; - } - - return NULL; -} - u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name) { - struct dss_clk *clk; + struct clk *clk; - clk = _dpu_kms_get_clk(dpu_kms, clock_name); + clk = msm_clk_bulk_get_clock(dpu_kms->clocks, dpu_kms->num_clocks, clock_name); if (!clk) return -EINVAL; - return clk_get_rate(clk->clk); + return clk_get_rate(clk); } static int dpu_kms_hw_init(struct msm_kms *kms) @@ -1043,7 +1026,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) atomic_set(&dpu_kms->bandwidth_ref, 0); - dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp", "mdp"); + dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp"); if (IS_ERR(dpu_kms->mmio)) { rc = PTR_ERR(dpu_kms->mmio); DPU_ERROR("mdp register memory map failed: %d\n", rc); @@ -1052,20 +1035,20 @@ static int dpu_kms_hw_init(struct msm_kms *kms) } DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio); - dpu_kms->vbif[VBIF_RT] = msm_ioremap(dpu_kms->pdev, "vbif", "vbif"); + dpu_kms->vbif[VBIF_RT] = msm_ioremap(dpu_kms->pdev, "vbif"); if (IS_ERR(dpu_kms->vbif[VBIF_RT])) { rc = PTR_ERR(dpu_kms->vbif[VBIF_RT]); DPU_ERROR("vbif register memory map failed: %d\n", rc); dpu_kms->vbif[VBIF_RT] = NULL; goto error; } - dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(dpu_kms->pdev, "vbif_nrt", "vbif_nrt"); + dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(dpu_kms->pdev, "vbif_nrt"); if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) { dpu_kms->vbif[VBIF_NRT] = NULL; DPU_DEBUG("VBIF NRT is not defined"); } - dpu_kms->reg_dma = msm_ioremap_quiet(dpu_kms->pdev, "regdma", "regdma"); + dpu_kms->reg_dma = msm_ioremap_quiet(dpu_kms->pdev, "regdma"); if (IS_ERR(dpu_kms->reg_dma)) { dpu_kms->reg_dma = NULL; DPU_DEBUG("REG_DMA is not defined"); @@ -1132,7 +1115,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) } rc = dpu_core_perf_init(&dpu_kms->perf, dev, dpu_kms->catalog, - _dpu_kms_get_clk(dpu_kms, "core")); + msm_clk_bulk_get_clock(dpu_kms->clocks, dpu_kms->num_clocks, "core")); if (rc) { DPU_ERROR("failed to init perf %d\n", rc); goto perf_err; @@ -1219,7 +1202,6 @@ static int dpu_bind(struct device *dev, struct device *master, void *data) struct platform_device *pdev = to_platform_device(dev); struct drm_device *ddev = priv->dev; struct dpu_kms *dpu_kms; - struct dss_module_power *mp; int ret = 0; dpu_kms = devm_kzalloc(&pdev->dev, sizeof(*dpu_kms), GFP_KERNEL); @@ -1236,12 +1218,12 @@ static int dpu_bind(struct device *dev, struct device *master, void *data) return ret; } - mp = &dpu_kms->mp; - ret = msm_dss_parse_clock(pdev, mp); - if (ret) { + ret = devm_clk_bulk_get_all(&pdev->dev, &dpu_kms->clocks); + if (ret < 0) { DPU_ERROR("failed to parse clocks, ret=%d\n", ret); return ret; } + dpu_kms->num_clocks = ret; platform_set_drvdata(pdev, dpu_kms); @@ -1265,11 +1247,6 @@ static void dpu_unbind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); - struct dss_module_power *mp = &dpu_kms->mp; - - msm_dss_put_clk(mp->clk_config, mp->num_clk); - devm_kfree(&pdev->dev, mp->clk_config); - mp->num_clk = 0; if (dpu_kms->rpm_enabled) pm_runtime_disable(&pdev->dev); @@ -1293,21 +1270,18 @@ static int dpu_dev_remove(struct platform_device *pdev) static int __maybe_unused dpu_runtime_suspend(struct device *dev) { - int i, rc = -1; + int i; struct platform_device *pdev = to_platform_device(dev); struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); - struct dss_module_power *mp = &dpu_kms->mp; /* Drop the performance state vote */ dev_pm_opp_set_rate(dev, 0); - rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false); - if (rc) - DPU_ERROR("clock disable failed rc:%d\n", rc); + clk_bulk_disable_unprepare(dpu_kms->num_clocks, dpu_kms->clocks); for (i = 0; i < dpu_kms->num_paths; i++) icc_set_bw(dpu_kms->path[i], 0, 0); - return rc; + return 0; } static int __maybe_unused dpu_runtime_resume(struct device *dev) @@ -1317,7 +1291,6 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); struct drm_encoder *encoder; struct drm_device *ddev; - struct dss_module_power *mp = &dpu_kms->mp; int i; ddev = dpu_kms->dev; @@ -1327,7 +1300,7 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) for (i = 0; i < dpu_kms->num_paths; i++) icc_set_bw(dpu_kms->path[i], 0, Bps_to_icc(MIN_IB_BW)); - rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); + rc = clk_bulk_prepare_enable(dpu_kms->num_clocks, dpu_kms->clocks); if (rc) { DPU_ERROR("clock enable failed rc:%d\n", rc); return rc; @@ -1348,9 +1321,12 @@ static const struct dev_pm_ops dpu_pm_ops = { }; const struct of_device_id dpu_dt_match[] = { + { .compatible = "qcom,msm8998-dpu", }, + { .compatible = "qcom,qcm2290-dpu", }, { .compatible = "qcom,sdm845-dpu", }, { .compatible = "qcom,sc7180-dpu", }, { .compatible = "qcom,sc7280-dpu", }, + { .compatible = "qcom,sc8180x-dpu", }, { .compatible = "qcom,sm8150-dpu", }, { .compatible = "qcom,sm8250-dpu", }, {} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 2d385b4b7f5e..779e7bd01efd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -21,7 +21,6 @@ #include "dpu_hw_lm.h" #include "dpu_hw_interrupts.h" #include "dpu_hw_top.h" -#include "dpu_io_util.h" #include "dpu_rm.h" #include "dpu_core_perf.h" @@ -113,7 +112,8 @@ struct dpu_kms { struct platform_device *pdev; bool rpm_enabled; - struct dss_module_power mp; + struct clk_bulk_data *clocks; + size_t num_clocks; /* reference count bandwidth requests, so we know when we can * release bandwidth. Each atomic update increments, and frame- @@ -144,7 +144,6 @@ struct dpu_global_state { uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0]; uint32_t mixer_to_enc_id[LM_MAX - LM_0]; uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; - uint32_t intf_to_enc_id[INTF_MAX - INTF_0]; uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0]; }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c index 131c1f1a869c..b10ca505f9ac 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c @@ -29,7 +29,8 @@ struct dpu_irq_controller { struct dpu_mdss { struct msm_mdss base; void __iomem *mmio; - struct dss_module_power mp; + struct clk_bulk_data *clocks; + size_t num_clocks; struct dpu_irq_controller irq_controller; }; @@ -136,10 +137,9 @@ static void _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss) static int dpu_mdss_enable(struct msm_mdss *mdss) { struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); - struct dss_module_power *mp = &dpu_mdss->mp; int ret; - ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); + ret = clk_bulk_prepare_enable(dpu_mdss->num_clocks, dpu_mdss->clocks); if (ret) { DPU_ERROR("clock enable failed, ret:%d\n", ret); return ret; @@ -174,21 +174,16 @@ static int dpu_mdss_enable(struct msm_mdss *mdss) static int dpu_mdss_disable(struct msm_mdss *mdss) { struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); - struct dss_module_power *mp = &dpu_mdss->mp; - int ret; - ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false); - if (ret) - DPU_ERROR("clock disable failed, ret:%d\n", ret); + clk_bulk_disable_unprepare(dpu_mdss->num_clocks, dpu_mdss->clocks); - return ret; + return 0; } static void dpu_mdss_destroy(struct msm_mdss *mdss) { struct platform_device *pdev = to_platform_device(mdss->dev); struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); - struct dss_module_power *mp = &dpu_mdss->mp; int irq; pm_runtime_suspend(mdss->dev); @@ -196,8 +191,6 @@ static void dpu_mdss_destroy(struct msm_mdss *mdss) _dpu_mdss_irq_domain_fini(dpu_mdss); irq = platform_get_irq(pdev, 0); irq_set_chained_handler_and_data(irq, NULL, NULL); - msm_dss_put_clk(mp->clk_config, mp->num_clk); - devm_kfree(&pdev->dev, mp->clk_config); if (dpu_mdss->mmio) devm_iounmap(&pdev->dev, dpu_mdss->mmio); @@ -214,7 +207,6 @@ int dpu_mdss_init(struct platform_device *pdev) { struct msm_drm_private *priv = platform_get_drvdata(pdev); struct dpu_mdss *dpu_mdss; - struct dss_module_power *mp; int ret; int irq; @@ -222,18 +214,18 @@ int dpu_mdss_init(struct platform_device *pdev) if (!dpu_mdss) return -ENOMEM; - dpu_mdss->mmio = msm_ioremap(pdev, "mdss", "mdss"); + dpu_mdss->mmio = msm_ioremap(pdev, "mdss"); if (IS_ERR(dpu_mdss->mmio)) return PTR_ERR(dpu_mdss->mmio); DRM_DEBUG("mapped mdss address space @%pK\n", dpu_mdss->mmio); - mp = &dpu_mdss->mp; - ret = msm_dss_parse_clock(pdev, mp); - if (ret) { + ret = devm_clk_bulk_get_all(&pdev->dev, &dpu_mdss->clocks); + if (ret < 0) { DPU_ERROR("failed to parse clocks, ret=%d\n", ret); goto clk_parse_err; } + dpu_mdss->num_clocks = ret; dpu_mdss->base.dev = &pdev->dev; dpu_mdss->base.funcs = &mdss_funcs; @@ -260,9 +252,7 @@ int dpu_mdss_init(struct platform_device *pdev) irq_error: _dpu_mdss_irq_domain_fini(dpu_mdss); irq_domain_error: - msm_dss_put_clk(mp->clk_config, mp->num_clk); clk_parse_err: - devm_kfree(&pdev->dev, mp->clk_config); if (dpu_mdss->mmio) devm_iounmap(&pdev->dev, dpu_mdss->mmio); dpu_mdss->mmio = NULL; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index ca75089c9d61..6565682fe227 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -902,7 +902,7 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, if (pstate->aspace) { ret = msm_framebuffer_prepare(new_state->fb, - pstate->aspace); + pstate->aspace, pstate->needs_dirtyfb); if (ret) { DPU_ERROR("failed to prepare framebuffer\n"); return ret; @@ -933,7 +933,8 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane, DPU_DEBUG_PLANE(pdpu, "FB[%u]\n", old_state->fb->base.id); - msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace); + msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace, + old_pstate->needs_dirtyfb); } static bool dpu_plane_validate_src(struct drm_rect *src, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h index 9d51dad5c6a5..50781e2d3577 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h @@ -25,6 +25,7 @@ * @pending: whether the current update is still pending * @plane_fetch_bw: calculated BW per plane * @plane_clk: calculated clk per plane + * @needs_dirtyfb: whether attached CRTC needs pixel data explicitly flushed */ struct dpu_plane_state { struct drm_plane_state base; @@ -37,6 +38,8 @@ struct dpu_plane_state { u64 plane_fetch_bw; u64 plane_clk; + + bool needs_dirtyfb; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index f9c83d6e427a..7497538adae1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -28,13 +28,20 @@ static inline bool reserved_by_other(uint32_t *res_map, int idx, */ struct dpu_rm_requirements { struct msm_display_topology topology; - struct dpu_encoder_hw_resources hw_res; }; int dpu_rm_destroy(struct dpu_rm *rm) { int i; + for (i = 0; i < ARRAY_SIZE(rm->dspp_blks); i++) { + struct dpu_hw_dspp *hw; + + if (rm->dspp_blks[i]) { + hw = to_dpu_hw_dspp(rm->dspp_blks[i]); + dpu_hw_dspp_destroy(hw); + } + } for (i = 0; i < ARRAY_SIZE(rm->pingpong_blks); i++) { struct dpu_hw_pingpong *hw; @@ -67,14 +74,8 @@ int dpu_rm_destroy(struct dpu_rm *rm) dpu_hw_ctl_destroy(hw); } } - for (i = 0; i < ARRAY_SIZE(rm->intf_blks); i++) { - struct dpu_hw_intf *hw; - - if (rm->intf_blks[i]) { - hw = to_dpu_hw_intf(rm->intf_blks[i]); - dpu_hw_intf_destroy(hw); - } - } + for (i = 0; i < ARRAY_SIZE(rm->hw_intf); i++) + dpu_hw_intf_destroy(rm->hw_intf[i]); return 0; } @@ -108,24 +109,12 @@ int dpu_rm_init(struct dpu_rm *rm, continue; } hw = dpu_hw_lm_init(lm->id, mmio, cat); - if (IS_ERR_OR_NULL(hw)) { + if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed lm object creation: err %d\n", rc); goto fail; } rm->mixer_blks[lm->id - LM_0] = &hw->base; - - if (!rm->lm_max_width) { - rm->lm_max_width = lm->sblk->maxwidth; - } else if (rm->lm_max_width != lm->sblk->maxwidth) { - /* - * Don't expect to have hw where lm max widths differ. - * If found, take the min. - */ - DPU_ERROR("unsupported: lm maxwidth differs\n"); - if (rm->lm_max_width > lm->sblk->maxwidth) - rm->lm_max_width = lm->sblk->maxwidth; - } } for (i = 0; i < cat->merge_3d_count; i++) { @@ -137,7 +126,7 @@ int dpu_rm_init(struct dpu_rm *rm, continue; } hw = dpu_hw_merge_3d_init(merge_3d->id, mmio, cat); - if (IS_ERR_OR_NULL(hw)) { + if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed merge_3d object creation: err %d\n", rc); @@ -155,7 +144,7 @@ int dpu_rm_init(struct dpu_rm *rm, continue; } hw = dpu_hw_pingpong_init(pp->id, mmio, cat); - if (IS_ERR_OR_NULL(hw)) { + if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed pingpong object creation: err %d\n", rc); @@ -179,12 +168,12 @@ int dpu_rm_init(struct dpu_rm *rm, continue; } hw = dpu_hw_intf_init(intf->id, mmio, cat); - if (IS_ERR_OR_NULL(hw)) { + if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed intf object creation: err %d\n", rc); goto fail; } - rm->intf_blks[intf->id - INTF_0] = &hw->base; + rm->hw_intf[intf->id - INTF_0] = hw; } for (i = 0; i < cat->ctl_count; i++) { @@ -196,7 +185,7 @@ int dpu_rm_init(struct dpu_rm *rm, continue; } hw = dpu_hw_ctl_init(ctl->id, mmio, cat); - if (IS_ERR_OR_NULL(hw)) { + if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed ctl object creation: err %d\n", rc); goto fail; @@ -213,7 +202,7 @@ int dpu_rm_init(struct dpu_rm *rm, continue; } hw = dpu_hw_dspp_init(dspp->id, mmio, cat); - if (IS_ERR_OR_NULL(hw)) { + if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed dspp object creation: err %d\n", rc); goto fail; @@ -452,54 +441,6 @@ static int _dpu_rm_reserve_ctls( return 0; } -static int _dpu_rm_reserve_intf( - struct dpu_rm *rm, - struct dpu_global_state *global_state, - uint32_t enc_id, - uint32_t id) -{ - int idx = id - INTF_0; - - if (idx < 0 || idx >= ARRAY_SIZE(rm->intf_blks)) { - DPU_ERROR("invalid intf id: %d", id); - return -EINVAL; - } - - if (!rm->intf_blks[idx]) { - DPU_ERROR("couldn't find intf id %d\n", id); - return -EINVAL; - } - - if (reserved_by_other(global_state->intf_to_enc_id, idx, enc_id)) { - DPU_ERROR("intf id %d already reserved\n", id); - return -ENAVAIL; - } - - global_state->intf_to_enc_id[idx] = enc_id; - return 0; -} - -static int _dpu_rm_reserve_intf_related_hw( - struct dpu_rm *rm, - struct dpu_global_state *global_state, - uint32_t enc_id, - struct dpu_encoder_hw_resources *hw_res) -{ - int i, ret = 0; - u32 id; - - for (i = 0; i < ARRAY_SIZE(hw_res->intfs); i++) { - if (hw_res->intfs[i] == INTF_MODE_NONE) - continue; - id = i + INTF_0; - ret = _dpu_rm_reserve_intf(rm, global_state, enc_id, id); - if (ret) - return ret; - } - - return ret; -} - static int _dpu_rm_make_reservation( struct dpu_rm *rm, struct dpu_global_state *global_state, @@ -521,11 +462,6 @@ static int _dpu_rm_make_reservation( return ret; } - ret = _dpu_rm_reserve_intf_related_hw(rm, global_state, enc->base.id, - &reqs->hw_res); - if (ret) - return ret; - return ret; } @@ -534,8 +470,6 @@ static int _dpu_rm_populate_requirements( struct dpu_rm_requirements *reqs, struct msm_display_topology req_topology) { - dpu_encoder_get_hw_resources(enc, &reqs->hw_res); - reqs->topology = req_topology; DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n", @@ -565,8 +499,6 @@ void dpu_rm_release(struct dpu_global_state *global_state, ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id); _dpu_rm_clear_mapping(global_state->ctl_to_enc_id, ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id); - _dpu_rm_clear_mapping(global_state->intf_to_enc_id, - ARRAY_SIZE(global_state->intf_to_enc_id), enc->base.id); } int dpu_rm_reserve( @@ -630,11 +562,6 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, hw_to_enc_id = global_state->ctl_to_enc_id; max_blks = ARRAY_SIZE(rm->ctl_blks); break; - case DPU_HW_BLK_INTF: - hw_blks = rm->intf_blks; - hw_to_enc_id = global_state->intf_to_enc_id; - max_blks = ARRAY_SIZE(rm->intf_blks); - break; case DPU_HW_BLK_DSPP: hw_blks = rm->dspp_blks; hw_to_enc_id = global_state->dspp_to_enc_id; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index 1f12c8d5b8aa..9b13200a050a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -18,20 +18,16 @@ struct dpu_global_state; * @pingpong_blks: array of pingpong hardware resources * @mixer_blks: array of layer mixer hardware resources * @ctl_blks: array of ctl hardware resources - * @intf_blks: array of intf hardware resources + * @hw_intf: array of intf hardware resources * @dspp_blks: array of dspp hardware resources - * @lm_max_width: cached layer mixer maximum width - * @rm_lock: resource manager mutex */ struct dpu_rm { struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0]; struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0]; struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0]; - struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0]; + struct dpu_hw_intf *hw_intf[INTF_MAX - INTF_0]; struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0]; struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0]; - - uint32_t lm_max_width; }; /** @@ -88,5 +84,16 @@ void dpu_rm_release(struct dpu_global_state *global_state, int dpu_rm_get_assigned_resources(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t enc_id, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size); + +/** + * dpu_rm_get_intf - Return a struct dpu_hw_intf instance given it's index. + * @rm: DPU Resource Manager handle + * @intf_idx: INTF's index + */ +static inline struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_intf intf_idx) +{ + return rm->hw_intf[intf_idx - INTF_0]; +} + #endif /* __DPU_RM_H__ */ diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4.xml.h b/drivers/gpu/drm/msm/disp/mdp4/mdp4.xml.h index c82d1bd09359..a2b6422948ec 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4.xml.h +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index 5a33bb148e9e..3cf476c55158 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -418,7 +418,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) mdp4_kms->dev = dev; - mdp4_kms->mmio = msm_ioremap(pdev, NULL, "MDP4"); + mdp4_kms->mmio = msm_ioremap(pdev, NULL); if (IS_ERR(mdp4_kms->mmio)) { ret = PTR_ERR(mdp4_kms->mmio); goto fail; diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c index 49bdabea8ed5..3e20f72d75ef 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c @@ -7,6 +7,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_damage_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_gem_atomic_helper.h> #include "mdp4_kms.h" @@ -90,6 +91,20 @@ static const struct drm_plane_funcs mdp4_plane_funcs = { .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, }; +static int mdp4_plane_prepare_fb(struct drm_plane *plane, + struct drm_plane_state *new_state) +{ + struct msm_drm_private *priv = plane->dev->dev_private; + struct msm_kms *kms = priv->kms; + + if (!new_state->fb) + return 0; + + drm_gem_plane_helper_prepare_fb(plane, new_state); + + return msm_framebuffer_prepare(new_state->fb, kms->aspace, false); +} + static void mdp4_plane_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state) { @@ -102,7 +117,7 @@ static void mdp4_plane_cleanup_fb(struct drm_plane *plane, return; DBG("%s: cleanup: FB[%u]", mdp4_plane->name, fb->base.id); - msm_framebuffer_cleanup(fb, kms->aspace); + msm_framebuffer_cleanup(fb, kms->aspace, false); } @@ -130,7 +145,7 @@ static void mdp4_plane_atomic_update(struct drm_plane *plane, } static const struct drm_plane_helper_funcs mdp4_plane_helper_funcs = { - .prepare_fb = msm_atomic_prepare_fb, + .prepare_fb = mdp4_plane_prepare_fb, .cleanup_fb = mdp4_plane_cleanup_fb, .atomic_check = mdp4_plane_atomic_check, .atomic_update = mdp4_plane_atomic_update, diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5.xml.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5.xml.h index 0e21cf3f9e2e..86fc44b518cb 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5.xml.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index bb7d066618e6..b966cd69f99d 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -690,6 +690,8 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, { struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc_state); + struct mdp5_interface *intf = mdp5_cstate->pipeline.intf; struct mdp5_kms *mdp5_kms = get_kms(crtc); struct drm_plane *plane; struct drm_device *dev = crtc->dev; @@ -706,12 +708,18 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, DBG("%s: check", crtc->name); drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { + struct mdp5_plane_state *mdp5_pstate = + to_mdp5_plane_state(pstate); + if (!pstate->visible) continue; pstates[cnt].plane = plane; pstates[cnt].state = to_mdp5_plane_state(pstate); + mdp5_pstate->needs_dirtyfb = + intf->mode == MDP5_INTF_DSI_MODE_COMMAND; + /* * if any plane on this crtc uses 2 hwpipes, then we need * the crtc to have a right hwmixer. diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 12a5f81e402b..3b92372e7bdf 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -190,12 +190,6 @@ static void mdp5_complete_commit(struct msm_kms *kms, unsigned crtc_mask) mdp5_smp_complete_commit(mdp5_kms->smp, &global_state->smp); } -static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate, - struct drm_encoder *encoder) -{ - return rate; -} - static int mdp5_set_split_display(struct msm_kms *kms, struct drm_encoder *encoder, struct drm_encoder *slave_encoder, @@ -278,7 +272,6 @@ static const struct mdp_kms_funcs kms_funcs = { .wait_flush = mdp5_wait_flush, .complete_commit = mdp5_complete_commit, .get_format = mdp_get_format, - .round_pixclk = mdp5_round_pixclk, .set_split_display = mdp5_set_split_display, .destroy = mdp5_kms_destroy, #ifdef CONFIG_DEBUG_FS @@ -827,7 +820,7 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) if (ret) goto fail; - mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5"); + mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys"); if (IS_ERR(mdp5_kms->mmio)) { ret = PTR_ERR(mdp5_kms->mmio); goto fail; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h index ac269a6802df..29bf11f08601 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h @@ -100,6 +100,11 @@ struct mdp5_plane_state { /* assigned by crtc blender */ enum mdp_mixer_stage_id stage; + + /* whether attached CRTC needs pixel data explicitly flushed to + * display (ex. DSI command mode display) + */ + bool needs_dirtyfb; }; #define to_mdp5_plane_state(x) \ container_of(x, struct mdp5_plane_state, base) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c index b3f79c2277e9..049c6784a531 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c @@ -210,13 +210,13 @@ int mdp5_mdss_init(struct platform_device *pdev) mdp5_mdss->base.dev = &pdev->dev; - mdp5_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "MDSS"); + mdp5_mdss->mmio = msm_ioremap(pdev, "mdss_phys"); if (IS_ERR(mdp5_mdss->mmio)) { ret = PTR_ERR(mdp5_mdss->mmio); goto fail; } - mdp5_mdss->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF"); + mdp5_mdss->vbif = msm_ioremap(pdev, "vbif_phys"); if (IS_ERR(mdp5_mdss->vbif)) { ret = PTR_ERR(mdp5_mdss->vbif); goto fail; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index c6b69afcbac8..1ee824600995 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -8,6 +8,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_damage_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_print.h> #include "mdp5_kms.h" @@ -48,6 +49,8 @@ static void mdp5_plane_destroy(struct drm_plane *plane) static void mdp5_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj) { + unsigned int zpos; + drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, DRM_MODE_ROTATE_0 | @@ -59,7 +62,12 @@ static void mdp5_plane_install_properties(struct drm_plane *plane, BIT(DRM_MODE_BLEND_PIXEL_NONE) | BIT(DRM_MODE_BLEND_PREMULTI) | BIT(DRM_MODE_BLEND_COVERAGE)); - drm_plane_create_zpos_property(plane, 1, 1, 255); + + if (plane->type == DRM_PLANE_TYPE_PRIMARY) + zpos = STAGE_BASE; + else + zpos = STAGE0 + drm_plane_index(plane); + drm_plane_create_zpos_property(plane, zpos, 1, 255); } static void @@ -91,13 +99,6 @@ static void mdp5_plane_reset(struct drm_plane *plane) kfree(to_mdp5_plane_state(plane->state)); mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); - - if (plane->type == DRM_PLANE_TYPE_PRIMARY) - mdp5_state->base.zpos = STAGE_BASE; - else - mdp5_state->base.zpos = STAGE0 + drm_plane_index(plane); - mdp5_state->base.normalized_zpos = mdp5_state->base.zpos; - __drm_atomic_helper_plane_reset(plane, &mdp5_state->base); } @@ -140,18 +141,34 @@ static const struct drm_plane_funcs mdp5_plane_funcs = { .atomic_print_state = mdp5_plane_atomic_print_state, }; +static int mdp5_plane_prepare_fb(struct drm_plane *plane, + struct drm_plane_state *new_state) +{ + struct msm_drm_private *priv = plane->dev->dev_private; + struct msm_kms *kms = priv->kms; + bool needs_dirtyfb = to_mdp5_plane_state(new_state)->needs_dirtyfb; + + if (!new_state->fb) + return 0; + + drm_gem_plane_helper_prepare_fb(plane, new_state); + + return msm_framebuffer_prepare(new_state->fb, kms->aspace, needs_dirtyfb); +} + static void mdp5_plane_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state) { struct mdp5_kms *mdp5_kms = get_kms(plane); struct msm_kms *kms = &mdp5_kms->base.base; struct drm_framebuffer *fb = old_state->fb; + bool needed_dirtyfb = to_mdp5_plane_state(old_state)->needs_dirtyfb; if (!fb) return; DBG("%s: cleanup: FB[%u]", plane->name, fb->base.id); - msm_framebuffer_cleanup(fb, kms->aspace); + msm_framebuffer_cleanup(fb, kms->aspace, needed_dirtyfb); } static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state, @@ -437,7 +454,7 @@ static void mdp5_plane_atomic_async_update(struct drm_plane *plane, } static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = { - .prepare_fb = msm_atomic_prepare_fb, + .prepare_fb = mdp5_plane_prepare_fb, .cleanup_fb = mdp5_plane_cleanup_fb, .atomic_check = mdp5_plane_atomic_check, .atomic_update = mdp5_plane_atomic_update, diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c index d7fa2c49e741..56a3063545ec 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c @@ -68,7 +68,7 @@ static int smp_request_block(struct mdp5_smp *smp, uint8_t reserved; /* we shouldn't be requesting blocks for an in-use client: */ - WARN_ON(bitmap_weight(cs, cnt) > 0); + WARN_ON(!bitmap_empty(cs, cnt)); reserved = smp->reserved[cid]; diff --git a/drivers/gpu/drm/msm/disp/mdp_common.xml.h b/drivers/gpu/drm/msm/disp/mdp_common.xml.h index bb0066a63732..be759106b621 100644 --- a/drivers/gpu/drm/msm/disp/mdp_common.xml.h +++ b/drivers/gpu/drm/msm/disp/mdp_common.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 8a6d3ead3440..fac815fb6d91 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -456,19 +456,19 @@ void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, dp_write_p0(catalog, MMSS_DP_DSC_DTO, 0x0); } -int dp_catalog_ctrl_set_pattern(struct dp_catalog *dp_catalog, - u32 pattern) +int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog, + u32 state_bit) { int bit, ret; u32 data; struct dp_catalog_private *catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog); - bit = BIT(pattern - 1); - DRM_DEBUG_DP("hw: bit=%d train=%d\n", bit, pattern); + bit = BIT(state_bit - 1); + DRM_DEBUG_DP("hw: bit=%d train=%d\n", bit, state_bit); dp_catalog_ctrl_state_ctrl(dp_catalog, bit); - bit = BIT(pattern - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT; + bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT; /* Poll for mainlink ready status */ ret = readx_poll_timeout(readl, catalog->io->dp_controller.link.base + @@ -476,7 +476,7 @@ int dp_catalog_ctrl_set_pattern(struct dp_catalog *dp_catalog, data, data & bit, POLLING_SLEEP_US, POLLING_TIMEOUT_US); if (ret < 0) { - DRM_ERROR("set pattern for link_train=%d failed\n", pattern); + DRM_ERROR("set state_bit for link_train=%d failed\n", state_bit); return ret; } return 0; diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h index 6965afa81aad..7dea1012ae66 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.h +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h @@ -94,7 +94,7 @@ void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog, u32 cc, u32 tb); void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, u32 rate, u32 stream_rate_khz, bool fixed_nvid); -int dp_catalog_ctrl_set_pattern(struct dp_catalog *dp_catalog, u32 pattern); +int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog, u32 pattern); void dp_catalog_ctrl_reset(struct dp_catalog *dp_catalog); bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c b/drivers/gpu/drm/msm/dp/dp_clk_util.c index 078afc5f5882..44a4fc59ff31 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +++ b/drivers/gpu/drm/msm/dp/dp_clk_util.c @@ -11,7 +11,7 @@ #include <drm/drm_print.h> -#include "dpu_io_util.h" +#include "dp_clk_util.h" void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk) { @@ -118,70 +118,3 @@ int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable) return rc; } - -int msm_dss_parse_clock(struct platform_device *pdev, - struct dss_module_power *mp) -{ - u32 i, rc = 0; - const char *clock_name; - int num_clk = 0; - - if (!pdev || !mp) - return -EINVAL; - - mp->num_clk = 0; - num_clk = of_property_count_strings(pdev->dev.of_node, "clock-names"); - if (num_clk <= 0) { - pr_debug("clocks are not defined\n"); - return 0; - } - - mp->clk_config = devm_kcalloc(&pdev->dev, - num_clk, sizeof(struct dss_clk), - GFP_KERNEL); - if (!mp->clk_config) - return -ENOMEM; - - for (i = 0; i < num_clk; i++) { - rc = of_property_read_string_index(pdev->dev.of_node, - "clock-names", i, - &clock_name); - if (rc) { - DRM_DEV_ERROR(&pdev->dev, "Failed to get clock name for %d\n", - i); - break; - } - strlcpy(mp->clk_config[i].clk_name, clock_name, - sizeof(mp->clk_config[i].clk_name)); - - mp->clk_config[i].type = DSS_CLK_AHB; - } - - rc = msm_dss_get_clk(&pdev->dev, mp->clk_config, num_clk); - if (rc) { - DRM_DEV_ERROR(&pdev->dev, "Failed to get clock refs %d\n", rc); - goto err; - } - - rc = of_clk_set_defaults(pdev->dev.of_node, false); - if (rc) { - DRM_DEV_ERROR(&pdev->dev, "Failed to set clock defaults %d\n", rc); - goto err; - } - - for (i = 0; i < num_clk; i++) { - u32 rate = clk_get_rate(mp->clk_config[i].clk); - if (!rate) - continue; - mp->clk_config[i].rate = rate; - mp->clk_config[i].type = DSS_CLK_PCLK; - mp->clk_config[i].max_rate = rate; - } - - mp->num_clk = num_clk; - return 0; - -err: - msm_dss_put_clk(mp->clk_config, num_clk); - return rc; -} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h b/drivers/gpu/drm/msm/dp/dp_clk_util.h index e6b5c772fa3b..067bf87f3d97 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h +++ b/drivers/gpu/drm/msm/dp/dp_clk_util.h @@ -2,8 +2,8 @@ /* Copyright (c) 2012, 2017-2018, The Linux Foundation. All rights reserved. */ -#ifndef __DPU_IO_UTIL_H__ -#define __DPU_IO_UTIL_H__ +#ifndef __DP_CLK_UTIL_H__ +#define __DP_CLK_UTIL_H__ #include <linux/platform_device.h> #include <linux/types.h> @@ -35,6 +35,4 @@ int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk); void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk); int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk); int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable); -int msm_dss_parse_clock(struct platform_device *pdev, - struct dss_module_power *mp); -#endif /* __DPU_IO_UTIL_H__ */ +#endif /* __DP_CLK_UTIL_H__ */ diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 88ca6c3aedd3..53568567e05b 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1083,7 +1083,7 @@ static int dp_ctrl_link_train_1(struct dp_ctrl_private *ctrl, *training_step = DP_TRAINING_1; - ret = dp_catalog_ctrl_set_pattern(ctrl->catalog, DP_TRAINING_PATTERN_1); + ret = dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, 1); if (ret) return ret; dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 | @@ -1181,7 +1181,8 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl, int *training_step) { int tries = 0, ret = 0; - char pattern; + u8 pattern; + u32 state_ctrl_bit; int const maximum_retries = 5; u8 link_status[DP_LINK_STATUS_SIZE]; @@ -1189,12 +1190,18 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl, *training_step = DP_TRAINING_2; - if (drm_dp_tps3_supported(ctrl->panel->dpcd)) + if (drm_dp_tps4_supported(ctrl->panel->dpcd)) { + pattern = DP_TRAINING_PATTERN_4; + state_ctrl_bit = 4; + } else if (drm_dp_tps3_supported(ctrl->panel->dpcd)) { pattern = DP_TRAINING_PATTERN_3; - else + state_ctrl_bit = 3; + } else { pattern = DP_TRAINING_PATTERN_2; + state_ctrl_bit = 2; + } - ret = dp_catalog_ctrl_set_pattern(ctrl->catalog, pattern); + ret = dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, state_ctrl_bit); if (ret) return ret; @@ -1365,60 +1372,48 @@ static int dp_ctrl_enable_stream_clocks(struct dp_ctrl_private *ctrl) return ret; } -int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset) +void dp_ctrl_reset_irq_ctrl(struct dp_ctrl *dp_ctrl, bool enable) +{ + struct dp_ctrl_private *ctrl; + + ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); + + dp_catalog_ctrl_reset(ctrl->catalog); + + if (enable) + dp_catalog_ctrl_enable_irq(ctrl->catalog, enable); +} + +void dp_ctrl_phy_init(struct dp_ctrl *dp_ctrl) { struct dp_ctrl_private *ctrl; struct dp_io *dp_io; struct phy *phy; - if (!dp_ctrl) { - DRM_ERROR("Invalid input data\n"); - return -EINVAL; - } - ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); dp_io = &ctrl->parser->io; phy = dp_io->phy; - ctrl->dp_ctrl.orientation = flip; - - if (reset) - dp_catalog_ctrl_reset(ctrl->catalog); - - DRM_DEBUG_DP("flip=%d\n", flip); dp_catalog_ctrl_phy_reset(ctrl->catalog); phy_init(phy); - dp_catalog_ctrl_enable_irq(ctrl->catalog, true); - - return 0; + DRM_DEBUG_DP("phy=%p init=%d power_on=%d\n", + phy, phy->init_count, phy->power_count); } -/** - * dp_ctrl_host_deinit() - Uninitialize DP controller - * @dp_ctrl: Display Port Driver data - * - * Perform required steps to uninitialize DP controller - * and its resources. - */ -void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl) +void dp_ctrl_phy_exit(struct dp_ctrl *dp_ctrl) { struct dp_ctrl_private *ctrl; struct dp_io *dp_io; struct phy *phy; - if (!dp_ctrl) { - DRM_ERROR("Invalid input data\n"); - return; - } - ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); dp_io = &ctrl->parser->io; phy = dp_io->phy; - dp_catalog_ctrl_enable_irq(ctrl->catalog, false); + dp_catalog_ctrl_phy_reset(ctrl->catalog); phy_exit(phy); - - DRM_DEBUG_DP("Host deinitialized successfully\n"); + DRM_DEBUG_DP("phy=%p init=%d power_on=%d\n", + phy, phy->init_count, phy->power_count); } static bool dp_ctrl_use_fixed_nvid(struct dp_ctrl_private *ctrl) @@ -1488,8 +1483,13 @@ static int dp_ctrl_deinitialize_mainlink(struct dp_ctrl_private *ctrl) } phy_power_off(phy); + + /* aux channel down, reinit phy */ phy_exit(phy); + phy_init(phy); + DRM_DEBUG_DP("phy=%p init=%d power_on=%d\n", + phy, phy->init_count, phy->power_count); return 0; } @@ -1761,6 +1761,9 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) /* end with failure */ break; /* lane == 1 already */ } + + /* stop link training before start re training */ + dp_ctrl_clear_training_pattern(ctrl); } } @@ -1893,33 +1896,20 @@ int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl) return ret; } + DRM_DEBUG_DP("Before, phy=%x init_count=%d power_on=%d\n", + (u32)(uintptr_t)phy, phy->init_count, phy->power_count); + phy_power_off(phy); /* aux channel down, reinit phy */ phy_exit(phy); phy_init(phy); - DRM_DEBUG_DP("DP off link/stream done\n"); + DRM_DEBUG_DP("phy=%p init=%d power_on=%d\n", + phy, phy->init_count, phy->power_count); return ret; } -void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl) -{ - struct dp_ctrl_private *ctrl; - struct dp_io *dp_io; - struct phy *phy; - - ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); - dp_io = &ctrl->parser->io; - phy = dp_io->phy; - - dp_catalog_ctrl_reset(ctrl->catalog); - - phy_exit(phy); - - DRM_DEBUG_DP("DP off phy done\n"); -} - int dp_ctrl_off(struct dp_ctrl *dp_ctrl) { struct dp_ctrl_private *ctrl; @@ -1948,9 +1938,9 @@ int dp_ctrl_off(struct dp_ctrl *dp_ctrl) } phy_power_off(phy); - phy_exit(phy); + DRM_DEBUG_DP("phy=%p init=%d power_on=%d\n", + phy, phy->init_count, phy->power_count); - DRM_DEBUG_DP("DP off done\n"); return ret; } diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h index 2363a2df9597..2433edbc70a6 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.h +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h @@ -19,12 +19,9 @@ struct dp_ctrl { u32 pixel_rate; }; -int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset); -void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl); int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl); int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl); int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl); -void dp_ctrl_off_phy(struct dp_ctrl *dp_ctrl); int dp_ctrl_off(struct dp_ctrl *dp_ctrl); void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl); void dp_ctrl_isr(struct dp_ctrl *dp_ctrl); @@ -34,4 +31,9 @@ struct dp_ctrl *dp_ctrl_get(struct device *dev, struct dp_link *link, struct dp_power *power, struct dp_catalog *catalog, struct dp_parser *parser); +void dp_ctrl_reset_irq_ctrl(struct dp_ctrl *dp_ctrl, bool enable); +void dp_ctrl_phy_init(struct dp_ctrl *dp_ctrl); +void dp_ctrl_phy_exit(struct dp_ctrl *dp_ctrl); +void dp_ctrl_irq_phy_exit(struct dp_ctrl *dp_ctrl); + #endif /* _DP_CTRL_H_ */ diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c b/drivers/gpu/drm/msm/dp/dp_debug.c index da4323556ef3..2f9c943f12d5 100644 --- a/drivers/gpu/drm/msm/dp/dp_debug.c +++ b/drivers/gpu/drm/msm/dp/dp_debug.c @@ -207,39 +207,39 @@ static const struct file_operations test_active_fops = { .write = dp_test_active_write }; -static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) +static void dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) { - int rc = 0; + char path[64]; struct dp_debug_private *debug = container_of(dp_debug, struct dp_debug_private, dp_debug); - debugfs_create_file("dp_debug", 0444, minor->debugfs_root, + snprintf(path, sizeof(path), "msm_dp-%s", debug->connector->name); + + debug->root = debugfs_create_dir(path, minor->debugfs_root); + + debugfs_create_file("dp_debug", 0444, debug->root, debug, &dp_debug_fops); debugfs_create_file("msm_dp_test_active", 0444, - minor->debugfs_root, + debug->root, debug, &test_active_fops); debugfs_create_file("msm_dp_test_data", 0444, - minor->debugfs_root, + debug->root, debug, &dp_test_data_fops); debugfs_create_file("msm_dp_test_type", 0444, - minor->debugfs_root, + debug->root, debug, &dp_test_type_fops); - - debug->root = minor->debugfs_root; - - return rc; } struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, struct dp_usbpd *usbpd, struct dp_link *link, struct drm_connector *connector, struct drm_minor *minor) { - int rc = 0; struct dp_debug_private *debug; struct dp_debug *dp_debug; + int rc; if (!dev || !panel || !usbpd || !link) { DRM_ERROR("invalid input\n"); @@ -266,11 +266,7 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, dp_debug->hdisplay = 0; dp_debug->vrefresh = 0; - rc = dp_debug_init(dp_debug, minor); - if (rc) { - devm_kfree(dev, debug); - goto error; - } + dp_debug_init(dp_debug, minor); return dp_debug; error: diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 7cc4d21f2091..178b774a5fbd 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -83,6 +83,7 @@ struct dp_display_private { /* state variables */ bool core_initialized; + bool phy_initialized; bool hpd_irq_on; bool audio_supported; @@ -143,10 +144,29 @@ static const struct msm_dp_config sc7280_dp_cfg = { .num_descs = 2, }; +static const struct msm_dp_config sc8180x_dp_cfg = { + .descs = (const struct msm_dp_desc[]) { + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, + [MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, + [MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, .connector_type = DRM_MODE_CONNECTOR_eDP }, + }, + .num_descs = 3, +}; + +static const struct msm_dp_config sm8350_dp_cfg = { + .descs = (const struct msm_dp_desc[]) { + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, + }, + .num_descs = 1, +}; + static const struct of_device_id dp_dt_match[] = { { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_cfg }, { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_cfg }, { .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_cfg }, + { .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_cfg }, + { .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_cfg }, + { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_cfg }, {} }; @@ -246,7 +266,7 @@ static int dp_display_bind(struct device *dev, struct device *master, goto end; } - dp->dp_display.panel_bridge = dp->parser->panel_bridge; + dp->dp_display.next_bridge = dp->parser->next_bridge; dp->aux->drm_dev = drm; rc = dp_aux_register(dp->aux); @@ -372,36 +392,51 @@ end: return rc; } -static void dp_display_host_init(struct dp_display_private *dp, int reset) +static void dp_display_host_phy_init(struct dp_display_private *dp) { - bool flip = false; + DRM_DEBUG_DP("type=%d core_init=%d phy_init=%d\n", + dp->dp_display.connector_type, dp->core_initialized, + dp->phy_initialized); - DRM_DEBUG_DP("core_initialized=%d\n", dp->core_initialized); - if (dp->core_initialized) { - DRM_DEBUG_DP("DP core already initialized\n"); - return; + if (!dp->phy_initialized) { + dp_ctrl_phy_init(dp->ctrl); + dp->phy_initialized = true; + } +} + +static void dp_display_host_phy_exit(struct dp_display_private *dp) +{ + DRM_DEBUG_DP("type=%d core_init=%d phy_init=%d\n", + dp->dp_display.connector_type, dp->core_initialized, + dp->phy_initialized); + + if (dp->phy_initialized) { + dp_ctrl_phy_exit(dp->ctrl); + dp->phy_initialized = false; } +} - if (dp->usbpd->orientation == ORIENTATION_CC2) - flip = true; +static void dp_display_host_init(struct dp_display_private *dp) +{ + DRM_DEBUG_DP("type=%d core_init=%d phy_init=%d\n", + dp->dp_display.connector_type, dp->core_initialized, + dp->phy_initialized); - dp_power_init(dp->power, flip); - dp_ctrl_host_init(dp->ctrl, flip, reset); + dp_power_init(dp->power, false); + dp_ctrl_reset_irq_ctrl(dp->ctrl, true); dp_aux_init(dp->aux); dp->core_initialized = true; } static void dp_display_host_deinit(struct dp_display_private *dp) { - if (!dp->core_initialized) { - DRM_DEBUG_DP("DP core not initialized\n"); - return; - } + DRM_DEBUG_DP("type=%d core_init=%d phy_init=%d\n", + dp->dp_display.connector_type, dp->core_initialized, + dp->phy_initialized); - dp_ctrl_host_deinit(dp->ctrl); + dp_ctrl_reset_irq_ctrl(dp->ctrl, false); dp_aux_deinit(dp->aux); dp_power_deinit(dp->power); - dp->core_initialized = false; } @@ -409,7 +444,7 @@ static int dp_display_usbpd_configure_cb(struct device *dev) { struct dp_display_private *dp = dev_get_dp_display_private(dev); - dp_display_host_init(dp, false); + dp_display_host_phy_init(dp); return dp_display_process_hpd_high(dp); } @@ -507,7 +542,9 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) mutex_lock(&dp->event_mutex); state = dp->hpd_state; - DRM_DEBUG_DP("hpd_state=%d\n", state); + DRM_DEBUG_DP("Before, type=%d hpd_state=%d\n", + dp->dp_display.connector_type, state); + if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) { mutex_unlock(&dp->event_mutex); return 0; @@ -530,11 +567,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) ret = dp_display_usbpd_configure_cb(&dp->pdev->dev); if (ret) { /* link train failed */ dp->hpd_state = ST_DISCONNECTED; - - if (ret == -ECONNRESET) { /* cable unplugged */ - dp->core_initialized = false; - } - } else { /* start sentinel checking in case of missing uevent */ dp_add_event(dp, EV_CONNECT_PENDING_TIMEOUT, 0, tout); @@ -544,6 +576,8 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) dp_catalog_hpd_config_intr(dp->catalog, DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, true); + DRM_DEBUG_DP("After, type=%d hpd_state=%d\n", + dp->dp_display.connector_type, state); mutex_unlock(&dp->event_mutex); /* uevent will complete connection part */ @@ -560,8 +594,10 @@ static int dp_connect_pending_timeout(struct dp_display_private *dp, u32 data) mutex_lock(&dp->event_mutex); state = dp->hpd_state; - if (state == ST_CONNECT_PENDING) + if (state == ST_CONNECT_PENDING) { dp->hpd_state = ST_CONNECTED; + DRM_DEBUG_DP("type=%d\n", dp->dp_display.connector_type); + } mutex_unlock(&dp->event_mutex); @@ -594,6 +630,9 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) state = dp->hpd_state; + DRM_DEBUG_DP("Before, type=%d hpd_state=%d\n", + dp->dp_display.connector_type, state); + /* disable irq_hpd/replug interrupts */ dp_catalog_hpd_config_intr(dp->catalog, DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, false); @@ -604,8 +643,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) if (state == ST_DISCONNECTED) { /* triggered by irq_hdp with sink_count = 0 */ if (dp->link->sink_count == 0) { - dp_ctrl_off_phy(dp->ctrl); - dp->core_initialized = false; + dp_display_host_phy_exit(dp); } mutex_unlock(&dp->event_mutex); return 0; @@ -637,13 +675,15 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) /* start sentinel checking in case of missing uevent */ dp_add_event(dp, EV_DISCONNECT_PENDING_TIMEOUT, 0, DP_TIMEOUT_5_SECOND); - DRM_DEBUG_DP("hpd_state=%d\n", state); /* signal the disconnect event early to ensure proper teardown */ dp_display_handle_plugged_change(&dp->dp_display, false); /* enable HDP plug interrupt to prepare for next plugin */ dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true); + DRM_DEBUG_DP("After, type=%d hpd_state=%d\n", + dp->dp_display.connector_type, state); + /* uevent will complete disconnection part */ mutex_unlock(&dp->event_mutex); return 0; @@ -656,8 +696,10 @@ static int dp_disconnect_pending_timeout(struct dp_display_private *dp, u32 data mutex_lock(&dp->event_mutex); state = dp->hpd_state; - if (state == ST_DISCONNECT_PENDING) + if (state == ST_DISCONNECT_PENDING) { dp->hpd_state = ST_DISCONNECTED; + DRM_DEBUG_DP("type=%d\n", dp->dp_display.connector_type); + } mutex_unlock(&dp->event_mutex); @@ -667,12 +709,14 @@ static int dp_disconnect_pending_timeout(struct dp_display_private *dp, u32 data static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) { u32 state; - int ret; mutex_lock(&dp->event_mutex); /* irq_hpd can happen at either connected or disconnected state */ state = dp->hpd_state; + DRM_DEBUG_DP("Before, type=%d hpd_state=%d\n", + dp->dp_display.connector_type, state); + if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) { mutex_unlock(&dp->event_mutex); return 0; @@ -692,17 +736,10 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) return 0; } - /* - * dp core (ahb/aux clks) must be initialized before - * irq_hpd be handled - */ - if (dp->core_initialized) { - ret = dp_display_usbpd_attention_cb(&dp->pdev->dev); - if (ret == -ECONNRESET) { /* cable unplugged */ - dp->core_initialized = false; - } - } - DRM_DEBUG_DP("hpd_state=%d\n", state); + dp_display_usbpd_attention_cb(&dp->pdev->dev); + + DRM_DEBUG_DP("After, type=%d hpd_state=%d\n", + dp->dp_display.connector_type, state); mutex_unlock(&dp->event_mutex); @@ -892,12 +929,19 @@ static int dp_display_disable(struct dp_display_private *dp, u32 data) dp_display->audio_enabled = false; - /* triggered by irq_hpd with sink_count = 0 */ if (dp->link->sink_count == 0) { + /* + * irq_hpd with sink_count = 0 + * hdmi unplugged out of dongle + */ dp_ctrl_off_link_stream(dp->ctrl); } else { + /* + * unplugged interrupt + * dongle unplugged out of DUT + */ dp_ctrl_off(dp->ctrl); - dp->core_initialized = false; + dp_display_host_phy_exit(dp); } dp_display->power_on = false; @@ -1027,7 +1071,7 @@ void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp) static void dp_display_config_hpd(struct dp_display_private *dp) { - dp_display_host_init(dp, true); + dp_display_host_init(dp); dp_catalog_ctrl_hpd_config(dp->catalog); /* Enable interrupt first time @@ -1145,8 +1189,9 @@ static irqreturn_t dp_display_irq_handler(int irq, void *dev_id) hpd_isr_status = dp_catalog_hpd_get_intr_status(dp->catalog); - DRM_DEBUG_DP("hpd isr status=%#x\n", hpd_isr_status); if (hpd_isr_status & 0x0F) { + DRM_DEBUG_DP("type=%d isr=0x%x\n", + dp->dp_display.connector_type, hpd_isr_status); /* hpd related interrupts */ if (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK) dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0); @@ -1299,27 +1344,31 @@ static int dp_pm_resume(struct device *dev) mutex_lock(&dp->event_mutex); - DRM_DEBUG_DP("Before, core_inited=%d power_on=%d\n", - dp->core_initialized, dp_display->power_on); + DRM_DEBUG_DP("Before, type=%d core_inited=%d phy_inited=%d power_on=%d\n", + dp->dp_display.connector_type, dp->core_initialized, + dp->phy_initialized, dp_display->power_on); /* start from disconnected state */ dp->hpd_state = ST_DISCONNECTED; /* turn on dp ctrl/phy */ - dp_display_host_init(dp, true); + dp_display_host_init(dp); dp_catalog_ctrl_hpd_config(dp->catalog); - /* - * set sink to normal operation mode -- D0 - * before dpcd read - */ - dp_link_psm_config(dp->link, &dp->panel->link_info, false); if (dp_catalog_link_is_connected(dp->catalog)) { + /* + * set sink to normal operation mode -- D0 + * before dpcd read + */ + dp_display_host_phy_init(dp); + dp_link_psm_config(dp->link, &dp->panel->link_info, false); sink_count = drm_dp_read_sink_count(dp->aux); if (sink_count < 0) sink_count = 0; + + dp_display_host_phy_exit(dp); } dp->link->sink_count = sink_count; @@ -1336,9 +1385,11 @@ static int dp_pm_resume(struct device *dev) dp_display_handle_plugged_change(dp_display, false); } - DRM_DEBUG_DP("After, sink_count=%d is_connected=%d core_inited=%d power_on=%d\n", - dp->link->sink_count, dp->dp_display.is_connected, - dp->core_initialized, dp_display->power_on); + DRM_DEBUG_DP("After, type=%d sink_count=%d is_connected=%d \ + core_inited=%d phy_inited=%d power_on=%d\n", + dp->dp_display.connector_type, dp->link->sink_count, + dp->dp_display.is_connected, dp->core_initialized, + dp->phy_initialized, dp_display->power_on); mutex_unlock(&dp->event_mutex); @@ -1355,24 +1406,24 @@ static int dp_pm_suspend(struct device *dev) mutex_lock(&dp->event_mutex); - DRM_DEBUG_DP("Before, core_inited=%d power_on=%d\n", - dp->core_initialized, dp_display->power_on); - - if (dp->core_initialized == true) { - /* mainlink enabled */ - if (dp_power_clk_status(dp->power, DP_CTRL_PM)) - dp_ctrl_off_link_stream(dp->ctrl); + DRM_DEBUG_DP("Before, type=%d core_inited=%d phy_inited=%d power_on=%d\n", + dp->dp_display.connector_type, dp->core_initialized, + dp->phy_initialized, dp_display->power_on); - dp_display_host_deinit(dp); - } + /* mainlink enabled */ + if (dp_power_clk_status(dp->power, DP_CTRL_PM)) + dp_ctrl_off_link_stream(dp->ctrl); - dp->hpd_state = ST_SUSPENDED; + dp_display_host_phy_exit(dp); /* host_init will be called at pm_resume */ - dp->core_initialized = false; + dp_display_host_deinit(dp); + + dp->hpd_state = ST_SUSPENDED; - DRM_DEBUG_DP("After, core_inited=%d power_on=%d\n", - dp->core_initialized, dp_display->power_on); + DRM_DEBUG_DP("After, type=%d core_inited=%d phy_inited=%d power_on=%d\n", + dp->dp_display.connector_type, dp->core_initialized, + dp->phy_initialized, dp_display->power_on); mutex_unlock(&dp->event_mutex); @@ -1460,6 +1511,7 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, struct drm_encoder *encoder) { struct msm_drm_private *priv; + struct dp_display_private *dp_priv; int ret; if (WARN_ON(!encoder) || WARN_ON(!dp_display) || WARN_ON(!dev)) @@ -1468,6 +1520,8 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, priv = dev->dev_private; dp_display->drm_dev = dev; + dp_priv = container_of(dp_display, struct dp_display_private, dp_display); + ret = dp_display_request_irq(dp_display); if (ret) { DRM_ERROR("request_irq failed, ret=%d\n", ret); @@ -1485,6 +1539,8 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, return ret; } + dp_priv->panel->connector = dp_display->connector; + priv->connectors[priv->num_connectors++] = dp_display->connector; dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder); @@ -1535,7 +1591,7 @@ int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder) state = dp_display->hpd_state; if (state == ST_DISPLAY_OFF) - dp_display_host_init(dp_display, true); + dp_display_host_phy_init(dp_display); dp_display_enable(dp_display, 0); diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h index e3adcd578a90..7af2b186d2d9 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.h +++ b/drivers/gpu/drm/msm/dp/dp_display.h @@ -16,7 +16,7 @@ struct msm_dp { struct drm_bridge *bridge; struct drm_connector *connector; struct drm_encoder *encoder; - struct drm_bridge *panel_bridge; + struct drm_bridge *next_bridge; bool is_connected; bool audio_enabled; bool power_on; diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index d4d360d19eba..80f59cf99089 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.c +++ b/drivers/gpu/drm/msm/dp/dp_drm.c @@ -169,16 +169,6 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display) drm_connector_attach_encoder(connector, dp_display->encoder); - if (dp_display->panel_bridge) { - ret = drm_bridge_attach(dp_display->encoder, - dp_display->panel_bridge, NULL, - DRM_BRIDGE_ATTACH_NO_CONNECTOR); - if (ret < 0) { - DRM_ERROR("failed to attach panel bridge: %d\n", ret); - return ERR_PTR(ret); - } - } - return connector; } @@ -246,5 +236,16 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi return ERR_PTR(rc); } + if (dp_display->next_bridge) { + rc = drm_bridge_attach(dp_display->encoder, + dp_display->next_bridge, bridge, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (rc < 0) { + DRM_ERROR("failed to attach panel bridge: %d\n", rc); + drm_bridge_remove(bridge); + return ERR_PTR(rc); + } + } + return bridge; } diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c index 71db10c0f262..f1418722c549 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.c +++ b/drivers/gpu/drm/msm/dp/dp_panel.c @@ -212,6 +212,11 @@ int dp_panel_read_sink_caps(struct dp_panel *dp_panel, if (drm_add_modes_noedid(connector, 640, 480)) drm_set_preferred_mode(connector, 640, 480); mutex_unlock(&connector->dev->mode_config.mutex); + } else { + /* always add fail-safe mode as backup mode */ + mutex_lock(&connector->dev->mode_config.mutex); + drm_add_modes_noedid(connector, 640, 480); + mutex_unlock(&connector->dev->mode_config.mutex); } if (panel->aux_cfg_update_done) { diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c index a7acc23f742b..1056b8d5755b 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.c +++ b/drivers/gpu/drm/msm/dp/dp_parser.c @@ -265,23 +265,16 @@ static int dp_parser_clock(struct dp_parser *parser) return 0; } -static int dp_parser_find_panel(struct dp_parser *parser) +static int dp_parser_find_next_bridge(struct dp_parser *parser) { struct device *dev = &parser->pdev->dev; - struct drm_panel *panel; - int rc; + struct drm_bridge *bridge; - rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL); - if (rc) { - DRM_ERROR("failed to acquire DRM panel: %d\n", rc); - return rc; - } + bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); + if (IS_ERR(bridge)) + return PTR_ERR(bridge); - parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel); - if (IS_ERR(parser->panel_bridge)) { - DRM_ERROR("failed to create panel bridge\n"); - return PTR_ERR(parser->panel_bridge); - } + parser->next_bridge = bridge; return 0; } @@ -307,10 +300,23 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type) if (rc) return rc; - if (connector_type == DRM_MODE_CONNECTOR_eDP) { - rc = dp_parser_find_panel(parser); - if (rc) + /* + * External bridges are mandatory for eDP interfaces: one has to + * provide at least an eDP panel (which gets wrapped into panel-bridge). + * + * For DisplayPort interfaces external bridges are optional, so + * silently ignore an error if one is not present (-ENODEV). + */ + rc = dp_parser_find_next_bridge(parser); + if (rc == -ENODEV) { + if (connector_type == DRM_MODE_CONNECTOR_eDP) { + DRM_ERROR("eDP: next bridge is not present\n"); return rc; + } + } else if (rc) { + if (rc != -EPROBE_DEFER) + DRM_ERROR("DP: error parsing next bridge: %d\n", rc); + return rc; } /* Map the corresponding regulator information according to diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h index 3172da089421..d371bae1c968 100644 --- a/drivers/gpu/drm/msm/dp/dp_parser.h +++ b/drivers/gpu/drm/msm/dp/dp_parser.h @@ -10,7 +10,7 @@ #include <linux/phy/phy.h> #include <linux/phy/phy-dp.h> -#include "dpu_io_util.h" +#include "dp_clk_util.h" #include "msm_drv.h" #define DP_LABEL "MDSS DP DISPLAY" @@ -123,7 +123,7 @@ struct dp_parser { struct dp_display_data disp_data; const struct dp_regulator_cfg *regulator_cfg; u32 max_dp_lanes; - struct drm_bridge *panel_bridge; + struct drm_bridge *next_bridge; int (*parse)(struct dp_parser *parser, int connector_type); }; diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 0fe02529b5e7..c12e66aa42a3 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -4,6 +4,7 @@ */ #include "dsi.h" +#include "dsi_cfg.h" struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi) { @@ -175,7 +176,8 @@ static int dsi_dev_remove(struct platform_device *pdev) } static const struct of_device_id dt_match[] = { - { .compatible = "qcom,mdss-dsi-ctrl" }, + { .compatible = "qcom,mdss-dsi-ctrl", .data = NULL /* autodetect cfg */ }, + { .compatible = "qcom,dsi-ctrl-6g-qcm2290", .data = &qcm2290_dsi_cfg_handler }, {} }; diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h index 49b551ad1bff..4dee6f0bdda6 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c index 96bbc8b6d009..2c23324a2296 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c @@ -213,6 +213,24 @@ static const struct msm_dsi_config sc7280_dsi_cfg = { .num_dsi = 1, }; +static const char * const dsi_qcm2290_bus_clk_names[] = { + "iface", "bus", +}; + +static const struct msm_dsi_config qcm2290_dsi_cfg = { + .io_offset = DSI_6G_REG_SHIFT, + .reg_cfg = { + .num = 1, + .regs = { + {"vdda", 21800, 4 }, /* 1.2 V */ + }, + }, + .bus_clk_names = dsi_qcm2290_bus_clk_names, + .num_bus_clks = ARRAY_SIZE(dsi_qcm2290_bus_clk_names), + .io_start = { 0x5e94000 }, + .num_dsi = 1, +}; + 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, @@ -300,3 +318,8 @@ const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor) return cfg_hnd; } +/* Non autodetect configs */ +const struct msm_dsi_cfg_handler qcm2290_dsi_cfg_handler = { + .cfg = &qcm2290_dsi_cfg, + .ops = &msm_dsi_6g_v2_host_ops, +}; diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h index 41e99a9fb5de..fe54a999968b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h @@ -60,5 +60,8 @@ struct msm_dsi_cfg_handler { const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor); +/* Non autodetect configs */ +extern const struct msm_dsi_cfg_handler qcm2290_dsi_cfg_handler; + #endif /* __MSM_DSI_CFG_H__ */ diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 6b3ced4aaaf5..d51e70fab93d 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -212,6 +212,10 @@ static const struct msm_dsi_cfg_handler *dsi_get_config( int ret; u32 major = 0, minor = 0; + cfg_hnd = device_get_match_data(dev); + if (cfg_hnd) + return cfg_hnd; + ahb_clk = msm_clk_get(msm_host->pdev, "iface"); if (IS_ERR(ahb_clk)) { pr_err("%s: cannot get interface clock\n", __func__); @@ -1813,7 +1817,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) goto fail; } - msm_host->ctrl_base = msm_ioremap_size(pdev, "dsi_ctrl", "DSI CTRL", &msm_host->ctrl_size); + msm_host->ctrl_base = msm_ioremap_size(pdev, "dsi_ctrl", &msm_host->ctrl_size); if (IS_ERR(msm_host->ctrl_base)) { pr_err("%s: unable to map Dsi ctrl base\n", __func__); ret = PTR_ERR(msm_host->ctrl_base); @@ -1877,7 +1881,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) /* do not autoenable, will be enabled later */ ret = devm_request_irq(&pdev->dev, msm_host->irq, dsi_host_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN, + IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN, "dsi_isr", msm_host); if (ret < 0) { dev_err(&pdev->dev, "failed to request IRQ%u: %d\n", diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index f19bae475c96..0c1b7dde377c 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -305,27 +305,6 @@ static int dsi_mgr_connector_get_modes(struct drm_connector *connector) return num; } -static enum drm_mode_status dsi_mgr_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - int id = dsi_mgr_connector_get_id(connector); - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); - struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi); - struct msm_drm_private *priv = connector->dev->dev_private; - struct msm_kms *kms = priv->kms; - long actual, requested; - - DBG(""); - requested = 1000 * mode->clock; - actual = kms->funcs->round_pixclk(kms, requested, encoder); - - DBG("requested=%ld, actual=%ld", requested, actual); - if (actual != requested) - return MODE_CLOCK_RANGE; - - return MODE_OK; -} - static struct drm_encoder * dsi_mgr_connector_best_encoder(struct drm_connector *connector) { @@ -336,13 +315,12 @@ dsi_mgr_connector_best_encoder(struct drm_connector *connector) return msm_dsi_get_encoder(msm_dsi); } -static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) +static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge) { int id = dsi_mgr_bridge_get_id(bridge); struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); struct mipi_dsi_host *host = msm_dsi->host; - struct drm_panel *panel = msm_dsi->panel; struct msm_dsi_phy_shared_timings phy_shared_timings[DSI_MAX]; bool is_bonded_dsi = IS_BONDED_DSI(); int ret; @@ -383,6 +361,34 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) if (is_bonded_dsi && msm_dsi1) msm_dsi_host_enable_irq(msm_dsi1->host); + return; + +host1_on_fail: + msm_dsi_host_power_off(host); +host_on_fail: + dsi_mgr_phy_disable(id); +phy_en_fail: + return; +} + +static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) +{ + int id = dsi_mgr_bridge_get_id(bridge); + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); + struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); + struct mipi_dsi_host *host = msm_dsi->host; + struct drm_panel *panel = msm_dsi->panel; + bool is_bonded_dsi = IS_BONDED_DSI(); + int ret; + + DBG("id=%d", id); + if (!msm_dsi_device_connected(msm_dsi)) + return; + + /* Do nothing with the host if it is slave-DSI in case of bonded DSI */ + if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) + return; + /* Always call panel functions once, because even for dual panels, * there is only one drm_panel instance. */ @@ -417,17 +423,7 @@ host_en_fail: if (panel) drm_panel_unprepare(panel); panel_prep_fail: - msm_dsi_host_disable_irq(host); - if (is_bonded_dsi && msm_dsi1) - msm_dsi_host_disable_irq(msm_dsi1->host); - if (is_bonded_dsi && msm_dsi1) - msm_dsi_host_power_off(msm_dsi1->host); -host1_on_fail: - msm_dsi_host_power_off(host); -host_on_fail: - dsi_mgr_phy_disable(id); -phy_en_fail: return; } @@ -573,6 +569,8 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, msm_dsi_host_set_display_mode(host, adjusted_mode); if (is_bonded_dsi && other_dsi) msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode); + + dsi_mgr_bridge_power_on(bridge); } static const struct drm_connector_funcs dsi_mgr_connector_funcs = { @@ -586,7 +584,6 @@ static const struct drm_connector_funcs dsi_mgr_connector_funcs = { static const struct drm_connector_helper_funcs dsi_mgr_conn_helper_funcs = { .get_modes = dsi_mgr_connector_get_modes, - .mode_valid = dsi_mgr_connector_mode_valid, .best_encoder = dsi_mgr_connector_best_encoder, }; diff --git a/drivers/gpu/drm/msm/dsi/dsi_phy_10nm.xml.h b/drivers/gpu/drm/msm/dsi/dsi_phy_10nm.xml.h index 8872d77027dd..8b1be69ccf89 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_phy_10nm.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi_phy_10nm.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/dsi/dsi_phy_14nm.xml.h b/drivers/gpu/drm/msm/dsi/dsi_phy_14nm.xml.h index 0d9a5ccfb808..515f1fa605bf 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_phy_14nm.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi_phy_14nm.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/dsi/dsi_phy_20nm.xml.h b/drivers/gpu/drm/msm/dsi/dsi_phy_20nm.xml.h index 15c7a5852c7a..81e4622eb358 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_phy_20nm.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi_phy_20nm.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/dsi/dsi_phy_28nm.xml.h b/drivers/gpu/drm/msm/dsi/dsi_phy_28nm.xml.h index 5148f4d5b182..8c7db35c12c8 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_phy_28nm.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi_phy_28nm.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/dsi/dsi_phy_28nm_8960.xml.h b/drivers/gpu/drm/msm/dsi/dsi_phy_28nm_8960.xml.h index 446fe9ffc9c4..44eeca31a811 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_phy_28nm_8960.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi_phy_28nm_8960.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/dsi/dsi_phy_5nm.xml.h b/drivers/gpu/drm/msm/dsi/dsi_phy_5nm.xml.h deleted file mode 100644 index 404c890a29f1..000000000000 --- a/drivers/gpu/drm/msm/dsi/dsi_phy_5nm.xml.h +++ /dev/null @@ -1,480 +0,0 @@ -#ifndef DSI_PHY_5NM_XML -#define DSI_PHY_5NM_XML - -/* Autogenerated file, DO NOT EDIT manually! - -This file was generated by the rules-ng-ng headergen tool in this git repository: -http://github.com/freedreno/envytools/ -git clone https://github.com/freedreno/envytools.git - -The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) - -Copyright (C) 2013-2021 by the following authors: -- Rob Clark <[email protected]> (robclark) -- Ilia Mirkin <[email protected]> (imirkin) - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 REG_DSI_5nm_PHY_CMN_REVISION_ID0 0x00000000 - -#define REG_DSI_5nm_PHY_CMN_REVISION_ID1 0x00000004 - -#define REG_DSI_5nm_PHY_CMN_REVISION_ID2 0x00000008 - -#define REG_DSI_5nm_PHY_CMN_REVISION_ID3 0x0000000c - -#define REG_DSI_5nm_PHY_CMN_CLK_CFG0 0x00000010 - -#define REG_DSI_5nm_PHY_CMN_CLK_CFG1 0x00000014 - -#define REG_DSI_5nm_PHY_CMN_GLBL_CTRL 0x00000018 - -#define REG_DSI_5nm_PHY_CMN_RBUF_CTRL 0x0000001c - -#define REG_DSI_5nm_PHY_CMN_VREG_CTRL_0 0x00000020 - -#define REG_DSI_5nm_PHY_CMN_CTRL_0 0x00000024 - -#define REG_DSI_5nm_PHY_CMN_CTRL_1 0x00000028 - -#define REG_DSI_5nm_PHY_CMN_CTRL_2 0x0000002c - -#define REG_DSI_5nm_PHY_CMN_CTRL_3 0x00000030 - -#define REG_DSI_5nm_PHY_CMN_LANE_CFG0 0x00000034 - -#define REG_DSI_5nm_PHY_CMN_LANE_CFG1 0x00000038 - -#define REG_DSI_5nm_PHY_CMN_PLL_CNTRL 0x0000003c - -#define REG_DSI_5nm_PHY_CMN_DPHY_SOT 0x00000040 - -#define REG_DSI_5nm_PHY_CMN_LANE_CTRL0 0x000000a0 - -#define REG_DSI_5nm_PHY_CMN_LANE_CTRL1 0x000000a4 - -#define REG_DSI_5nm_PHY_CMN_LANE_CTRL2 0x000000a8 - -#define REG_DSI_5nm_PHY_CMN_LANE_CTRL3 0x000000ac - -#define REG_DSI_5nm_PHY_CMN_LANE_CTRL4 0x000000b0 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_0 0x000000b4 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_1 0x000000b8 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_2 0x000000bc - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_3 0x000000c0 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_4 0x000000c4 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_5 0x000000c8 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_6 0x000000cc - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_7 0x000000d0 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_8 0x000000d4 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_9 0x000000d8 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_10 0x000000dc - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_11 0x000000e0 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_12 0x000000e4 - -#define REG_DSI_5nm_PHY_CMN_TIMING_CTRL_13 0x000000e8 - -#define REG_DSI_5nm_PHY_CMN_GLBL_HSTX_STR_CTRL_0 0x000000ec - -#define REG_DSI_5nm_PHY_CMN_GLBL_HSTX_STR_CTRL_1 0x000000f0 - -#define REG_DSI_5nm_PHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL 0x000000f4 - -#define REG_DSI_5nm_PHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL 0x000000f8 - -#define REG_DSI_5nm_PHY_CMN_GLBL_RESCODE_OFFSET_MID_CTRL 0x000000fc - -#define REG_DSI_5nm_PHY_CMN_GLBL_LPTX_STR_CTRL 0x00000100 - -#define REG_DSI_5nm_PHY_CMN_GLBL_PEMPH_CTRL_0 0x00000104 - -#define REG_DSI_5nm_PHY_CMN_GLBL_PEMPH_CTRL_1 0x00000108 - -#define REG_DSI_5nm_PHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL 0x0000010c - -#define REG_DSI_5nm_PHY_CMN_VREG_CTRL_1 0x00000110 - -#define REG_DSI_5nm_PHY_CMN_CTRL_4 0x00000114 - -#define REG_DSI_5nm_PHY_CMN_PHY_STATUS 0x00000140 - -#define REG_DSI_5nm_PHY_CMN_LANE_STATUS0 0x00000148 - -#define REG_DSI_5nm_PHY_CMN_LANE_STATUS1 0x0000014c - -static inline uint32_t REG_DSI_5nm_PHY_LN(uint32_t i0) { return 0x00000000 + 0x80*i0; } - -static inline uint32_t REG_DSI_5nm_PHY_LN_CFG0(uint32_t i0) { return 0x00000000 + 0x80*i0; } - -static inline uint32_t REG_DSI_5nm_PHY_LN_CFG1(uint32_t i0) { return 0x00000004 + 0x80*i0; } - -static inline uint32_t REG_DSI_5nm_PHY_LN_CFG2(uint32_t i0) { return 0x00000008 + 0x80*i0; } - -static inline uint32_t REG_DSI_5nm_PHY_LN_TEST_DATAPATH(uint32_t i0) { return 0x0000000c + 0x80*i0; } - -static inline uint32_t REG_DSI_5nm_PHY_LN_PIN_SWAP(uint32_t i0) { return 0x00000010 + 0x80*i0; } - -static inline uint32_t REG_DSI_5nm_PHY_LN_LPRX_CTRL(uint32_t i0) { return 0x00000014 + 0x80*i0; } - -static inline uint32_t REG_DSI_5nm_PHY_LN_TX_DCTRL(uint32_t i0) { return 0x00000018 + 0x80*i0; } - -#define REG_DSI_5nm_PHY_PLL_ANALOG_CONTROLS_ONE 0x00000000 - -#define REG_DSI_5nm_PHY_PLL_ANALOG_CONTROLS_TWO 0x00000004 - -#define REG_DSI_5nm_PHY_PLL_INT_LOOP_SETTINGS 0x00000008 - -#define REG_DSI_5nm_PHY_PLL_INT_LOOP_SETTINGS_TWO 0x0000000c - -#define REG_DSI_5nm_PHY_PLL_ANALOG_CONTROLS_THREE 0x00000010 - -#define REG_DSI_5nm_PHY_PLL_ANALOG_CONTROLS_FOUR 0x00000014 - -#define REG_DSI_5nm_PHY_PLL_ANALOG_CONTROLS_FIVE 0x00000018 - -#define REG_DSI_5nm_PHY_PLL_INT_LOOP_CONTROLS 0x0000001c - -#define REG_DSI_5nm_PHY_PLL_DSM_DIVIDER 0x00000020 - -#define REG_DSI_5nm_PHY_PLL_FEEDBACK_DIVIDER 0x00000024 - -#define REG_DSI_5nm_PHY_PLL_SYSTEM_MUXES 0x00000028 - -#define REG_DSI_5nm_PHY_PLL_FREQ_UPDATE_CONTROL_OVERRIDES 0x0000002c - -#define REG_DSI_5nm_PHY_PLL_CMODE 0x00000030 - -#define REG_DSI_5nm_PHY_PLL_PSM_CTRL 0x00000034 - -#define REG_DSI_5nm_PHY_PLL_RSM_CTRL 0x00000038 - -#define REG_DSI_5nm_PHY_PLL_VCO_TUNE_MAP 0x0000003c - -#define REG_DSI_5nm_PHY_PLL_PLL_CNTRL 0x00000040 - -#define REG_DSI_5nm_PHY_PLL_CALIBRATION_SETTINGS 0x00000044 - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_CAL_TIMER_LOW 0x00000048 - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_CAL_TIMER_HIGH 0x0000004c - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_CAL_SETTINGS 0x00000050 - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_MIN 0x00000054 - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_MAX 0x00000058 - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_PFILT 0x0000005c - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_IFILT 0x00000060 - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_TWO 0x00000064 - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE 0x00000068 - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_FOUR 0x0000006c - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_ICODE_HIGH 0x00000070 - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_ICODE_LOW 0x00000074 - -#define REG_DSI_5nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE 0x00000078 - -#define REG_DSI_5nm_PHY_PLL_FREQ_DETECT_THRESH 0x0000007c - -#define REG_DSI_5nm_PHY_PLL_FREQ_DET_REFCLK_HIGH 0x00000080 - -#define REG_DSI_5nm_PHY_PLL_FREQ_DET_REFCLK_LOW 0x00000084 - -#define REG_DSI_5nm_PHY_PLL_FREQ_DET_PLLCLK_HIGH 0x00000088 - -#define REG_DSI_5nm_PHY_PLL_FREQ_DET_PLLCLK_LOW 0x0000008c - -#define REG_DSI_5nm_PHY_PLL_PFILT 0x00000090 - -#define REG_DSI_5nm_PHY_PLL_IFILT 0x00000094 - -#define REG_DSI_5nm_PHY_PLL_PLL_GAIN 0x00000098 - -#define REG_DSI_5nm_PHY_PLL_ICODE_LOW 0x0000009c - -#define REG_DSI_5nm_PHY_PLL_ICODE_HIGH 0x000000a0 - -#define REG_DSI_5nm_PHY_PLL_LOCKDET 0x000000a4 - -#define REG_DSI_5nm_PHY_PLL_OUTDIV 0x000000a8 - -#define REG_DSI_5nm_PHY_PLL_FASTLOCK_CONTROL 0x000000ac - -#define REG_DSI_5nm_PHY_PLL_PASS_OUT_OVERRIDE_ONE 0x000000b0 - -#define REG_DSI_5nm_PHY_PLL_PASS_OUT_OVERRIDE_TWO 0x000000b4 - -#define REG_DSI_5nm_PHY_PLL_CORE_OVERRIDE 0x000000b8 - -#define REG_DSI_5nm_PHY_PLL_CORE_INPUT_OVERRIDE 0x000000bc - -#define REG_DSI_5nm_PHY_PLL_RATE_CHANGE 0x000000c0 - -#define REG_DSI_5nm_PHY_PLL_PLL_DIGITAL_TIMERS 0x000000c4 - -#define REG_DSI_5nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO 0x000000c8 - -#define REG_DSI_5nm_PHY_PLL_DECIMAL_DIV_START 0x000000cc - -#define REG_DSI_5nm_PHY_PLL_FRAC_DIV_START_LOW 0x000000d0 - -#define REG_DSI_5nm_PHY_PLL_FRAC_DIV_START_MID 0x000000d4 - -#define REG_DSI_5nm_PHY_PLL_FRAC_DIV_START_HIGH 0x000000d8 - -#define REG_DSI_5nm_PHY_PLL_DEC_FRAC_MUXES 0x000000dc - -#define REG_DSI_5nm_PHY_PLL_DECIMAL_DIV_START_1 0x000000e0 - -#define REG_DSI_5nm_PHY_PLL_FRAC_DIV_START_LOW_1 0x000000e4 - -#define REG_DSI_5nm_PHY_PLL_FRAC_DIV_START_MID_1 0x000000e8 - -#define REG_DSI_5nm_PHY_PLL_FRAC_DIV_START_HIGH_1 0x000000ec - -#define REG_DSI_5nm_PHY_PLL_DECIMAL_DIV_START_2 0x000000f0 - -#define REG_DSI_5nm_PHY_PLL_FRAC_DIV_START_LOW_2 0x000000f4 - -#define REG_DSI_5nm_PHY_PLL_FRAC_DIV_START_MID_2 0x000000f8 - -#define REG_DSI_5nm_PHY_PLL_FRAC_DIV_START_HIGH_2 0x000000fc - -#define REG_DSI_5nm_PHY_PLL_MASH_CONTROL 0x00000100 - -#define REG_DSI_5nm_PHY_PLL_SSC_STEPSIZE_LOW 0x00000104 - -#define REG_DSI_5nm_PHY_PLL_SSC_STEPSIZE_HIGH 0x00000108 - -#define REG_DSI_5nm_PHY_PLL_SSC_DIV_PER_LOW 0x0000010c - -#define REG_DSI_5nm_PHY_PLL_SSC_DIV_PER_HIGH 0x00000110 - -#define REG_DSI_5nm_PHY_PLL_SSC_ADJPER_LOW 0x00000114 - -#define REG_DSI_5nm_PHY_PLL_SSC_ADJPER_HIGH 0x00000118 - -#define REG_DSI_5nm_PHY_PLL_SSC_MUX_CONTROL 0x0000011c - -#define REG_DSI_5nm_PHY_PLL_SSC_STEPSIZE_LOW_1 0x00000120 - -#define REG_DSI_5nm_PHY_PLL_SSC_STEPSIZE_HIGH_1 0x00000124 - -#define REG_DSI_5nm_PHY_PLL_SSC_DIV_PER_LOW_1 0x00000128 - -#define REG_DSI_5nm_PHY_PLL_SSC_DIV_PER_HIGH_1 0x0000012c - -#define REG_DSI_5nm_PHY_PLL_SSC_ADJPER_LOW_1 0x00000130 - -#define REG_DSI_5nm_PHY_PLL_SSC_ADJPER_HIGH_1 0x00000134 - -#define REG_DSI_5nm_PHY_PLL_SSC_STEPSIZE_LOW_2 0x00000138 - -#define REG_DSI_5nm_PHY_PLL_SSC_STEPSIZE_HIGH_2 0x0000013c - -#define REG_DSI_5nm_PHY_PLL_SSC_DIV_PER_LOW_2 0x00000140 - -#define REG_DSI_5nm_PHY_PLL_SSC_DIV_PER_HIGH_2 0x00000144 - -#define REG_DSI_5nm_PHY_PLL_SSC_ADJPER_LOW_2 0x00000148 - -#define REG_DSI_5nm_PHY_PLL_SSC_ADJPER_HIGH_2 0x0000014c - -#define REG_DSI_5nm_PHY_PLL_SSC_CONTROL 0x00000150 - -#define REG_DSI_5nm_PHY_PLL_PLL_OUTDIV_RATE 0x00000154 - -#define REG_DSI_5nm_PHY_PLL_PLL_LOCKDET_RATE_1 0x00000158 - -#define REG_DSI_5nm_PHY_PLL_PLL_LOCKDET_RATE_2 0x0000015c - -#define REG_DSI_5nm_PHY_PLL_PLL_PROP_GAIN_RATE_1 0x00000160 - -#define REG_DSI_5nm_PHY_PLL_PLL_PROP_GAIN_RATE_2 0x00000164 - -#define REG_DSI_5nm_PHY_PLL_PLL_BAND_SEL_RATE_1 0x00000168 - -#define REG_DSI_5nm_PHY_PLL_PLL_BAND_SEL_RATE_2 0x0000016c - -#define REG_DSI_5nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1 0x00000170 - -#define REG_DSI_5nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_2 0x00000174 - -#define REG_DSI_5nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1 0x00000178 - -#define REG_DSI_5nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_2 0x0000017c - -#define REG_DSI_5nm_PHY_PLL_PLL_FASTLOCK_EN_BAND 0x00000180 - -#define REG_DSI_5nm_PHY_PLL_FREQ_TUNE_ACCUM_INIT_MID 0x00000184 - -#define REG_DSI_5nm_PHY_PLL_FREQ_TUNE_ACCUM_INIT_HIGH 0x00000188 - -#define REG_DSI_5nm_PHY_PLL_FREQ_TUNE_ACCUM_INIT_MUX 0x0000018c - -#define REG_DSI_5nm_PHY_PLL_PLL_LOCK_OVERRIDE 0x00000190 - -#define REG_DSI_5nm_PHY_PLL_PLL_LOCK_DELAY 0x00000194 - -#define REG_DSI_5nm_PHY_PLL_PLL_LOCK_MIN_DELAY 0x00000198 - -#define REG_DSI_5nm_PHY_PLL_CLOCK_INVERTERS 0x0000019c - -#define REG_DSI_5nm_PHY_PLL_SPARE_AND_JPC_OVERRIDES 0x000001a0 - -#define REG_DSI_5nm_PHY_PLL_BIAS_CONTROL_1 0x000001a4 - -#define REG_DSI_5nm_PHY_PLL_BIAS_CONTROL_2 0x000001a8 - -#define REG_DSI_5nm_PHY_PLL_ALOG_OBSV_BUS_CTRL_1 0x000001ac - -#define REG_DSI_5nm_PHY_PLL_COMMON_STATUS_ONE 0x000001b0 - -#define REG_DSI_5nm_PHY_PLL_COMMON_STATUS_TWO 0x000001b4 - -#define REG_DSI_5nm_PHY_PLL_BAND_SEL_CAL 0x000001b8 - -#define REG_DSI_5nm_PHY_PLL_ICODE_ACCUM_STATUS_LOW 0x000001bc - -#define REG_DSI_5nm_PHY_PLL_ICODE_ACCUM_STATUS_HIGH 0x000001c0 - -#define REG_DSI_5nm_PHY_PLL_FD_OUT_LOW 0x000001c4 - -#define REG_DSI_5nm_PHY_PLL_FD_OUT_HIGH 0x000001c8 - -#define REG_DSI_5nm_PHY_PLL_ALOG_OBSV_BUS_STATUS_1 0x000001cc - -#define REG_DSI_5nm_PHY_PLL_PLL_MISC_CONFIG 0x000001d0 - -#define REG_DSI_5nm_PHY_PLL_FLL_CONFIG 0x000001d4 - -#define REG_DSI_5nm_PHY_PLL_FLL_FREQ_ACQ_TIME 0x000001d8 - -#define REG_DSI_5nm_PHY_PLL_FLL_CODE0 0x000001dc - -#define REG_DSI_5nm_PHY_PLL_FLL_CODE1 0x000001e0 - -#define REG_DSI_5nm_PHY_PLL_FLL_GAIN0 0x000001e4 - -#define REG_DSI_5nm_PHY_PLL_FLL_GAIN1 0x000001e8 - -#define REG_DSI_5nm_PHY_PLL_SW_RESET 0x000001ec - -#define REG_DSI_5nm_PHY_PLL_FAST_PWRUP 0x000001f0 - -#define REG_DSI_5nm_PHY_PLL_LOCKTIME0 0x000001f4 - -#define REG_DSI_5nm_PHY_PLL_LOCKTIME1 0x000001f8 - -#define REG_DSI_5nm_PHY_PLL_DEBUG_BUS_SEL 0x000001fc - -#define REG_DSI_5nm_PHY_PLL_DEBUG_BUS0 0x00000200 - -#define REG_DSI_5nm_PHY_PLL_DEBUG_BUS1 0x00000204 - -#define REG_DSI_5nm_PHY_PLL_DEBUG_BUS2 0x00000208 - -#define REG_DSI_5nm_PHY_PLL_DEBUG_BUS3 0x0000020c - -#define REG_DSI_5nm_PHY_PLL_ANALOG_FLL_CONTROL_OVERRIDES 0x00000210 - -#define REG_DSI_5nm_PHY_PLL_VCO_CONFIG 0x00000214 - -#define REG_DSI_5nm_PHY_PLL_VCO_CAL_CODE1_MODE0_STATUS 0x00000218 - -#define REG_DSI_5nm_PHY_PLL_VCO_CAL_CODE1_MODE1_STATUS 0x0000021c - -#define REG_DSI_5nm_PHY_PLL_RESET_SM_STATUS 0x00000220 - -#define REG_DSI_5nm_PHY_PLL_TDC_OFFSET 0x00000224 - -#define REG_DSI_5nm_PHY_PLL_PS3_PWRDOWN_CONTROLS 0x00000228 - -#define REG_DSI_5nm_PHY_PLL_PS4_PWRDOWN_CONTROLS 0x0000022c - -#define REG_DSI_5nm_PHY_PLL_PLL_RST_CONTROLS 0x00000230 - -#define REG_DSI_5nm_PHY_PLL_GEAR_BAND_SELECT_CONTROLS 0x00000234 - -#define REG_DSI_5nm_PHY_PLL_PSM_CLK_CONTROLS 0x00000238 - -#define REG_DSI_5nm_PHY_PLL_SYSTEM_MUXES_2 0x0000023c - -#define REG_DSI_5nm_PHY_PLL_VCO_CONFIG_1 0x00000240 - -#define REG_DSI_5nm_PHY_PLL_VCO_CONFIG_2 0x00000244 - -#define REG_DSI_5nm_PHY_PLL_CLOCK_INVERTERS_1 0x00000248 - -#define REG_DSI_5nm_PHY_PLL_CLOCK_INVERTERS_2 0x0000024c - -#define REG_DSI_5nm_PHY_PLL_CMODE_1 0x00000250 - -#define REG_DSI_5nm_PHY_PLL_CMODE_2 0x00000254 - -#define REG_DSI_5nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1 0x00000258 - -#define REG_DSI_5nm_PHY_PLL_ANALOG_CONTROLS_FIVE_2 0x0000025c - -#define REG_DSI_5nm_PHY_PLL_PERF_OPTIMIZE 0x00000260 - - -#endif /* DSI_PHY_5NM_XML */ diff --git a/drivers/gpu/drm/msm/dsi/dsi_phy_7nm.xml.h b/drivers/gpu/drm/msm/dsi/dsi_phy_7nm.xml.h index 782f6b332baf..5bc061797003 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_phy_7nm.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi_phy_7nm.xml.h @@ -8,27 +8,26 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) - -Copyright (C) 2013-2021 by the following authors: +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) + +Copyright (C) 2013-2022 by the following authors: - Rob Clark <[email protected]> (robclark) - Ilia Mirkin <[email protected]> (imirkin) @@ -156,6 +155,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define REG_DSI_7nm_PHY_CMN_LANE_STATUS1 0x0000014c +#define REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10 0x000001ac + static inline uint32_t REG_DSI_7nm_PHY_LN(uint32_t i0) { return 0x00000000 + 0x80*i0; } static inline uint32_t REG_DSI_7nm_PHY_LN_CFG0(uint32_t i0) { return 0x00000000 + 0x80*i0; } diff --git a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h index fbb6a7a6b940..03bc322d0487 100644 --- a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h +++ b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 2027b38617ab..a39de3bdc7fa 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -709,14 +709,14 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) if (!of_property_read_u32(dev->of_node, "phy-type", &phy_type)) phy->cphy_mode = (phy_type == PHY_TYPE_CPHY); - phy->base = msm_ioremap_size(pdev, "dsi_phy", "DSI_PHY", &phy->base_size); + phy->base = msm_ioremap_size(pdev, "dsi_phy", &phy->base_size); if (IS_ERR(phy->base)) { DRM_DEV_ERROR(dev, "%s: failed to map phy base\n", __func__); ret = -ENOMEM; goto fail; } - phy->pll_base = msm_ioremap_size(pdev, "dsi_pll", "DSI_PLL", &phy->pll_size); + phy->pll_base = msm_ioremap_size(pdev, "dsi_pll", &phy->pll_size); if (IS_ERR(phy->pll_base)) { DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); ret = -ENOMEM; @@ -724,7 +724,7 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) } if (phy->cfg->has_phy_lane) { - phy->lane_base = msm_ioremap_size(pdev, "dsi_phy_lane", "DSI_PHY_LANE", &phy->lane_size); + phy->lane_base = msm_ioremap_size(pdev, "dsi_phy_lane", &phy->lane_size); if (IS_ERR(phy->lane_base)) { DRM_DEV_ERROR(&pdev->dev, "%s: failed to map phy lane base\n", __func__); ret = -ENOMEM; @@ -733,7 +733,7 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) } if (phy->cfg->has_phy_regulator) { - phy->reg_base = msm_ioremap_size(pdev, "dsi_phy_regulator", "DSI_PHY_REG", &phy->reg_size); + phy->reg_base = msm_ioremap_size(pdev, "dsi_phy_regulator", &phy->reg_size); if (IS_ERR(phy->reg_base)) { DRM_DEV_ERROR(&pdev->dev, "%s: failed to map phy regulator base\n", __func__); ret = -ENOMEM; @@ -741,6 +741,12 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) } } + if (phy->cfg->ops.parse_dt_properties) { + ret = phy->cfg->ops.parse_dt_properties(phy); + if (ret) + goto fail; + } + ret = dsi_phy_regulator_init(phy); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 4c8257581bfc..dc91b43d5a38 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -25,6 +25,7 @@ struct msm_dsi_phy_ops { void (*save_pll_state)(struct msm_dsi_phy *phy); int (*restore_pll_state)(struct msm_dsi_phy *phy); bool (*set_continuous_clock)(struct msm_dsi_phy *phy, bool enable); + int (*parse_dt_properties)(struct msm_dsi_phy *phy); }; struct msm_dsi_phy_cfg { @@ -82,6 +83,8 @@ struct msm_dsi_dphy_timing { #define DSI_PIXEL_PLL_CLK 1 #define NUM_PROVIDED_CLKS 2 +#define DSI_LANE_MAX 5 + struct msm_dsi_phy { struct platform_device *pdev; void __iomem *base; @@ -99,6 +102,7 @@ struct msm_dsi_phy { struct msm_dsi_dphy_timing timing; const struct msm_dsi_phy_cfg *cfg; + void *tuning_cfg; enum msm_dsi_phy_usecase usecase; bool regulator_ldo_mode; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index d8128f50b0dd..08b015ea1b1e 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -83,6 +83,18 @@ struct dsi_pll_10nm { #define to_pll_10nm(x) container_of(x, struct dsi_pll_10nm, clk_hw) +/** + * struct dsi_phy_10nm_tuning_cfg - Holds 10nm PHY tuning config parameters. + * @rescode_offset_top: Offset for pull-up legs rescode. + * @rescode_offset_bot: Offset for pull-down legs rescode. + * @vreg_ctrl: vreg ctrl to drive LDO level + */ +struct dsi_phy_10nm_tuning_cfg { + u8 rescode_offset_top[DSI_LANE_MAX]; + u8 rescode_offset_bot[DSI_LANE_MAX]; + u8 vreg_ctrl; +}; + /* * Global list of private DSI PLL struct pointers. We need this for bonded DSI * mode, where the master PLL's clk_ops needs access the slave's private data @@ -562,7 +574,9 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov char clk_name[32], parent[32], vco_name[32]; char parent2[32], parent3[32], parent4[32]; struct clk_init_data vco_init = { - .parent_names = (const char *[]){ "xo" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "ref", + }, .num_parents = 1, .name = vco_name, .flags = CLK_IGNORE_UNUSED, @@ -747,6 +761,7 @@ static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy) int i; u8 tx_dctrl[] = { 0x00, 0x00, 0x00, 0x04, 0x01 }; void __iomem *lane_base = phy->lane_base; + struct dsi_phy_10nm_tuning_cfg *tuning_cfg = phy->tuning_cfg; if (phy->cfg->quirks & DSI_PHY_10NM_QUIRK_OLD_TIMINGS) tx_dctrl[3] = 0x02; @@ -775,10 +790,13 @@ static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy) dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG2(i), 0x0); dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG3(i), i == 4 ? 0x80 : 0x0); - dsi_phy_write(lane_base + - REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i), 0x0); - dsi_phy_write(lane_base + - REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i), 0x0); + + /* platform specific dsi phy drive strength adjustment */ + dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i), + tuning_cfg->rescode_offset_top[i]); + dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i), + tuning_cfg->rescode_offset_bot[i]); + dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(i), tx_dctrl[i]); } @@ -799,6 +817,7 @@ static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, u32 const timeout_us = 1000; struct msm_dsi_dphy_timing *timing = &phy->timing; void __iomem *base = phy->base; + struct dsi_phy_10nm_tuning_cfg *tuning_cfg = phy->tuning_cfg; u32 data; DBG(""); @@ -834,8 +853,9 @@ static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, /* Select MS1 byte-clk */ dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_GLBL_CTRL, 0x10); - /* Enable LDO */ - dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL, 0x59); + /* Enable LDO with platform specific drive level/amplitude adjustment */ + dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL, + tuning_cfg->vreg_ctrl); /* Configure PHY lane swap (TODO: we need to calculate this) */ dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CFG0, 0x21); @@ -922,6 +942,92 @@ static void dsi_10nm_phy_disable(struct msm_dsi_phy *phy) DBG("DSI%d PHY disabled", phy->id); } +static int dsi_10nm_phy_parse_dt(struct msm_dsi_phy *phy) +{ + struct device *dev = &phy->pdev->dev; + struct dsi_phy_10nm_tuning_cfg *tuning_cfg; + s8 offset_top[DSI_LANE_MAX] = { 0 }; /* No offset */ + s8 offset_bot[DSI_LANE_MAX] = { 0 }; /* No offset */ + u32 ldo_level = 400; /* 400mV */ + u8 level; + int ret, i; + + tuning_cfg = devm_kzalloc(dev, sizeof(*tuning_cfg), GFP_KERNEL); + if (!tuning_cfg) + return -ENOMEM; + + /* Drive strength adjustment parameters */ + ret = of_property_read_u8_array(dev->of_node, "qcom,phy-rescode-offset-top", + offset_top, DSI_LANE_MAX); + if (ret && ret != -EINVAL) { + DRM_DEV_ERROR(dev, "failed to parse qcom,phy-rescode-offset-top, %d\n", ret); + return ret; + } + + for (i = 0; i < DSI_LANE_MAX; i++) { + if (offset_top[i] < -32 || offset_top[i] > 31) { + DRM_DEV_ERROR(dev, + "qcom,phy-rescode-offset-top value %d is not in range [-32..31]\n", + offset_top[i]); + return -EINVAL; + } + tuning_cfg->rescode_offset_top[i] = 0x3f & offset_top[i]; + } + + ret = of_property_read_u8_array(dev->of_node, "qcom,phy-rescode-offset-bot", + offset_bot, DSI_LANE_MAX); + if (ret && ret != -EINVAL) { + DRM_DEV_ERROR(dev, "failed to parse qcom,phy-rescode-offset-bot, %d\n", ret); + return ret; + } + + for (i = 0; i < DSI_LANE_MAX; i++) { + if (offset_bot[i] < -32 || offset_bot[i] > 31) { + DRM_DEV_ERROR(dev, + "qcom,phy-rescode-offset-bot value %d is not in range [-32..31]\n", + offset_bot[i]); + return -EINVAL; + } + tuning_cfg->rescode_offset_bot[i] = 0x3f & offset_bot[i]; + } + + /* Drive level/amplitude adjustment parameters */ + ret = of_property_read_u32(dev->of_node, "qcom,phy-drive-ldo-level", &ldo_level); + if (ret && ret != -EINVAL) { + DRM_DEV_ERROR(dev, "failed to parse qcom,phy-drive-ldo-level, %d\n", ret); + return ret; + } + + switch (ldo_level) { + case 375: + level = 0; + break; + case 400: + level = 1; + break; + case 425: + level = 2; + break; + case 450: + level = 3; + break; + case 475: + level = 4; + break; + case 500: + level = 5; + break; + default: + DRM_DEV_ERROR(dev, "qcom,phy-drive-ldo-level %d is not supported\n", ldo_level); + return -EINVAL; + } + tuning_cfg->vreg_ctrl = 0x58 | (0x7 & level); + + phy->tuning_cfg = tuning_cfg; + + return 0; +} + const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = { .has_phy_lane = true, .reg_cfg = { @@ -936,6 +1042,7 @@ const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = { .pll_init = dsi_pll_10nm_init, .save_pll_state = dsi_10nm_pll_save_state, .restore_pll_state = dsi_10nm_pll_restore_state, + .parse_dt_properties = dsi_10nm_phy_parse_dt, }, .min_pll_rate = 1000000000UL, .max_pll_rate = 3500000000UL, @@ -957,6 +1064,7 @@ const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs = { .pll_init = dsi_pll_10nm_init, .save_pll_state = dsi_10nm_pll_save_state, .restore_pll_state = dsi_10nm_pll_restore_state, + .parse_dt_properties = dsi_10nm_phy_parse_dt, }, .min_pll_rate = 1000000000UL, .max_pll_rate = 3500000000UL, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 7414966f198e..75557ac99adf 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -802,7 +802,9 @@ static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **prov { char clk_name[32], parent[32], vco_name[32]; struct clk_init_data vco_init = { - .parent_names = (const char *[]){ "xo" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "ref", + }, .num_parents = 1, .name = vco_name, .flags = CLK_IGNORE_UNUSED, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index 2da673a2add6..48eab80b548e 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -521,7 +521,9 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov { char clk_name[32], parent1[32], parent2[32], vco_name[32]; struct clk_init_data vco_init = { - .parent_names = (const char *[]){ "xo" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "ref", .name = "xo", + }, .num_parents = 1, .name = vco_name, .flags = CLK_IGNORE_UNUSED, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index 71ed4aa0dc67..fc56cdcc9ad6 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -385,7 +385,9 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov { char *clk_name, *parent_name, *vco_name; struct clk_init_data vco_init = { - .parent_names = (const char *[]){ "pxo" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "ref", + }, .num_parents = 1, .flags = CLK_IGNORE_UNUSED, .ops = &clk_ops_dsi_pll_28nm_vco, 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 079613d2aaa9..6e506feb111f 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -588,7 +588,9 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide char clk_name[32], parent[32], vco_name[32]; char parent2[32], parent3[32], parent4[32]; struct clk_init_data vco_init = { - .parent_names = (const char *[]){ "bi_tcxo" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "ref", + }, .num_parents = 1, .name = vco_name, .flags = CLK_IGNORE_UNUSED, @@ -862,20 +864,26 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, /* Alter PHY configurations if data rate less than 1.5GHZ*/ less_than_1500_mhz = (clk_req->bitclk_rate <= 1500000000); - /* For C-PHY, no low power settings for lower clk rate */ - if (phy->cphy_mode) - less_than_1500_mhz = false; - if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) { vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52; - glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x00; - glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c; + if (phy->cphy_mode) { + glbl_rescode_top_ctrl = 0x00; + glbl_rescode_bot_ctrl = 0x3c; + } else { + glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x00; + glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c; + } glbl_str_swi_cal_sel_ctrl = 0x00; glbl_hstx_str_ctrl_0 = 0x88; } else { vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59; - glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00; - glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88; + if (phy->cphy_mode) { + glbl_str_swi_cal_sel_ctrl = 0x03; + glbl_hstx_str_ctrl_0 = 0x66; + } else { + glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00; + glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88; + } glbl_rescode_top_ctrl = 0x03; glbl_rescode_bot_ctrl = 0x3c; } diff --git a/drivers/gpu/drm/msm/dsi/sfpb.xml.h b/drivers/gpu/drm/msm/dsi/sfpb.xml.h index 1f5e9e9f9803..2ae711cbec36 100644 --- a/drivers/gpu/drm/msm/dsi/sfpb.xml.h +++ b/drivers/gpu/drm/msm/dsi/sfpb.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 719720709e9e..ec324352e862 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -133,7 +133,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) hdmi->config = config; spin_lock_init(&hdmi->reg_lock); - hdmi->mmio = msm_ioremap(pdev, config->mmio_name, "HDMI"); + hdmi->mmio = msm_ioremap(pdev, config->mmio_name); if (IS_ERR(hdmi->mmio)) { ret = PTR_ERR(hdmi->mmio); goto fail; @@ -144,8 +144,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) config->mmio_name); hdmi->mmio_phy_addr = res->start; - hdmi->qfprom_mmio = msm_ioremap(pdev, - config->qfprom_mmio_name, "HDMI_QFPROM"); + hdmi->qfprom_mmio = msm_ioremap(pdev, config->qfprom_mmio_name); if (IS_ERR(hdmi->qfprom_mmio)) { DRM_DEV_INFO(&pdev->dev, "can't find qfprom resource\n"); hdmi->qfprom_mmio = NULL; @@ -306,7 +305,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, } ret = devm_request_irq(&pdev->dev, hdmi->irq, - msm_hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + msm_hdmi_irq, IRQF_TRIGGER_HIGH, "hdmi_isr", hdmi); if (ret < 0) { DRM_DEV_ERROR(dev->dev, "failed to request IRQ%u: %d\n", diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h index a1cede6cfd02..c9eb26df67c0 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 68fba4bf7212..10ebe2089cb6 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -282,15 +282,18 @@ static enum drm_mode_status msm_hdmi_bridge_mode_valid(struct drm_bridge *bridge long actual, requested; requested = 1000 * mode->clock; - actual = kms->funcs->round_pixclk(kms, - requested, hdmi_bridge->hdmi->encoder); /* for mdp5/apq8074, we manage our own pixel clk (as opposed to * mdp4/dtv stuff where pixel clk is assigned to mdp/encoder * instead): */ - if (config->pwr_clk_cnt > 0) - actual = clk_round_rate(hdmi->pwr_clks[0], actual); + if (kms->funcs->round_pixclk) + actual = kms->funcs->round_pixclk(kms, + requested, hdmi_bridge->hdmi->encoder); + else if (config->pwr_clk_cnt > 0) + actual = clk_round_rate(hdmi->pwr_clks[0], requested); + else + actual = requested; DBG("requested=%ld, actual=%ld", requested, actual); diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c index 16b0e8836d27..9780107e1cc9 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -144,7 +144,7 @@ static int msm_hdmi_phy_probe(struct platform_device *pdev) if (!phy->cfg) return -ENODEV; - phy->mmio = msm_ioremap(pdev, "hdmi_phy", "HDMI_PHY"); + phy->mmio = msm_ioremap(pdev, "hdmi_phy"); if (IS_ERR(phy->mmio)) { DRM_DEV_ERROR(dev, "%s: failed to map phy base\n", __func__); return -ENOMEM; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c index 99c7853353fd..b06d9d25a189 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c @@ -716,19 +716,18 @@ int msm_hdmi_pll_8996_init(struct platform_device *pdev) pll->pdev = pdev; - pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll", "HDMI_PLL"); + pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll"); if (IS_ERR(pll->mmio_qserdes_com)) { DRM_DEV_ERROR(dev, "failed to map pll base\n"); return -ENOMEM; } for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { - char name[32], label[32]; + char name[32]; snprintf(name, sizeof(name), "hdmi_tx_l%d", i); - snprintf(label, sizeof(label), "HDMI_TX_L%d", i); - pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name, label); + pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name); if (IS_ERR(pll->mmio_qserdes_tx[i])) { DRM_DEV_ERROR(dev, "failed to map pll base\n"); return -ENOMEM; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c index 562dfac67792..be4b0b67e797 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c @@ -434,7 +434,7 @@ int msm_hdmi_pll_8960_init(struct platform_device *pdev) if (!pll) return -ENOMEM; - pll->mmio = msm_ioremap(pdev, "hdmi_pll", "HDMI_PLL"); + pll->mmio = msm_ioremap(pdev, "hdmi_pll"); if (IS_ERR(pll->mmio)) { DRM_DEV_ERROR(dev, "failed to map pll base\n"); return -ENOMEM; diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h index 4bf34cea1c89..3edc698c4df5 100644 --- a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h +++ b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h @@ -8,25 +8,24 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml ( 981 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml ( 15291 bytes, from 2021-06-15 22:36:13) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-06-05 21:37:42) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 10953 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_5nm.xml ( 10900 bytes, from 2021-05-21 19:18:08) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-02-18 16:45:44) -- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-02-18 16:45:44) +- /home/robclark/tmp/mesa/src/freedreno/registers/msm.xml ( 944 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2020-12-31 19:26:32) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp4.xml ( 20912 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp_common.xml ( 2849 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/mdp/mdp5.xml ( 37461 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi.xml ( 17560 bytes, from 2021-09-16 22:37:02) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml ( 3236 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml ( 4935 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml ( 7004 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml ( 3712 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml ( 5381 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml ( 4499 bytes, from 2021-07-22 15:21:56) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml ( 11007 bytes, from 2022-03-03 01:18:13) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/sfpb.xml ( 602 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/dsi/mmss_cc.xml ( 1686 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/qfprom.xml ( 600 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/hdmi/hdmi.xml ( 41874 bytes, from 2021-01-30 18:25:22) +- /home/robclark/tmp/mesa/src/freedreno/registers/edp/edp.xml ( 10416 bytes, from 2021-01-30 18:25:22) Copyright (C) 2013-2021 by the following authors: - Rob Clark <[email protected]> (robclark) diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 27c9ae563f2f..1686fbb611fd 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -5,7 +5,6 @@ */ #include <drm/drm_atomic_uapi.h> -#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_vblank.h> #include "msm_atomic_trace.h" @@ -13,20 +12,6 @@ #include "msm_gem.h" #include "msm_kms.h" -int msm_atomic_prepare_fb(struct drm_plane *plane, - struct drm_plane_state *new_state) -{ - struct msm_drm_private *priv = plane->dev->dev_private; - struct msm_kms *kms = priv->kms; - - if (!new_state->fb) - return 0; - - drm_gem_plane_helper_prepare_fb(plane, new_state); - - return msm_framebuffer_prepare(new_state->fb, kms->aspace); -} - /* * Helpers to control vblanks while we flush.. basically just to ensure * that vblank accounting is switched on, so we get valid seqn/timestamp diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 0804c31e8962..ea2a20699cb4 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -201,9 +201,9 @@ shrink_set(void *data, u64 val) return 0; } -DEFINE_SIMPLE_ATTRIBUTE(shrink_fops, - shrink_get, shrink_set, - "0x%08llx\n"); +DEFINE_DEBUGFS_ATTRIBUTE(shrink_fops, + shrink_get, shrink_set, + "0x%08llx\n"); static int msm_gem_show(struct seq_file *m, void *arg) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index ff19c5a94d6f..61c81af23ba7 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -41,9 +41,10 @@ * - 1.6.0 - Syncobj support * - 1.7.0 - Add MSM_PARAM_SUSPENDS to access suspend count * - 1.8.0 - Add MSM_BO_CACHED_COHERENT for supported GPUs (a6xx) + * - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN */ #define MSM_VERSION_MAJOR 1 -#define MSM_VERSION_MINOR 8 +#define MSM_VERSION_MINOR 9 #define MSM_VERSION_PATCHLEVEL 0 static const struct drm_mode_config_funcs mode_config_funcs = { @@ -57,14 +58,6 @@ static const struct drm_mode_config_helper_funcs mode_config_helper_funcs = { .atomic_commit_tail = msm_atomic_commit_tail, }; -#ifdef CONFIG_DRM_MSM_REGISTER_LOGGING -static bool reglog; -MODULE_PARM_DESC(reglog, "Enable register read/write logging"); -module_param(reglog, bool, 0600); -#else -#define reglog 0 -#endif - #ifdef CONFIG_DRM_FBDEV_EMULATION static bool fbdev = true; MODULE_PARM_DESC(fbdev, "Enable fbdev compat layer"); @@ -83,152 +76,6 @@ static bool modeset = true; MODULE_PARM_DESC(modeset, "Use kernel modesetting [KMS] (1=on (default), 0=disable)"); module_param(modeset, bool, 0600); -/* - * Util/helpers: - */ - -struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count, - const char *name) -{ - int i; - char n[32]; - - snprintf(n, sizeof(n), "%s_clk", name); - - for (i = 0; bulk && i < count; i++) { - if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n)) - return bulk[i].clk; - } - - - return NULL; -} - -struct clk *msm_clk_get(struct platform_device *pdev, const char *name) -{ - struct clk *clk; - char name2[32]; - - clk = devm_clk_get(&pdev->dev, name); - if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) - return clk; - - snprintf(name2, sizeof(name2), "%s_clk", name); - - clk = devm_clk_get(&pdev->dev, name2); - if (!IS_ERR(clk)) - dev_warn(&pdev->dev, "Using legacy clk name binding. Use " - "\"%s\" instead of \"%s\"\n", name, name2); - - return clk; -} - -static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name, - const char *dbgname, bool quiet, phys_addr_t *psize) -{ - struct resource *res; - unsigned long size; - void __iomem *ptr; - - if (name) - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); - else - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!res) { - if (!quiet) - DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name); - return ERR_PTR(-EINVAL); - } - - size = resource_size(res); - - ptr = devm_ioremap(&pdev->dev, res->start, size); - if (!ptr) { - if (!quiet) - DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name); - return ERR_PTR(-ENOMEM); - } - - if (reglog) - printk(KERN_DEBUG "IO:region %s %p %08lx\n", dbgname, ptr, size); - - if (psize) - *psize = size; - - return ptr; -} - -void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, - const char *dbgname) -{ - return _msm_ioremap(pdev, name, dbgname, false, NULL); -} - -void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name, - const char *dbgname) -{ - return _msm_ioremap(pdev, name, dbgname, true, NULL); -} - -void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name, - const char *dbgname, phys_addr_t *psize) -{ - return _msm_ioremap(pdev, name, dbgname, false, psize); -} - -void msm_writel(u32 data, void __iomem *addr) -{ - if (reglog) - printk(KERN_DEBUG "IO:W %p %08x\n", addr, data); - writel(data, addr); -} - -u32 msm_readl(const void __iomem *addr) -{ - u32 val = readl(addr); - if (reglog) - pr_err("IO:R %p %08x\n", addr, val); - return val; -} - -void msm_rmw(void __iomem *addr, u32 mask, u32 or) -{ - u32 val = msm_readl(addr); - - val &= ~mask; - msm_writel(val | or, addr); -} - -static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t) -{ - struct msm_hrtimer_work *work = container_of(t, - struct msm_hrtimer_work, timer); - - kthread_queue_work(work->worker, &work->work); - - return HRTIMER_NORESTART; -} - -void msm_hrtimer_queue_work(struct msm_hrtimer_work *work, - ktime_t wakeup_time, - enum hrtimer_mode mode) -{ - hrtimer_start(&work->timer, wakeup_time, mode); -} - -void msm_hrtimer_work_init(struct msm_hrtimer_work *work, - struct kthread_worker *worker, - kthread_work_func_t fn, - clockid_t clock_id, - enum hrtimer_mode mode) -{ - hrtimer_init(&work->timer, clock_id, mode); - work->timer.function = msm_hrtimer_worktimer; - work->worker = worker; - kthread_init_work(&work->work, fn); -} - static irqreturn_t msm_irq(int irq, void *arg) { struct drm_device *dev = arg; @@ -715,8 +562,16 @@ static void context_close(struct msm_file_private *ctx) static void msm_postclose(struct drm_device *dev, struct drm_file *file) { + struct msm_drm_private *priv = dev->dev_private; struct msm_file_private *ctx = file->driver_priv; + /* + * It is not possible to set sysprof param to non-zero if gpu + * is not initialized: + */ + if (priv->gpu) + msm_file_private_set_sysprof(ctx, priv->gpu, 0); + context_close(ctx); } @@ -766,7 +621,27 @@ static int msm_ioctl_get_param(struct drm_device *dev, void *data, if (!gpu) return -ENXIO; - return gpu->funcs->get_param(gpu, args->param, &args->value); + return gpu->funcs->get_param(gpu, file->driver_priv, + args->param, &args->value); +} + +static int msm_ioctl_set_param(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct msm_drm_private *priv = dev->dev_private; + struct drm_msm_param *args = data; + struct msm_gpu *gpu; + + if (args->pipe != MSM_PIPE_3D0) + return -EINVAL; + + gpu = priv->gpu; + + if (!gpu) + return -ENXIO; + + return gpu->funcs->set_param(gpu, file->driver_priv, + args->param, args->value); } static int msm_ioctl_gem_new(struct drm_device *dev, void *data, @@ -1054,6 +929,7 @@ static int msm_ioctl_submitqueue_close(struct drm_device *dev, void *data, static const struct drm_ioctl_desc msm_ioctls[] = { DRM_IOCTL_DEF_DRV(MSM_GET_PARAM, msm_ioctl_get_param, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(MSM_SET_PARAM, msm_ioctl_set_param, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(MSM_GEM_NEW, msm_ioctl_gem_new, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(MSM_GEM_INFO, msm_ioctl_gem_info, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_RENDER_ALLOW), @@ -1438,9 +1314,12 @@ static void msm_pdev_shutdown(struct platform_device *pdev) static const struct of_device_id dt_match[] = { { .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 }, { .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 }, + { .compatible = "qcom,msm8998-mdss", .data = (void *)KMS_DPU }, + { .compatible = "qcom,qcm2290-mdss", .data = (void *)KMS_DPU }, { .compatible = "qcom,sdm845-mdss", .data = (void *)KMS_DPU }, { .compatible = "qcom,sc7180-mdss", .data = (void *)KMS_DPU }, { .compatible = "qcom,sc7280-mdss", .data = (void *)KMS_DPU }, + { .compatible = "qcom,sc8180x-mdss", .data = (void *)KMS_DPU }, { .compatible = "qcom,sm8150-mdss", .data = (void *)KMS_DPU }, { .compatible = "qcom,sm8250-mdss", .data = (void *)KMS_DPU }, {} diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index ae52412d529a..d661debb50f1 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -109,24 +109,6 @@ struct msm_display_topology { u32 num_dspp; }; -/** - * struct msm_display_info - defines display properties - * @intf_type: DRM_MODE_ENCODER_ type - * @capabilities: Bitmask of display flags - * @num_of_h_tiles: Number of horizontal tiles in case of split interface - * @h_tile_instance: Controller instance used per tile. Number of elements is - * based on num_of_h_tiles - * @is_te_using_watchdog_timer: Boolean to indicate watchdog TE is - * used instead of panel TE in cmd mode panels - */ -struct msm_display_info { - int intf_type; - uint32_t capabilities; - uint32_t num_of_h_tiles; - uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY]; - bool is_te_using_watchdog_timer; -}; - /* Commit/Event thread specific structure */ struct msm_drm_thread { struct drm_device *dev; @@ -257,8 +239,6 @@ struct msm_format { struct msm_pending_timer; -int msm_atomic_prepare_fb(struct drm_plane *plane, - struct drm_plane_state *new_state); int msm_atomic_init_pending_timer(struct msm_pending_timer *timer, struct msm_kms *kms, int crtc_idx); void msm_atomic_destroy_pending_timer(struct msm_pending_timer *timer); @@ -317,9 +297,9 @@ int msm_gem_prime_pin(struct drm_gem_object *obj); void msm_gem_prime_unpin(struct drm_gem_object *obj); int msm_framebuffer_prepare(struct drm_framebuffer *fb, - struct msm_gem_address_space *aspace); + struct msm_gem_address_space *aspace, bool needs_dirtyfb); void msm_framebuffer_cleanup(struct drm_framebuffer *fb, - struct msm_gem_address_space *aspace); + struct msm_gem_address_space *aspace, bool needed_dirtyfb); uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, struct msm_gem_address_space *aspace, int plane); struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane); @@ -480,15 +460,21 @@ struct clk *msm_clk_get(struct platform_device *pdev, const char *name); struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count, const char *name); -void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, - const char *dbgname); +void __iomem *msm_ioremap(struct platform_device *pdev, const char *name); void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name, - const char *dbgname, phys_addr_t *size); -void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name, - const char *dbgname); -void msm_writel(u32 data, void __iomem *addr); -u32 msm_readl(const void __iomem *addr); -void msm_rmw(void __iomem *addr, u32 mask, u32 or); + phys_addr_t *size); +void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name); + +#define msm_writel(data, addr) writel((data), (addr)) +#define msm_readl(addr) readl((addr)) + +static inline void msm_rmw(void __iomem *addr, u32 mask, u32 or) +{ + u32 val = msm_readl(addr); + + val &= ~mask; + msm_writel(val | or, addr); +} /** * struct msm_hrtimer_work - a helper to combine an hrtimer with kthread_work diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index 4d34df5354e0..7137492fe78e 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -18,16 +18,36 @@ struct msm_framebuffer { struct drm_framebuffer base; const struct msm_format *format; + + /* Count of # of attached planes which need dirtyfb: */ + refcount_t dirtyfb; }; #define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base) static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos); +static int msm_framebuffer_dirtyfb(struct drm_framebuffer *fb, + struct drm_file *file_priv, unsigned int flags, + unsigned int color, struct drm_clip_rect *clips, + unsigned int num_clips) +{ + struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); + + /* If this fb is not used on any display requiring pixel data to be + * flushed, then skip dirtyfb + */ + if (refcount_read(&msm_fb->dirtyfb) == 1) + return 0; + + return drm_atomic_helper_dirtyfb(fb, file_priv, flags, color, + clips, num_clips); +} + static const struct drm_framebuffer_funcs msm_framebuffer_funcs = { .create_handle = drm_gem_fb_create_handle, .destroy = drm_gem_fb_destroy, - .dirty = drm_atomic_helper_dirtyfb, + .dirty = msm_framebuffer_dirtyfb, }; #ifdef CONFIG_DEBUG_FS @@ -48,17 +68,19 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m) } #endif -/* prepare/pin all the fb's bo's for scanout. Note that it is not valid - * to prepare an fb more multiple different initiator 'id's. But that - * should be fine, since only the scanout (mdpN) side of things needs - * this, the gpu doesn't care about fb's. +/* prepare/pin all the fb's bo's for scanout. */ int msm_framebuffer_prepare(struct drm_framebuffer *fb, - struct msm_gem_address_space *aspace) + struct msm_gem_address_space *aspace, + bool needs_dirtyfb) { + struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); int ret, i, n = fb->format->num_planes; uint64_t iova; + if (needs_dirtyfb) + refcount_inc(&msm_fb->dirtyfb); + for (i = 0; i < n; i++) { ret = msm_gem_get_and_pin_iova(fb->obj[i], aspace, &iova); drm_dbg_state(fb->dev, "FB[%u]: iova[%d]: %08llx (%d)", fb->base.id, i, iova, ret); @@ -70,10 +92,15 @@ int msm_framebuffer_prepare(struct drm_framebuffer *fb, } void msm_framebuffer_cleanup(struct drm_framebuffer *fb, - struct msm_gem_address_space *aspace) + struct msm_gem_address_space *aspace, + bool needed_dirtyfb) { + struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); int i, n = fb->format->num_planes; + if (needed_dirtyfb) + refcount_dec(&msm_fb->dirtyfb); + for (i = 0; i < n; i++) msm_gem_unpin_iova(fb->obj[i], aspace); } @@ -194,6 +221,8 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, goto fail; } + refcount_set(&msm_fb->dirtyfb, 1); + drm_dbg_state(dev, "create: FB ID: %d (%p)", fb->base.id, fb); return fb; diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 54ca0817d807..af612add5264 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -35,6 +35,9 @@ struct msm_gem_address_space { * will be non-NULL: */ struct pid *pid; + + /* @faults: the number of GPU hangs associated with this address space */ + int faults; }; struct msm_gem_vma { diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 6cfa984dee6a..c6d60c8d286d 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -872,16 +872,46 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, submit->nr_cmds = i; + /* + * If using userspace provided seqno fence, validate that the id + * is available before arming sched job. Since access to fence_idr + * is serialized on the queue lock, the slot should be still avail + * after the job is armed + */ + if ((args->flags & MSM_SUBMIT_FENCE_SN_IN) && + idr_find(&queue->fence_idr, args->fence)) { + ret = -EINVAL; + goto out; + } + drm_sched_job_arm(&submit->base); submit->user_fence = dma_fence_get(&submit->base.s_fence->finished); - /* - * Allocate an id which can be used by WAIT_FENCE ioctl to map back - * to the underlying fence. - */ - submit->fence_id = idr_alloc_cyclic(&queue->fence_idr, - submit->user_fence, 1, INT_MAX, GFP_KERNEL); + if (args->flags & MSM_SUBMIT_FENCE_SN_IN) { + /* + * Userspace has assigned the seqno fence that it wants + * us to use. It is an error to pick a fence sequence + * number that is not available. + */ + submit->fence_id = args->fence; + ret = idr_alloc_u32(&queue->fence_idr, submit->user_fence, + &submit->fence_id, submit->fence_id, + GFP_KERNEL); + /* + * We've already validated that the fence_id slot is valid, + * so if idr_alloc_u32 failed, it is a kernel bug + */ + WARN_ON(ret); + } else { + /* + * Allocate an id which can be used by WAIT_FENCE ioctl to map + * back to the underlying fence. + */ + submit->fence_id = idr_alloc_cyclic(&queue->fence_idr, + submit->user_fence, 1, + INT_MAX, GFP_KERNEL); + } if (submit->fence_id < 0) { ret = submit->fence_id = 0; submit->fence_id = 0; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 2c1049c0ea14..faf0c242874e 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -370,8 +370,8 @@ static void recover_worker(struct kthread_work *work) struct task_struct *task; /* Increment the fault counts */ - gpu->global_faults++; submit->queue->faults++; + submit->aspace->faults++; task = get_pid_task(submit->pid, PIDTYPE_PID); if (task) { @@ -389,6 +389,12 @@ static void recover_worker(struct kthread_work *work) } else { msm_rd_dump_submit(priv->hangrd, submit, NULL); } + } else { + /* + * We couldn't attribute this fault to any particular context, + * so increment the global fault count instead. + */ + gpu->global_faults++; } /* Record the crash state */ @@ -838,7 +844,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, gpu->funcs = funcs; gpu->name = name; - gpu->worker = kthread_create_worker(0, "%s-worker", gpu->name); + gpu->worker = kthread_create_worker(0, "gpu-worker"); if (IS_ERR(gpu->worker)) { ret = PTR_ERR(gpu->worker); gpu->worker = NULL; @@ -861,7 +867,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, /* Map registers: */ - gpu->mmio = msm_ioremap(pdev, config->ioname, name); + gpu->mmio = msm_ioremap(pdev, config->ioname); if (IS_ERR(gpu->mmio)) { ret = PTR_ERR(gpu->mmio); goto fail; @@ -876,7 +882,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, } ret = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, - IRQF_TRIGGER_HIGH, gpu->name, gpu); + IRQF_TRIGGER_HIGH, "gpu-irq", gpu); if (ret) { DRM_DEV_ERROR(drm->dev, "failed to request IRQ%u: %d\n", gpu->irq, ret); goto fail; @@ -953,6 +959,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, gpu->nr_rings = nr_rings; + refcount_set(&gpu->sysprof_active, 1); + return 0; fail: diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 92aa1e9196c6..02419f2ca2bc 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -42,7 +42,10 @@ struct msm_gpu_config { * + z180_gpu */ struct msm_gpu_funcs { - int (*get_param)(struct msm_gpu *gpu, uint32_t param, uint64_t *value); + int (*get_param)(struct msm_gpu *gpu, struct msm_file_private *ctx, + uint32_t param, uint64_t *value); + int (*set_param)(struct msm_gpu *gpu, struct msm_file_private *ctx, + uint32_t param, uint64_t value); int (*hw_init)(struct msm_gpu *gpu); int (*pm_suspend)(struct msm_gpu *gpu); int (*pm_resume)(struct msm_gpu *gpu); @@ -157,6 +160,13 @@ struct msm_gpu { int nr_rings; /** + * sysprof_active: + * + * The count of contexts that have enabled system profiling. + */ + refcount_t sysprof_active; + + /** * cur_ctx_seqno: * * The ctx->seqno value of the last context to submit rendering, @@ -199,7 +209,10 @@ struct msm_gpu { /* does gpu need hw_init? */ bool needs_hw_init; - /* number of GPU hangs (for all contexts) */ + /** + * global_faults: number of GPU hangs not attributed to a particular + * address space + */ int global_faults; void __iomem *mmio; @@ -324,6 +337,24 @@ struct msm_file_private { int seqno; /** + * sysprof: + * + * The value of MSM_PARAM_SYSPROF set by userspace. This is + * intended to be used by system profiling tools like Mesa's + * pps-producer (perfetto), and restricted to CAP_SYS_ADMIN. + * + * Setting a value of 1 will preserve performance counters across + * context switches. Setting a value of 2 will in addition + * suppress suspend. (Performance counters lose state across + * power collapse, which is undesirable for profiling in some + * cases.) + * + * The value automatically reverts to zero when the drm device + * file is closed. + */ + int sysprof; + + /** * entities: * * Table of per-priority-level sched entities used by submitqueues @@ -519,6 +550,8 @@ void msm_submitqueue_close(struct msm_file_private *ctx); void msm_submitqueue_destroy(struct kref *kref); +int msm_file_private_set_sysprof(struct msm_file_private *ctx, + struct msm_gpu *gpu, int sysprof); void __msm_file_private_destroy(struct kref *kref); static inline void msm_file_private_put(struct msm_file_private *ctx) diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 9bf319be11f6..12641616acd3 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -83,6 +83,12 @@ static struct devfreq_dev_profile msm_devfreq_profile = { static void msm_devfreq_boost_work(struct kthread_work *work); static void msm_devfreq_idle_work(struct kthread_work *work); +static bool has_devfreq(struct msm_gpu *gpu) +{ + struct msm_gpu_devfreq *df = &gpu->devfreq; + return !!df->devfreq; +} + void msm_devfreq_init(struct msm_gpu *gpu) { struct msm_gpu_devfreq *df = &gpu->devfreq; @@ -149,6 +155,9 @@ void msm_devfreq_cleanup(struct msm_gpu *gpu) { struct msm_gpu_devfreq *df = &gpu->devfreq; + if (!has_devfreq(gpu)) + return; + devfreq_cooling_unregister(gpu->cooling); dev_pm_qos_remove_request(&df->boost_freq); dev_pm_qos_remove_request(&df->idle_freq); @@ -156,16 +165,24 @@ void msm_devfreq_cleanup(struct msm_gpu *gpu) void msm_devfreq_resume(struct msm_gpu *gpu) { - gpu->devfreq.busy_cycles = 0; - gpu->devfreq.time = ktime_get(); + struct msm_gpu_devfreq *df = &gpu->devfreq; - devfreq_resume_device(gpu->devfreq.devfreq); + if (!has_devfreq(gpu)) + return; + + df->busy_cycles = 0; + df->time = ktime_get(); + + devfreq_resume_device(df->devfreq); } void msm_devfreq_suspend(struct msm_gpu *gpu) { struct msm_gpu_devfreq *df = &gpu->devfreq; + if (!has_devfreq(gpu)) + return; + devfreq_suspend_device(df->devfreq); cancel_idle_work(df); @@ -185,6 +202,9 @@ void msm_devfreq_boost(struct msm_gpu *gpu, unsigned factor) struct msm_gpu_devfreq *df = &gpu->devfreq; uint64_t freq; + if (!has_devfreq(gpu)) + return; + freq = get_freq(gpu); freq *= factor; @@ -207,7 +227,7 @@ void msm_devfreq_active(struct msm_gpu *gpu) struct devfreq_dev_status status; unsigned int idle_time; - if (!df->devfreq) + if (!has_devfreq(gpu)) return; /* @@ -253,7 +273,7 @@ void msm_devfreq_idle(struct msm_gpu *gpu) { struct msm_gpu_devfreq *df = &gpu->devfreq; - if (!df->devfreq) + if (!has_devfreq(gpu)) return; msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1), diff --git a/drivers/gpu/drm/msm/msm_io_utils.c b/drivers/gpu/drm/msm/msm_io_utils.c new file mode 100644 index 000000000000..7b504617833a --- /dev/null +++ b/drivers/gpu/drm/msm/msm_io_utils.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016-2018, 2020-2021 The Linux Foundation. All rights reserved. + * Copyright (C) 2013 Red Hat + * Author: Rob Clark <[email protected]> + */ + +#include "msm_drv.h" + +/* + * Util/helpers: + */ + +struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count, + const char *name) +{ + int i; + char n[32]; + + snprintf(n, sizeof(n), "%s_clk", name); + + for (i = 0; bulk && i < count; i++) { + if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n)) + return bulk[i].clk; + } + + + return NULL; +} + +struct clk *msm_clk_get(struct platform_device *pdev, const char *name) +{ + struct clk *clk; + char name2[32]; + + clk = devm_clk_get(&pdev->dev, name); + if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER) + return clk; + + snprintf(name2, sizeof(name2), "%s_clk", name); + + clk = devm_clk_get(&pdev->dev, name2); + if (!IS_ERR(clk)) + dev_warn(&pdev->dev, "Using legacy clk name binding. Use " + "\"%s\" instead of \"%s\"\n", name, name2); + + return clk; +} + +static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name, + bool quiet, phys_addr_t *psize) +{ + struct resource *res; + unsigned long size; + void __iomem *ptr; + + if (name) + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + else + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (!res) { + if (!quiet) + DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name); + return ERR_PTR(-EINVAL); + } + + size = resource_size(res); + + ptr = devm_ioremap(&pdev->dev, res->start, size); + if (!ptr) { + if (!quiet) + DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name); + return ERR_PTR(-ENOMEM); + } + + if (psize) + *psize = size; + + return ptr; +} + +void __iomem *msm_ioremap(struct platform_device *pdev, const char *name) +{ + return _msm_ioremap(pdev, name, false, NULL); +} + +void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name) +{ + return _msm_ioremap(pdev, name, true, NULL); +} + +void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name, + phys_addr_t *psize) +{ + return _msm_ioremap(pdev, name, false, psize); +} + +static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t) +{ + struct msm_hrtimer_work *work = container_of(t, + struct msm_hrtimer_work, timer); + + kthread_queue_work(work->worker, &work->work); + + return HRTIMER_NORESTART; +} + +void msm_hrtimer_queue_work(struct msm_hrtimer_work *work, + ktime_t wakeup_time, + enum hrtimer_mode mode) +{ + hrtimer_start(&work->timer, wakeup_time, mode); +} + +void msm_hrtimer_work_init(struct msm_hrtimer_work *work, + struct kthread_worker *worker, + kthread_work_func_t fn, + clockid_t clock_id, + enum hrtimer_mode mode) +{ + hrtimer_init(&work->timer, clock_id, mode); + work->timer.function = msm_hrtimer_worktimer; + work->worker = worker; + kthread_init_work(&work->work, fn); +} diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index 81432ec07012..9d835331f214 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -62,6 +62,7 @@ enum rd_sect_type { RD_FRAG_SHADER, RD_BUFFER_CONTENTS, RD_GPU_ID, + RD_CHIP_ID, }; #define BUF_SZ 512 /* should be power of 2 */ @@ -196,12 +197,17 @@ static int rd_open(struct inode *inode, struct file *file) /* the parsing tools need to know gpu-id to know which * register database to load. + * + * Note: These particular params do not require a context */ - gpu->funcs->get_param(gpu, MSM_PARAM_GPU_ID, &val); + gpu->funcs->get_param(gpu, NULL, MSM_PARAM_GPU_ID, &val); gpu_id = val; rd_write_section(rd, RD_GPU_ID, &gpu_id, sizeof(gpu_id)); + gpu->funcs->get_param(gpu, NULL, MSM_PARAM_CHIP_ID, &val); + rd_write_section(rd, RD_CHIP_ID, &val, sizeof(val)); + out: mutex_unlock(&gpu->lock); return ret; diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c index 7cb158bcbcf6..79b6ccd6ce64 100644 --- a/drivers/gpu/drm/msm/msm_submitqueue.c +++ b/drivers/gpu/drm/msm/msm_submitqueue.c @@ -7,6 +7,45 @@ #include "msm_gpu.h" +int msm_file_private_set_sysprof(struct msm_file_private *ctx, + struct msm_gpu *gpu, int sysprof) +{ + /* + * Since pm_runtime and sysprof_active are both refcounts, we + * call apply the new value first, and then unwind the previous + * value + */ + + switch (sysprof) { + default: + return -EINVAL; + case 2: + pm_runtime_get_sync(&gpu->pdev->dev); + fallthrough; + case 1: + refcount_inc(&gpu->sysprof_active); + fallthrough; + case 0: + break; + } + + /* unwind old value: */ + switch (ctx->sysprof) { + case 2: + pm_runtime_put_autosuspend(&gpu->pdev->dev); + fallthrough; + case 1: + refcount_dec(&gpu->sysprof_active); + fallthrough; + case 0: + break; + } + + ctx->sysprof = sysprof; + + return 0; +} + void __msm_file_private_destroy(struct kref *kref) { struct msm_file_private *ctx = container_of(kref, diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 133c8736426a..0c1a2ea0ed04 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -635,8 +635,6 @@ nv50_wndw_reset(struct drm_plane *plane) plane->funcs->atomic_destroy_state(plane, plane->state); __drm_atomic_helper_plane_reset(plane, &asyw->state); - plane->state->zpos = nv50_wndw_zpos_default(plane); - plane->state->normalized_zpos = nv50_wndw_zpos_default(plane); } static void diff --git a/drivers/gpu/drm/nouveau/include/nvif/list.h b/drivers/gpu/drm/nouveau/include/nvif/list.h deleted file mode 100644 index 8af5d144ecb0..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvif/list.h +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * Copyright © 2010 Francisco Jerez <[email protected]> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -/* Modified by Ben Skeggs <[email protected]> to match kernel list APIs */ - -#ifndef _XORG_LIST_H_ -#define _XORG_LIST_H_ - -/** - * @file Classic doubly-link circular list implementation. - * For real usage examples of the linked list, see the file test/list.c - * - * Example: - * We need to keep a list of struct foo in the parent struct bar, i.e. what - * we want is something like this. - * - * struct bar { - * ... - * struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{} - * ... - * } - * - * We need one list head in bar and a list element in all list_of_foos (both are of - * data type 'struct list_head'). - * - * struct bar { - * ... - * struct list_head list_of_foos; - * ... - * } - * - * struct foo { - * ... - * struct list_head entry; - * ... - * } - * - * Now we initialize the list head: - * - * struct bar bar; - * ... - * INIT_LIST_HEAD(&bar.list_of_foos); - * - * Then we create the first element and add it to this list: - * - * struct foo *foo = malloc(...); - * .... - * list_add(&foo->entry, &bar.list_of_foos); - * - * Repeat the above for each element you want to add to the list. Deleting - * works with the element itself. - * list_del(&foo->entry); - * free(foo); - * - * Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty - * list again. - * - * Looping through the list requires a 'struct foo' as iterator and the - * name of the field the subnodes use. - * - * struct foo *iterator; - * list_for_each_entry(iterator, &bar.list_of_foos, entry) { - * if (iterator->something == ...) - * ... - * } - * - * Note: You must not call list_del() on the iterator if you continue the - * loop. You need to run the safe for-each loop instead: - * - * struct foo *iterator, *next; - * list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) { - * if (...) - * list_del(&iterator->entry); - * } - * - */ - -/** - * The linkage struct for list nodes. This struct must be part of your - * to-be-linked struct. struct list_head is required for both the head of the - * list and for each list node. - * - * Position and name of the struct list_head field is irrelevant. - * There are no requirements that elements of a list are of the same type. - * There are no requirements for a list head, any struct list_head can be a list - * head. - */ -struct list_head { - struct list_head *next, *prev; -}; - -/** - * Initialize the list as an empty list. - * - * Example: - * INIT_LIST_HEAD(&bar->list_of_foos); - * - * @param The list to initialized. - */ -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -static inline void -INIT_LIST_HEAD(struct list_head *list) -{ - list->next = list->prev = list; -} - -static inline void -__list_add(struct list_head *entry, - struct list_head *prev, struct list_head *next) -{ - next->prev = entry; - entry->next = next; - entry->prev = prev; - prev->next = entry; -} - -/** - * Insert a new element after the given list head. The new element does not - * need to be initialised as empty list. - * The list changes from: - * head → some element → ... - * to - * head → new element → older element → ... - * - * Example: - * struct foo *newfoo = malloc(...); - * list_add(&newfoo->entry, &bar->list_of_foos); - * - * @param entry The new element to prepend to the list. - * @param head The existing list. - */ -static inline void -list_add(struct list_head *entry, struct list_head *head) -{ - __list_add(entry, head, head->next); -} - -/** - * Append a new element to the end of the list given with this list head. - * - * The list changes from: - * head → some element → ... → lastelement - * to - * head → some element → ... → lastelement → new element - * - * Example: - * struct foo *newfoo = malloc(...); - * list_add_tail(&newfoo->entry, &bar->list_of_foos); - * - * @param entry The new element to prepend to the list. - * @param head The existing list. - */ -static inline void -list_add_tail(struct list_head *entry, struct list_head *head) -{ - __list_add(entry, head->prev, head); -} - -static inline void -__list_del(struct list_head *prev, struct list_head *next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * Remove the element from the list it is in. Using this function will reset - * the pointers to/from this element so it is removed from the list. It does - * NOT free the element itself or manipulate it otherwise. - * - * Using list_del on a pure list head (like in the example at the top of - * this file) will NOT remove the first element from - * the list but rather reset the list as empty list. - * - * Example: - * list_del(&foo->entry); - * - * @param entry The element to remove. - */ -static inline void -list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); -} - -static inline void -list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * Check if the list is empty. - * - * Example: - * list_empty(&bar->list_of_foos); - * - * @return True if the list contains one or more elements or False otherwise. - */ -static inline bool -list_empty(struct list_head *head) -{ - return head->next == head; -} - -/** - * Returns a pointer to the container of this list element. - * - * Example: - * struct foo* f; - * f = container_of(&foo->entry, struct foo, entry); - * assert(f == foo); - * - * @param ptr Pointer to the struct list_head. - * @param type Data type of the list element. - * @param member Member name of the struct list_head field in the list element. - * @return A pointer to the data struct containing the list head. - */ -#ifndef container_of -#define container_of(ptr, type, member) \ - (type *)((char *)(ptr) - (char *) &((type *)0)->member) -#endif - -/** - * Alias of container_of - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * Retrieve the first list entry for the given list pointer. - * - * Example: - * struct foo *first; - * first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos); - * - * @param ptr The list head - * @param type Data type of the list element to retrieve - * @param member Member name of the struct list_head field in the list element. - * @return A pointer to the first list element. - */ -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -/** - * Retrieve the last list entry for the given listpointer. - * - * Example: - * struct foo *first; - * first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos); - * - * @param ptr The list head - * @param type Data type of the list element to retrieve - * @param member Member name of the struct list_head field in the list element. - * @return A pointer to the last list element. - */ -#define list_last_entry(ptr, type, member) \ - list_entry((ptr)->prev, type, member) - -#define __container_of(ptr, sample, member) \ - (void *)container_of((ptr), typeof(*(sample)), member) - -/** - * Loop through the list given by head and set pos to struct in the list. - * - * Example: - * struct foo *iterator; - * list_for_each_entry(iterator, &bar->list_of_foos, entry) { - * [modify iterator] - * } - * - * This macro is not safe for node deletion. Use list_for_each_entry_safe - * instead. - * - * @param pos Iterator variable of the type of the list elements. - * @param head List head - * @param member Member name of the struct list_head in the list elements. - * - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = __container_of((head)->next, pos, member); \ - &pos->member != (head); \ - pos = __container_of(pos->member.next, pos, member)) - -/** - * Loop through the list, keeping a backup pointer to the element. This - * macro allows for the deletion of a list element while looping through the - * list. - * - * See list_for_each_entry for more details. - */ -#define list_for_each_entry_safe(pos, tmp, head, member) \ - for (pos = __container_of((head)->next, pos, member), \ - tmp = __container_of(pos->member.next, pos, member); \ - &pos->member != (head); \ - pos = tmp, tmp = __container_of(pos->member.next, tmp, member)) - - -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = __container_of((head)->prev, pos, member); \ - &pos->member != (head); \ - pos = __container_of(pos->member.prev, pos, member)) - -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = __container_of(pos->member.next, pos, member); \ - &pos->member != (head); \ - pos = __container_of(pos->member.next, pos, member)) - -#define list_for_each_entry_continue_reverse(pos, head, member) \ - for (pos = __container_of(pos->member.prev, pos, member); \ - &pos->member != (head); \ - pos = __container_of(pos->member.prev, pos, member)) - -#define list_for_each_entry_from(pos, head, member) \ - for (; \ - &pos->member != (head); \ - pos = __container_of(pos->member.next, pos, member)) - -#endif diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index b35205c4e979..b83d91ec030a 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -403,7 +403,6 @@ void omap_plane_install_properties(struct drm_plane *plane, static void omap_plane_reset(struct drm_plane *plane) { - struct omap_plane *omap_plane = to_omap_plane(plane); struct omap_plane_state *omap_state; if (plane->state) @@ -414,15 +413,6 @@ static void omap_plane_reset(struct drm_plane *plane) return; __drm_atomic_helper_plane_reset(plane, &omap_state->base); - - /* - * Set the zpos default depending on whether we are a primary or overlay - * plane. - */ - plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY - ? 0 : omap_plane->id; - plane->state->color_encoding = DRM_COLOR_YCBCR_BT601; - plane->state->color_range = DRM_COLOR_YCBCR_FULL_RANGE; } static struct drm_plane_state * @@ -533,6 +523,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, unsigned int num_planes = dispc_get_num_ovls(priv->dispc); struct drm_plane *plane; struct omap_plane *omap_plane; + unsigned int zpos; int ret; u32 nformats; const u32 *formats; @@ -564,7 +555,16 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, drm_plane_helper_add(plane, &omap_plane_helper_funcs); omap_plane_install_properties(plane, &plane->base); - drm_plane_create_zpos_property(plane, 0, 0, num_planes - 1); + + /* + * Set the zpos default depending on whether we are a primary or overlay + * plane. + */ + if (plane->type == DRM_PLANE_TYPE_PRIMARY) + zpos = 0; + else + zpos = omap_plane->id; + drm_plane_create_zpos_property(plane, zpos, 0, num_planes - 1); drm_plane_create_alpha_property(plane); drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_PREMULTI) | BIT(DRM_MODE_BLEND_COVERAGE)); diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index c324a3ed34b9..c09eb5ad65fc 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -3058,6 +3058,7 @@ static const struct drm_display_mode rocktech_rk101ii01d_ct_mode = { static const struct panel_desc rocktech_rk101ii01d_ct = { .modes = &rocktech_rk101ii01d_ct_mode, + .bpc = 8, .num_modes = 1, .size = { .width = 217, diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 96bb5a465627..94b6f0a19c83 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -562,7 +562,7 @@ static int panfrost_probe(struct platform_device *pdev) pfdev->coherent = device_get_dma_attr(&pdev->dev) == DEV_DMA_COHERENT; - /* Allocate and initialze the DRM device. */ + /* Allocate and initialize the DRM device. */ ddev = drm_dev_alloc(&panfrost_drm_driver, &pdev->dev); if (IS_ERR(ddev)) return PTR_ERR(ddev); diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c index b0142341e223..77e7cb6d1ae3 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2019 Arm Ltd. * * Based on msm_gem_freedreno.c: diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h b/drivers/gpu/drm/panfrost/panfrost_issues.h index 8e59d765bf19..501a76c5e95f 100644 --- a/drivers/gpu/drm/panfrost/panfrost_issues.h +++ b/drivers/gpu/drm/panfrost/panfrost_issues.h @@ -14,7 +14,7 @@ */ enum panfrost_hw_issue { /* Need way to guarantee that all previously-translated memory accesses - * are commited */ + * are committed */ HW_ISSUE_6367, /* On job complete with non-done the cache is not flushed */ diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index 39562f2d11a4..d3f82b26a631 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0 /* Copyright 2019 Linaro, Ltd, Rob Herring <[email protected]> */ #include <drm/panfrost_drm.h> diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h b/drivers/gpu/drm/panfrost/panfrost_regs.h index 16e776cc82ea..0b6cd8fdcb47 100644 --- a/drivers/gpu/drm/panfrost/panfrost_regs.h +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h @@ -293,7 +293,7 @@ #define AS_FAULTADDRESS_LO(as) (MMU_AS(as) + 0x20) /* (RO) Fault Address for address space n, low word */ #define AS_FAULTADDRESS_HI(as) (MMU_AS(as) + 0x24) /* (RO) Fault Address for address space n, high word */ #define AS_STATUS(as) (MMU_AS(as) + 0x28) /* (RO) Status flags for address space n */ -/* Additional Bifrost AS regsiters */ +/* Additional Bifrost AS registers */ #define AS_TRANSCFG_LO(as) (MMU_AS(as) + 0x30) /* (RW) Translation table configuration for address space n, low word */ #define AS_TRANSCFG_HI(as) (MMU_AS(as) + 0x34) /* (RW) Translation table configuration for address space n, high word */ #define AS_FAULTEXTRA_LO(as) (MMU_AS(as) + 0x38) /* (RO) Secondary fault address for address space n, low word */ diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile index 286bc81b3e7c..e7275b5e7ec8 100644 --- a/drivers/gpu/drm/rcar-du/Makefile +++ b/drivers/gpu/drm/rcar-du/Makefile @@ -6,12 +6,6 @@ rcar-du-drm-y := rcar_du_crtc.o \ rcar_du_kms.o \ rcar_du_plane.o \ -rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS) += rcar_du_of.o \ - rcar_du_of_lvds_r8a7790.dtb.o \ - rcar_du_of_lvds_r8a7791.dtb.o \ - rcar_du_of_lvds_r8a7793.dtb.o \ - rcar_du_of_lvds_r8a7795.dtb.o \ - rcar_du_of_lvds_r8a7796.dtb.o rcar-du-drm-$(CONFIG_DRM_RCAR_VSP) += rcar_du_vsp.o rcar-du-drm-$(CONFIG_DRM_RCAR_WRITEBACK) += rcar_du_writeback.o diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 982e450233ed..957ea97541d5 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -28,7 +28,6 @@ #include "rcar_du_drv.h" #include "rcar_du_kms.h" -#include "rcar_du_of.h" #include "rcar_du_regs.h" /* ----------------------------------------------------------------------------- @@ -634,6 +633,9 @@ static int rcar_du_probe(struct platform_device *pdev) unsigned int mask; int ret; + if (drm_firmware_drivers_only()) + return -ENODEV; + /* Allocate and initialize the R-Car device structure. */ rcdu = devm_drm_dev_alloc(&pdev->dev, &rcar_du_driver, struct rcar_du_device, ddev); @@ -699,22 +701,7 @@ static struct platform_driver rcar_du_platform_driver = { }, }; -static int __init rcar_du_init(void) -{ - if (drm_firmware_drivers_only()) - return -ENODEV; - - rcar_du_of_init(rcar_du_of_table); - - return platform_driver_register(&rcar_du_platform_driver); -} -module_init(rcar_du_init); - -static void __exit rcar_du_exit(void) -{ - platform_driver_unregister(&rcar_du_platform_driver); -} -module_exit(rcar_du_exit); +module_platform_driver(rcar_du_platform_driver); MODULE_AUTHOR("Laurent Pinchart <[email protected]>"); MODULE_DESCRIPTION("Renesas R-Car Display Unit DRM Driver"); diff --git a/drivers/gpu/drm/rcar-du/rcar_du_of.c b/drivers/gpu/drm/rcar-du/rcar_du_of.c deleted file mode 100644 index afef69669bb4..000000000000 --- a/drivers/gpu/drm/rcar-du/rcar_du_of.c +++ /dev/null @@ -1,323 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * rcar_du_of.c - Legacy DT bindings compatibility - * - * Copyright (C) 2018 Laurent Pinchart <[email protected]> - * - * Based on work from Jyri Sarha <[email protected]> - * Copyright (C) 2015 Texas Instruments - */ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_fdt.h> -#include <linux/of_graph.h> -#include <linux/slab.h> - -#include "rcar_du_crtc.h" -#include "rcar_du_drv.h" -#include "rcar_du_of.h" - -/* ----------------------------------------------------------------------------- - * Generic Overlay Handling - */ - -struct rcar_du_of_overlay { - const char *compatible; - void *begin; - void *end; -}; - -#define RCAR_DU_OF_DTB(type, soc) \ - extern char __dtb_rcar_du_of_##type##_##soc##_begin[]; \ - extern char __dtb_rcar_du_of_##type##_##soc##_end[] - -#define RCAR_DU_OF_OVERLAY(type, soc) \ - { \ - .compatible = "renesas,du-" #soc, \ - .begin = __dtb_rcar_du_of_##type##_##soc##_begin, \ - .end = __dtb_rcar_du_of_##type##_##soc##_end, \ - } - -static int __init rcar_du_of_apply_overlay(const struct rcar_du_of_overlay *dtbs, - const char *compatible) -{ - const struct rcar_du_of_overlay *dtb = NULL; - unsigned int i; - int ovcs_id; - - for (i = 0; dtbs[i].compatible; ++i) { - if (!strcmp(dtbs[i].compatible, compatible)) { - dtb = &dtbs[i]; - break; - } - } - - if (!dtb) - return -ENODEV; - - ovcs_id = 0; - return of_overlay_fdt_apply(dtb->begin, dtb->end - dtb->begin, - &ovcs_id); -} - -static int __init rcar_du_of_add_property(struct of_changeset *ocs, - struct device_node *np, - const char *name, const void *value, - int length) -{ - struct property *prop; - int ret = -ENOMEM; - - prop = kzalloc(sizeof(*prop), GFP_KERNEL); - if (!prop) - return -ENOMEM; - - prop->name = kstrdup(name, GFP_KERNEL); - if (!prop->name) - goto out_err; - - prop->value = kmemdup(value, length, GFP_KERNEL); - if (!prop->value) - goto out_err; - - of_property_set_flag(prop, OF_DYNAMIC); - - prop->length = length; - - ret = of_changeset_add_property(ocs, np, prop); - if (!ret) - return 0; - -out_err: - kfree(prop->value); - kfree(prop->name); - kfree(prop); - return ret; -} - -/* ----------------------------------------------------------------------------- - * LVDS Overlays - */ - -RCAR_DU_OF_DTB(lvds, r8a7790); -RCAR_DU_OF_DTB(lvds, r8a7791); -RCAR_DU_OF_DTB(lvds, r8a7793); -RCAR_DU_OF_DTB(lvds, r8a7795); -RCAR_DU_OF_DTB(lvds, r8a7796); - -static const struct rcar_du_of_overlay rcar_du_lvds_overlays[] __initconst = { - RCAR_DU_OF_OVERLAY(lvds, r8a7790), - RCAR_DU_OF_OVERLAY(lvds, r8a7791), - RCAR_DU_OF_OVERLAY(lvds, r8a7793), - RCAR_DU_OF_OVERLAY(lvds, r8a7795), - RCAR_DU_OF_OVERLAY(lvds, r8a7796), - { /* Sentinel */ }, -}; - -static struct of_changeset rcar_du_lvds_changeset; - -static void __init rcar_du_of_lvds_patch_one(struct device_node *lvds, - const struct of_phandle_args *clk, - struct device_node *local, - struct device_node *remote) -{ - unsigned int psize; - unsigned int i; - __be32 value[4]; - int ret; - - /* - * Set the LVDS clocks property. This can't be performed by the overlay - * as the structure of the clock specifier has changed over time, and we - * don't know at compile time which binding version the system we will - * run on uses. - */ - if (clk->args_count >= ARRAY_SIZE(value) - 1) - return; - - of_changeset_init(&rcar_du_lvds_changeset); - - value[0] = cpu_to_be32(clk->np->phandle); - for (i = 0; i < clk->args_count; ++i) - value[i + 1] = cpu_to_be32(clk->args[i]); - - psize = (clk->args_count + 1) * 4; - ret = rcar_du_of_add_property(&rcar_du_lvds_changeset, lvds, - "clocks", value, psize); - if (ret < 0) - goto done; - - /* - * Insert the node in the OF graph: patch the LVDS ports remote-endpoint - * properties to point to the endpoints of the sibling nodes in the - * graph. This can't be performed by the overlay: on the input side the - * overlay would contain a phandle for the DU LVDS output port that - * would clash with the system DT, and on the output side the connection - * is board-specific. - */ - value[0] = cpu_to_be32(local->phandle); - value[1] = cpu_to_be32(remote->phandle); - - for (i = 0; i < 2; ++i) { - struct device_node *endpoint; - - endpoint = of_graph_get_endpoint_by_regs(lvds, i, 0); - if (!endpoint) { - ret = -EINVAL; - goto done; - } - - ret = rcar_du_of_add_property(&rcar_du_lvds_changeset, - endpoint, "remote-endpoint", - &value[i], sizeof(value[i])); - of_node_put(endpoint); - if (ret < 0) - goto done; - } - - ret = of_changeset_apply(&rcar_du_lvds_changeset); - -done: - if (ret < 0) - of_changeset_destroy(&rcar_du_lvds_changeset); -} - -struct lvds_of_data { - struct resource res; - struct of_phandle_args clkspec; - struct device_node *local; - struct device_node *remote; -}; - -static void __init rcar_du_of_lvds_patch(const struct of_device_id *of_ids) -{ - const struct rcar_du_device_info *info; - const struct of_device_id *match; - struct lvds_of_data lvds_data[2] = { }; - struct device_node *lvds_node; - struct device_node *soc_node; - struct device_node *du_node; - char compatible[22]; - const char *soc_name; - unsigned int i; - int ret; - - /* Get the DU node and exit if not present or disabled. */ - du_node = of_find_matching_node_and_match(NULL, of_ids, &match); - if (!du_node || !of_device_is_available(du_node)) { - of_node_put(du_node); - return; - } - - info = match->data; - soc_node = of_get_parent(du_node); - - if (WARN_ON(info->num_lvds > ARRAY_SIZE(lvds_data))) - goto done; - - /* - * Skip if the LVDS nodes already exists. - * - * The nodes are searched based on the compatible string, which we - * construct from the SoC name found in the DU compatible string. As a - * match has been found we know the compatible string matches the - * expected format and can thus skip some of the string manipulation - * normal safety checks. - */ - soc_name = strchr(match->compatible, '-') + 1; - sprintf(compatible, "renesas,%s-lvds", soc_name); - lvds_node = of_find_compatible_node(NULL, NULL, compatible); - if (lvds_node) { - of_node_put(lvds_node); - return; - } - - /* - * Parse the DU node and store the register specifier, the clock - * specifier and the local and remote endpoint of the LVDS link for - * later use. - */ - for (i = 0; i < info->num_lvds; ++i) { - struct lvds_of_data *lvds = &lvds_data[i]; - unsigned int port; - char name[7]; - int index; - - sprintf(name, "lvds.%u", i); - index = of_property_match_string(du_node, "clock-names", name); - if (index < 0) - continue; - - ret = of_parse_phandle_with_args(du_node, "clocks", - "#clock-cells", index, - &lvds->clkspec); - if (ret < 0) - continue; - - port = info->routes[RCAR_DU_OUTPUT_LVDS0 + i].port; - - lvds->local = of_graph_get_endpoint_by_regs(du_node, port, 0); - if (!lvds->local) - continue; - - lvds->remote = of_graph_get_remote_endpoint(lvds->local); - if (!lvds->remote) - continue; - - index = of_property_match_string(du_node, "reg-names", name); - if (index < 0) - continue; - - of_address_to_resource(du_node, index, &lvds->res); - } - - /* Parse and apply the overlay. This will resolve phandles. */ - ret = rcar_du_of_apply_overlay(rcar_du_lvds_overlays, - match->compatible); - if (ret < 0) - goto done; - - /* Patch the newly created LVDS encoder nodes. */ - for_each_child_of_node(soc_node, lvds_node) { - struct resource res; - - if (!of_device_is_compatible(lvds_node, compatible)) - continue; - - /* Locate the lvds_data entry based on the resource start. */ - ret = of_address_to_resource(lvds_node, 0, &res); - if (ret < 0) - continue; - - for (i = 0; i < ARRAY_SIZE(lvds_data); ++i) { - if (lvds_data[i].res.start == res.start) - break; - } - - if (i == ARRAY_SIZE(lvds_data)) - continue; - - /* Patch the LVDS encoder. */ - rcar_du_of_lvds_patch_one(lvds_node, &lvds_data[i].clkspec, - lvds_data[i].local, - lvds_data[i].remote); - } - -done: - for (i = 0; i < info->num_lvds; ++i) { - of_node_put(lvds_data[i].clkspec.np); - of_node_put(lvds_data[i].local); - of_node_put(lvds_data[i].remote); - } - - of_node_put(soc_node); - of_node_put(du_node); -} - -void __init rcar_du_of_init(const struct of_device_id *of_ids) -{ - rcar_du_of_lvds_patch(of_ids); -} diff --git a/drivers/gpu/drm/rcar-du/rcar_du_of.h b/drivers/gpu/drm/rcar-du/rcar_du_of.h deleted file mode 100644 index 8dd3fbe96650..000000000000 --- a/drivers/gpu/drm/rcar-du/rcar_du_of.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * rcar_du_of.h - Legacy DT bindings compatibility - * - * Copyright (C) 2018 Laurent Pinchart <[email protected]> - */ -#ifndef __RCAR_DU_OF_H__ -#define __RCAR_DU_OF_H__ - -#include <linux/init.h> - -struct of_device_id; - -#if IS_ENABLED(CONFIG_DRM_RCAR_LVDS) -void __init rcar_du_of_init(const struct of_device_id *of_ids); -#else -static inline void rcar_du_of_init(const struct of_device_id *of_ids) { } -#endif /* CONFIG_DRM_RCAR_LVDS */ - -#endif /* __RCAR_DU_OF_H__ */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7790.dts b/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7790.dts deleted file mode 100644 index 8bee4e787a0a..000000000000 --- a/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7790.dts +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * rcar_du_of_lvds_r8a7790.dts - Legacy LVDS DT bindings conversion for R8A7790 - * - * Copyright (C) 2018 Laurent Pinchart <[email protected]> - */ - -/dts-v1/; -/plugin/; - -&{/} { - #address-cells = <2>; - #size-cells = <2>; - - lvds@feb90000 { - compatible = "renesas,r8a7790-lvds"; - reg = <0 0xfeb90000 0 0x1c>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - lvds0_input: endpoint { - }; - }; - port@1 { - reg = <1>; - lvds0_out: endpoint { - }; - }; - }; - }; - - lvds@feb94000 { - compatible = "renesas,r8a7790-lvds"; - reg = <0 0xfeb94000 0 0x1c>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - lvds1_input: endpoint { - }; - }; - port@1 { - reg = <1>; - lvds1_out: endpoint { - }; - }; - }; - }; -}; - -&{/display@feb00000/ports} { - port@1 { - endpoint { - remote-endpoint = <&lvds0_input>; - }; - }; - port@2 { - endpoint { - remote-endpoint = <&lvds1_input>; - }; - }; -}; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7791.dts b/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7791.dts deleted file mode 100644 index 92c0509971ec..000000000000 --- a/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7791.dts +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * rcar_du_of_lvds_r8a7791.dts - Legacy LVDS DT bindings conversion for R8A7791 - * - * Copyright (C) 2018 Laurent Pinchart <[email protected]> - */ - -/dts-v1/; -/plugin/; - -&{/} { - #address-cells = <2>; - #size-cells = <2>; - - lvds@feb90000 { - compatible = "renesas,r8a7791-lvds"; - reg = <0 0xfeb90000 0 0x1c>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - lvds0_input: endpoint { - }; - }; - port@1 { - reg = <1>; - lvds0_out: endpoint { - }; - }; - }; - }; -}; - -&{/display@feb00000/ports} { - port@1 { - endpoint { - remote-endpoint = <&lvds0_input>; - }; - }; -}; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7793.dts b/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7793.dts deleted file mode 100644 index c8b93f21de0f..000000000000 --- a/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7793.dts +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * rcar_du_of_lvds_r8a7793.dts - Legacy LVDS DT bindings conversion for R8A7793 - * - * Copyright (C) 2018 Laurent Pinchart <[email protected]> - */ - -/dts-v1/; -/plugin/; - -&{/} { - #address-cells = <2>; - #size-cells = <2>; - - lvds@feb90000 { - compatible = "renesas,r8a7793-lvds"; - reg = <0 0xfeb90000 0 0x1c>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - lvds0_input: endpoint { - }; - }; - port@1 { - reg = <1>; - lvds0_out: endpoint { - }; - }; - }; - }; -}; - -&{/display@feb00000/ports} { - port@1 { - endpoint { - remote-endpoint = <&lvds0_input>; - }; - }; -}; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7795.dts b/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7795.dts deleted file mode 100644 index 16c2d03cb016..000000000000 --- a/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7795.dts +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * rcar_du_of_lvds_r8a7795.dts - Legacy LVDS DT bindings conversion for R8A7795 - * - * Copyright (C) 2018 Laurent Pinchart <[email protected]> - */ - -/dts-v1/; -/plugin/; - -&{/soc} { - #address-cells = <2>; - #size-cells = <2>; - - lvds@feb90000 { - compatible = "renesas,r8a7795-lvds"; - reg = <0 0xfeb90000 0 0x14>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - lvds0_input: endpoint { - }; - }; - port@1 { - reg = <1>; - lvds0_out: endpoint { - }; - }; - }; - }; -}; - -&{/soc/display@feb00000/ports} { - port@3 { - endpoint { - remote-endpoint = <&lvds0_input>; - }; - }; -}; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7796.dts b/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7796.dts deleted file mode 100644 index 680e923ac036..000000000000 --- a/drivers/gpu/drm/rcar-du/rcar_du_of_lvds_r8a7796.dts +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * rcar_du_of_lvds_r8a7796.dts - Legacy LVDS DT bindings conversion for R8A7796 - * - * Copyright (C) 2018 Laurent Pinchart <[email protected]> - */ - -/dts-v1/; -/plugin/; - -&{/soc} { - #address-cells = <2>; - #size-cells = <2>; - - lvds@feb90000 { - compatible = "renesas,r8a7796-lvds"; - reg = <0 0xfeb90000 0 0x14>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - lvds0_input: endpoint { - }; - }; - port@1 { - reg = <1>; - lvds0_out: endpoint { - }; - }; - }; - }; -}; - -&{/soc/display@feb00000/ports} { - port@3 { - endpoint { - remote-endpoint = <&lvds0_input>; - }; - }; -}; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index 862197be1e01..5c1c7bb04f3f 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c @@ -549,8 +549,10 @@ void __rcar_du_plane_setup(struct rcar_du_group *rgrp, rcar_du_plane_setup_format(rgrp, (state->hwindex + 1) % 8, state); - if (rcdu->info->gen < 3) - rcar_du_plane_setup_scanout(rgrp, state); + if (rcdu->info->gen >= 3) + return; + + rcar_du_plane_setup_scanout(rgrp, state); if (state->source == RCAR_DU_PLANE_VSPD1) { unsigned int vspd1_sink = rgrp->index ? 2 : 0; @@ -558,6 +560,12 @@ void __rcar_du_plane_setup(struct rcar_du_group *rgrp, if (rcdu->vspd1_sink != vspd1_sink) { rcdu->vspd1_sink = vspd1_sink; rcar_du_set_dpad0_vsp1_routing(rcdu); + + /* + * Changes to the VSP1 sink take effect on DRES and thus + * need a restart of the group. + */ + rgrp->need_restart = true; } } } @@ -696,7 +704,6 @@ static void rcar_du_plane_reset(struct drm_plane *plane) state->hwindex = -1; state->source = RCAR_DU_PLANE_MEMORY; state->colorkey = RCAR_DU_COLORKEY_NONE; - state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; } static int rcar_du_plane_atomic_set_property(struct drm_plane *plane, diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index b7fc5b069cbc..8eb9b2b097ae 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -84,15 +84,6 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc) __rcar_du_plane_setup(crtc->group, &state); - /* - * Ensure that the plane source configuration takes effect by requesting - * a restart of the group. See rcar_du_plane_atomic_update() for a more - * detailed explanation. - * - * TODO: Check whether this is still needed on Gen3. - */ - crtc->group->need_restart = true; - vsp1_du_setup_lif(crtc->vsp->vsp, crtc->vsp_pipe, &cfg); } @@ -362,7 +353,6 @@ static void rcar_du_vsp_plane_reset(struct drm_plane *plane) return; __drm_atomic_helper_plane_reset(plane, &state->state); - state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; } static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = { diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index 72a272cfc11e..8dbfbbd3cad1 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -901,6 +901,7 @@ static const struct of_device_id rcar_lvds_of_table[] = { { .compatible = "renesas,r8a7793-lvds", .data = &rcar_lvds_gen2_info }, { .compatible = "renesas,r8a7795-lvds", .data = &rcar_lvds_gen3_info }, { .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info }, + { .compatible = "renesas,r8a77961-lvds", .data = &rcar_lvds_gen3_info }, { .compatible = "renesas,r8a77965-lvds", .data = &rcar_lvds_gen3_info }, { .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info }, { .compatible = "renesas,r8a77980-lvds", .data = &rcar_lvds_gen3_info }, diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 92c1902f53e4..ce4dc20412e0 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -579,7 +579,7 @@ static const struct drm_simple_display_pipe_funcs ssd130x_pipe_funcs = { static int ssd130x_connector_get_modes(struct drm_connector *connector) { struct ssd130x_device *ssd130x = drm_to_ssd130x(connector->dev); - struct drm_display_mode *mode = &ssd130x->mode; + struct drm_display_mode *mode; struct device *dev = ssd130x->dev; mode = drm_mode_duplicate(connector->dev, &ssd130x->mode); diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c index 1d6051b4f6fe..414c9973aa6d 100644 --- a/drivers/gpu/drm/sti/sti_cursor.c +++ b/drivers/gpu/drm/sti/sti_cursor.c @@ -351,7 +351,7 @@ static const struct drm_plane_funcs sti_cursor_plane_helpers_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_cleanup, - .reset = sti_plane_reset, + .reset = drm_atomic_helper_plane_reset, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, .late_register = sti_cursor_late_register, diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c index d1a35d97bc45..3db3768a3241 100644 --- a/drivers/gpu/drm/sti/sti_gdp.c +++ b/drivers/gpu/drm/sti/sti_gdp.c @@ -905,7 +905,7 @@ static const struct drm_plane_funcs sti_gdp_plane_helpers_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_cleanup, - .reset = sti_plane_reset, + .reset = drm_atomic_helper_plane_reset, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, .late_register = sti_gdp_late_register, diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c index 3c61ba8b43e0..2201a50353eb 100644 --- a/drivers/gpu/drm/sti/sti_hqvdp.c +++ b/drivers/gpu/drm/sti/sti_hqvdp.c @@ -1283,7 +1283,7 @@ static const struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_cleanup, - .reset = sti_plane_reset, + .reset = drm_atomic_helper_plane_reset, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, .late_register = sti_hqvdp_late_register, diff --git a/drivers/gpu/drm/sti/sti_plane.c b/drivers/gpu/drm/sti/sti_plane.c index 3da4a46df2f2..173409cdb99e 100644 --- a/drivers/gpu/drm/sti/sti_plane.c +++ b/drivers/gpu/drm/sti/sti_plane.c @@ -112,12 +112,6 @@ static int sti_plane_get_default_zpos(enum drm_plane_type type) return 0; } -void sti_plane_reset(struct drm_plane *plane) -{ - drm_atomic_helper_plane_reset(plane); - plane->state->zpos = sti_plane_get_default_zpos(plane->type); -} - static void sti_plane_attach_zorder_property(struct drm_plane *drm_plane, enum drm_plane_type type) { diff --git a/drivers/gpu/drm/sti/sti_plane.h b/drivers/gpu/drm/sti/sti_plane.h index 065ffffbfb4a..8e33e629d9b0 100644 --- a/drivers/gpu/drm/sti/sti_plane.h +++ b/drivers/gpu/drm/sti/sti_plane.h @@ -81,5 +81,4 @@ void sti_plane_update_fps(struct sti_plane *plane, void sti_plane_init_property(struct sti_plane *plane, enum drm_plane_type type); -void sti_plane_reset(struct drm_plane *plane); #endif diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 5eeb32c9c9ce..17cc050207f4 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -77,6 +77,7 @@ #define LTDC_CPSR 0x0044 /* Current Position Status */ #define LTDC_CDSR 0x0048 /* Current Display Status */ #define LTDC_EDCR 0x0060 /* External Display Control */ +#define LTDC_CCRCR 0x007C /* Computed CRC value */ #define LTDC_FUT 0x0090 /* Fifo underrun Threshold */ /* Layer register offsets */ @@ -121,6 +122,7 @@ #define GCR_LTDCEN BIT(0) /* LTDC ENable */ #define GCR_DEN BIT(16) /* Dither ENable */ +#define GCR_CRCEN BIT(19) /* CRC ENable */ #define GCR_PCPOL BIT(28) /* Pixel Clock POLarity-Inverted */ #define GCR_DEPOL BIT(29) /* Data Enable POLarity-High */ #define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity-High */ @@ -227,6 +229,13 @@ #define NB_PF 8 /* Max nb of HW pixel format */ +/* + * Skip the first value and the second in case CRC was enabled during + * the thread irq. This is to be sure CRC value is relevant for the + * frame. + */ +#define CRC_SKIP_FRAMES 2 + enum ltdc_pix_fmt { PF_NONE, /* RGB formats */ @@ -624,7 +633,8 @@ static inline void ltdc_set_ycbcr_config(struct drm_plane *plane, u32 drm_pix_fm break; default: /* RGB or not a YCbCr supported format */ - break; + DRM_ERROR("Unsupported pixel format: %u\n", drm_pix_fmt); + return; } /* Enable limited range */ @@ -664,6 +674,26 @@ static inline void ltdc_set_ycbcr_coeffs(struct drm_plane *plane) ltdc_ycbcr2rgb_coeffs[enc][ran][1]); } +static inline void ltdc_irq_crc_handle(struct ltdc_device *ldev, + struct drm_crtc *crtc) +{ + u32 crc; + int ret; + + if (ldev->crc_skip_count < CRC_SKIP_FRAMES) { + ldev->crc_skip_count++; + return; + } + + /* Get the CRC of the frame */ + ret = regmap_read(ldev->regmap, LTDC_CCRCR, &crc); + if (ret) + return; + + /* Report to DRM the CRC (hw dependent feature) */ + drm_crtc_add_crc_entry(crtc, true, drm_crtc_accurate_vblank_count(crtc), &crc); +} + static irqreturn_t ltdc_irq_thread(int irq, void *arg) { struct drm_device *ddev = arg; @@ -671,9 +701,14 @@ static irqreturn_t ltdc_irq_thread(int irq, void *arg) struct drm_crtc *crtc = drm_crtc_from_index(ddev, 0); /* Line IRQ : trigger the vblank event */ - if (ldev->irq_status & ISR_LIF) + if (ldev->irq_status & ISR_LIF) { drm_crtc_handle_vblank(crtc); + /* Early return if CRC is not active */ + if (ldev->crc_active) + ltdc_irq_crc_handle(ldev, crtc); + } + /* Save FIFO Underrun & Transfer Error status */ mutex_lock(&ldev->err_lock); if (ldev->irq_status & ISR_FUIF) @@ -1079,6 +1114,48 @@ static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc) regmap_clear_bits(ldev->regmap, LTDC_IER, IER_LIE); } +static int ltdc_crtc_set_crc_source(struct drm_crtc *crtc, const char *source) +{ + struct ltdc_device *ldev = crtc_to_ltdc(crtc); + int ret; + + DRM_DEBUG_DRIVER("\n"); + + if (!crtc) + return -ENODEV; + + if (source && strcmp(source, "auto") == 0) { + ldev->crc_active = true; + ret = regmap_set_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN); + } else if (!source) { + ldev->crc_active = false; + ret = regmap_clear_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN); + } else { + ret = -EINVAL; + } + + ldev->crc_skip_count = 0; + return ret; +} + +static int ltdc_crtc_verify_crc_source(struct drm_crtc *crtc, + const char *source, size_t *values_cnt) +{ + DRM_DEBUG_DRIVER("\n"); + + if (!crtc) + return -ENODEV; + + if (source && strcmp(source, "auto") != 0) { + DRM_DEBUG_DRIVER("Unknown CRC source %s for %s\n", + source, crtc->name); + return -EINVAL; + } + + *values_cnt = 1; + return 0; +} + static const struct drm_crtc_funcs ltdc_crtc_funcs = { .destroy = drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, @@ -1091,6 +1168,20 @@ static const struct drm_crtc_funcs ltdc_crtc_funcs = { .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, }; +static const struct drm_crtc_funcs ltdc_crtc_with_crc_support_funcs = { + .destroy = drm_crtc_cleanup, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .reset = drm_atomic_helper_crtc_reset, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, + .enable_vblank = ltdc_crtc_enable_vblank, + .disable_vblank = ltdc_crtc_disable_vblank, + .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp, + .set_crc_source = ltdc_crtc_set_crc_source, + .verify_crc_source = ltdc_crtc_verify_crc_source, +}; + /* * DRM_PLANE */ @@ -1478,8 +1569,13 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) drm_plane_create_zpos_immutable_property(primary, 0); - ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL, - <dc_crtc_funcs, NULL); + /* Init CRTC according to its hardware features */ + if (ldev->caps.crc) + ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL, + <dc_crtc_with_crc_support_funcs, NULL); + else + ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL, + <dc_crtc_funcs, NULL); if (ret) { DRM_ERROR("Can not initialize CRTC\n"); goto cleanup; @@ -1629,6 +1725,7 @@ static int ltdc_get_caps(struct drm_device *ddev) ldev->caps.ycbcr_input = false; ldev->caps.ycbcr_output = false; ldev->caps.plane_reg_shadow = false; + ldev->caps.crc = false; break; case HWVER_20101: ldev->caps.layer_ofs = LAY_OFS_0; @@ -1643,6 +1740,7 @@ static int ltdc_get_caps(struct drm_device *ddev) ldev->caps.ycbcr_input = false; ldev->caps.ycbcr_output = false; ldev->caps.plane_reg_shadow = false; + ldev->caps.crc = false; break; case HWVER_40100: ldev->caps.layer_ofs = LAY_OFS_1; @@ -1657,6 +1755,7 @@ static int ltdc_get_caps(struct drm_device *ddev) ldev->caps.ycbcr_input = true; ldev->caps.ycbcr_output = true; ldev->caps.plane_reg_shadow = true; + ldev->caps.crc = true; break; default: return -ENODEV; diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h index 6968d1ca5149..59fc5d1bbbab 100644 --- a/drivers/gpu/drm/stm/ltdc.h +++ b/drivers/gpu/drm/stm/ltdc.h @@ -27,6 +27,7 @@ struct ltdc_caps { bool ycbcr_input; /* ycbcr input converter supported */ bool ycbcr_output; /* ycbcr output converter supported */ bool plane_reg_shadow; /* plane shadow registers ability */ + bool crc; /* cyclic redundancy check supported */ }; #define LTDC_MAX_LAYER 4 @@ -46,6 +47,8 @@ struct ltdc_device { u32 irq_status; struct fps_info plane_fpsi[LTDC_MAX_LAYER]; struct drm_atomic_state *suspend_state; + int crc_skip_count; + bool crc_active; }; int ltdc_load(struct drm_device *ddev); diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index 929e95f86b5b..6d43080791a0 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -18,7 +18,6 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane) { - struct sun4i_layer *layer = plane_to_sun4i_layer(plane); struct sun4i_layer_state *state; if (plane->state) { @@ -31,10 +30,8 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane) } state = kzalloc(sizeof(*state), GFP_KERNEL); - if (state) { + if (state) __drm_atomic_helper_plane_reset(plane, &state->state); - plane->state->zpos = layer->id; - } } static struct drm_plane_state * @@ -192,7 +189,8 @@ static const uint64_t sun4i_layer_modifiers[] = { static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, struct sun4i_backend *backend, - enum drm_plane_type type) + enum drm_plane_type type, + unsigned int id) { const uint64_t *modifiers = sun4i_layer_modifiers; const uint32_t *formats = sun4i_layer_formats; @@ -204,6 +202,7 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, if (!layer) return ERR_PTR(-ENOMEM); + layer->id = id; layer->backend = backend; if (IS_ERR_OR_NULL(backend->frontend)) { @@ -226,8 +225,8 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, &sun4i_backend_layer_helper_funcs); drm_plane_create_alpha_property(&layer->plane); - drm_plane_create_zpos_property(&layer->plane, 0, 0, - SUN4I_BACKEND_NUM_LAYERS - 1); + drm_plane_create_zpos_property(&layer->plane, layer->id, + 0, SUN4I_BACKEND_NUM_LAYERS - 1); return layer; } @@ -249,14 +248,13 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm, enum drm_plane_type type = i ? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY; struct sun4i_layer *layer; - layer = sun4i_layer_init_one(drm, backend, type); + layer = sun4i_layer_init_one(drm, backend, type, i); if (IS_ERR(layer)) { dev_err(drm->dev, "Couldn't initialize %s plane\n", i ? "overlay" : "primary"); return ERR_CAST(layer); } - layer->id = i; planes[i] = &layer->plane; } diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index eb70eee8992a..c6951cf5d2ca 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -345,18 +345,19 @@ static void tegra_dc_setup_window(struct tegra_plane *plane, { unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp; struct tegra_dc *dc = plane->dc; - bool yuv, planar; + unsigned int planes; u32 value; + bool yuv; /* * For YUV planar modes, the number of bytes per pixel takes into * account only the luma component and therefore is 1. */ - yuv = tegra_plane_format_is_yuv(window->format, &planar, NULL); + yuv = tegra_plane_format_is_yuv(window->format, &planes, NULL); if (!yuv) bpp = window->bits_per_pixel / 8; else - bpp = planar ? 1 : 2; + bpp = (planes > 1) ? 1 : 2; tegra_plane_writel(plane, window->format, DC_WIN_COLOR_DEPTH); tegra_plane_writel(plane, window->swap, DC_WIN_BYTE_SWAP); @@ -385,7 +386,7 @@ static void tegra_dc_setup_window(struct tegra_plane *plane, * For DDA computations the number of bytes per pixel for YUV planar * modes needs to take into account all Y, U and V components. */ - if (yuv && planar) + if (yuv && planes > 1) bpp = 2; h_dda = compute_dda_inc(window->src.w, window->dst.w, false, bpp); @@ -405,9 +406,12 @@ static void tegra_dc_setup_window(struct tegra_plane *plane, tegra_plane_writel(plane, window->base[0], DC_WINBUF_START_ADDR); - if (yuv && planar) { + if (yuv && planes > 1) { tegra_plane_writel(plane, window->base[1], DC_WINBUF_START_ADDR_U); - tegra_plane_writel(plane, window->base[2], DC_WINBUF_START_ADDR_V); + + if (planes > 2) + tegra_plane_writel(plane, window->base[2], DC_WINBUF_START_ADDR_V); + value = window->stride[1] << 16 | window->stride[0]; tegra_plane_writel(plane, value, DC_WIN_LINE_STRIDE); } else { @@ -1193,6 +1197,13 @@ static const u32 tegra114_overlay_formats[] = { DRM_FORMAT_YUYV, DRM_FORMAT_YUV420, DRM_FORMAT_YUV422, + /* semi-planar formats */ + DRM_FORMAT_NV12, + DRM_FORMAT_NV21, + DRM_FORMAT_NV16, + DRM_FORMAT_NV61, + DRM_FORMAT_NV24, + DRM_FORMAT_NV42, }; static const u32 tegra124_overlay_formats[] = { @@ -1221,8 +1232,18 @@ static const u32 tegra124_overlay_formats[] = { /* planar formats */ DRM_FORMAT_UYVY, DRM_FORMAT_YUYV, - DRM_FORMAT_YUV420, - DRM_FORMAT_YUV422, + DRM_FORMAT_YVYU, + DRM_FORMAT_VYUY, + DRM_FORMAT_YUV420, /* YU12 */ + DRM_FORMAT_YUV422, /* YU16 */ + DRM_FORMAT_YUV444, /* YU24 */ + /* semi-planar formats */ + DRM_FORMAT_NV12, + DRM_FORMAT_NV21, + DRM_FORMAT_NV16, + DRM_FORMAT_NV61, + DRM_FORMAT_NV24, + DRM_FORMAT_NV42, }; static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, @@ -3211,16 +3232,9 @@ static int tegra_dc_probe(struct platform_device *pdev) return -ENXIO; err = tegra_dc_rgb_probe(dc); - if (err < 0 && err != -ENODEV) { - const char *level = KERN_ERR; - - if (err == -EPROBE_DEFER) - level = KERN_DEBUG; - - dev_printk(level, dc->dev, "failed to probe RGB output: %d\n", - err); - return err; - } + if (err < 0 && err != -ENODEV) + return dev_err_probe(&pdev->dev, err, + "failed to probe RGB output\n"); platform_set_drvdata(pdev, dc); pm_runtime_enable(&pdev->dev); diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h index 3f91a10ea6c7..f902794d42cc 100644 --- a/drivers/gpu/drm/tegra/dc.h +++ b/drivers/gpu/drm/tegra/dc.h @@ -637,6 +637,13 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc); #define WIN_COLOR_DEPTH_A8B8G8R8 36 #define WIN_COLOR_DEPTH_B8G8R8X8 37 #define WIN_COLOR_DEPTH_R8G8B8X8 38 +#define WIN_COLOR_DEPTH_YCbCr444P 41 +#define WIN_COLOR_DEPTH_YCrCb420SP 42 +#define WIN_COLOR_DEPTH_YCbCr420SP 43 +#define WIN_COLOR_DEPTH_YCrCb422SP 44 +#define WIN_COLOR_DEPTH_YCbCr422SP 45 +#define WIN_COLOR_DEPTH_YCrCb444SP 48 +#define WIN_COLOR_DEPTH_YCbCr444SP 49 #define WIN_COLOR_DEPTH_X8B8G8R8 65 #define WIN_COLOR_DEPTH_X8R8G8B8 66 diff --git a/drivers/gpu/drm/tegra/dp.c b/drivers/gpu/drm/tegra/dp.c index e4369e5b2943..7295975e5733 100644 --- a/drivers/gpu/drm/tegra/dp.c +++ b/drivers/gpu/drm/tegra/dp.c @@ -549,6 +549,15 @@ static void drm_dp_link_get_adjustments(struct drm_dp_link *link, { struct drm_dp_link_train_set *adjust = &link->train.adjust; unsigned int i; + u8 post_cursor; + int err; + + err = drm_dp_dpcd_read(link->aux, DP_ADJUST_REQUEST_POST_CURSOR2, + &post_cursor, sizeof(post_cursor)); + if (err < 0) { + DRM_ERROR("failed to read post_cursor2: %d\n", err); + post_cursor = 0; + } for (i = 0; i < link->lanes; i++) { adjust->voltage_swing[i] = @@ -560,7 +569,7 @@ static void drm_dp_link_get_adjustments(struct drm_dp_link *link, DP_TRAIN_PRE_EMPHASIS_SHIFT; adjust->post_cursor[i] = - drm_dp_get_adjust_request_post_cursor(status, i); + (post_cursor >> (i << 1)) & 0x3; } } diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index 5847dcad2478..20e1dd6b3bf0 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -280,7 +280,6 @@ static void tegra_dpaux_hotplug(struct work_struct *work) static irqreturn_t tegra_dpaux_irq(int irq, void *data) { struct tegra_dpaux *dpaux = data; - irqreturn_t ret = IRQ_HANDLED; u32 value; /* clear interrupts */ @@ -297,7 +296,7 @@ static irqreturn_t tegra_dpaux_irq(int irq, void *data) if (value & DPAUX_INTR_AUX_DONE) complete(&dpaux->complete); - return ret; + return IRQ_HANDLED; } enum tegra_dpaux_functions { diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index f46d377f0c30..de1333dc0d86 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -1538,8 +1538,10 @@ static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi) dsi->slave = platform_get_drvdata(gangster); of_node_put(np); - if (!dsi->slave) + if (!dsi->slave) { + put_device(&gangster->dev); return -EPROBE_DEFER; + } dsi->slave->master = dsi; } diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 8845af5d325f..bf240767dad9 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -1775,7 +1775,6 @@ static irqreturn_t tegra_hdmi_irq(int irq, void *data) static int tegra_hdmi_probe(struct platform_device *pdev) { - const char *level = KERN_ERR; struct tegra_hdmi *hdmi; struct resource *regs; int err; @@ -1817,36 +1816,21 @@ static int tegra_hdmi_probe(struct platform_device *pdev) hdmi->hdmi = devm_regulator_get(&pdev->dev, "hdmi"); err = PTR_ERR_OR_ZERO(hdmi->hdmi); - if (err) { - if (err == -EPROBE_DEFER) - level = KERN_DEBUG; - - dev_printk(level, &pdev->dev, - "failed to get HDMI regulator: %d\n", err); - return err; - } + if (err) + return dev_err_probe(&pdev->dev, err, + "failed to get HDMI regulator\n"); hdmi->pll = devm_regulator_get(&pdev->dev, "pll"); err = PTR_ERR_OR_ZERO(hdmi->pll); - if (err) { - if (err == -EPROBE_DEFER) - level = KERN_DEBUG; - - dev_printk(level, &pdev->dev, - "failed to get PLL regulator: %d\n", err); - return err; - } + if (err) + return dev_err_probe(&pdev->dev, err, + "failed to get PLL regulator\n"); hdmi->vdd = devm_regulator_get(&pdev->dev, "vdd"); err = PTR_ERR_OR_ZERO(hdmi->vdd); - if (err) { - if (err == -EPROBE_DEFER) - level = KERN_DEBUG; - - dev_printk(level, &pdev->dev, - "failed to get VDD regulator: %d\n", err); - return err; - } + if (err) + return dev_err_probe(&pdev->dev, err, + "failed to get VDD regulator\n"); hdmi->output.dev = &pdev->dev; diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index b910155f80c4..b8d3174c04c9 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -540,8 +540,8 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, struct tegra_plane *p = to_tegra_plane(plane); u32 value, min_width, bypass = 0; dma_addr_t base, addr_flag = 0; - unsigned int bpc; - bool yuv, planar; + unsigned int bpc, planes; + bool yuv; int err; /* rien ne va plus */ @@ -559,7 +559,7 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, return; } - yuv = tegra_plane_format_is_yuv(tegra_plane_state->format, &planar, &bpc); + yuv = tegra_plane_format_is_yuv(tegra_plane_state->format, &planes, &bpc); tegra_dc_assign_shared_plane(dc, p); @@ -660,20 +660,26 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, value = PITCH(fb->pitches[0]); tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE); - if (yuv && planar) { + if (yuv && planes > 1) { base = tegra_plane_state->iova[1] + fb->offsets[1]; base |= addr_flag; tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_U); tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_U); - base = tegra_plane_state->iova[2] + fb->offsets[2]; - base |= addr_flag; + if (planes > 2) { + base = tegra_plane_state->iova[2] + fb->offsets[2]; + base |= addr_flag; + + tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_V); + tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_V); + } + + value = PITCH_U(fb->pitches[1]); - tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_V); - tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_V); + if (planes > 2) + value |= PITCH_V(fb->pitches[2]); - value = PITCH_U(fb->pitches[2]) | PITCH_V(fb->pitches[2]); tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE_UV); } else { tegra_plane_writel(p, 0, DC_WINBUF_START_ADDR_U); diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 321cb1f13da6..e0e6938c6200 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -413,6 +413,22 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap) *swap = BYTE_SWAP_SWAP2; break; + case DRM_FORMAT_YVYU: + if (!swap) + return -EINVAL; + + *format = WIN_COLOR_DEPTH_YCbCr422; + *swap = BYTE_SWAP_SWAP4; + break; + + case DRM_FORMAT_VYUY: + if (!swap) + return -EINVAL; + + *format = WIN_COLOR_DEPTH_YCbCr422; + *swap = BYTE_SWAP_SWAP4HW; + break; + case DRM_FORMAT_YUV420: *format = WIN_COLOR_DEPTH_YCbCr420P; break; @@ -421,6 +437,34 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap) *format = WIN_COLOR_DEPTH_YCbCr422P; break; + case DRM_FORMAT_YUV444: + *format = WIN_COLOR_DEPTH_YCbCr444P; + break; + + case DRM_FORMAT_NV12: + *format = WIN_COLOR_DEPTH_YCbCr420SP; + break; + + case DRM_FORMAT_NV21: + *format = WIN_COLOR_DEPTH_YCrCb420SP; + break; + + case DRM_FORMAT_NV16: + *format = WIN_COLOR_DEPTH_YCbCr422SP; + break; + + case DRM_FORMAT_NV61: + *format = WIN_COLOR_DEPTH_YCrCb422SP; + break; + + case DRM_FORMAT_NV24: + *format = WIN_COLOR_DEPTH_YCbCr444SP; + break; + + case DRM_FORMAT_NV42: + *format = WIN_COLOR_DEPTH_YCrCb444SP; + break; + default: return -EINVAL; } @@ -441,13 +485,13 @@ bool tegra_plane_format_is_indexed(unsigned int format) return false; } -bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int *bpc) +bool tegra_plane_format_is_yuv(unsigned int format, unsigned int *planes, unsigned int *bpc) { switch (format) { case WIN_COLOR_DEPTH_YCbCr422: case WIN_COLOR_DEPTH_YUV422: - if (planar) - *planar = false; + if (planes) + *planes = 1; if (bpc) *bpc = 8; @@ -462,8 +506,23 @@ bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int * case WIN_COLOR_DEPTH_YUV422R: case WIN_COLOR_DEPTH_YCbCr422RA: case WIN_COLOR_DEPTH_YUV422RA: - if (planar) - *planar = true; + case WIN_COLOR_DEPTH_YCbCr444P: + if (planes) + *planes = 3; + + if (bpc) + *bpc = 8; + + return true; + + case WIN_COLOR_DEPTH_YCrCb420SP: + case WIN_COLOR_DEPTH_YCbCr420SP: + case WIN_COLOR_DEPTH_YCrCb422SP: + case WIN_COLOR_DEPTH_YCbCr422SP: + case WIN_COLOR_DEPTH_YCrCb444SP: + case WIN_COLOR_DEPTH_YCbCr444SP: + if (planes) + *planes = 2; if (bpc) *bpc = 8; @@ -471,8 +530,8 @@ bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int * return true; } - if (planar) - *planar = false; + if (planes) + *planes = 1; return false; } diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h index dfb20712fbd7..e33a581e6490 100644 --- a/drivers/gpu/drm/tegra/plane.h +++ b/drivers/gpu/drm/tegra/plane.h @@ -90,7 +90,7 @@ int tegra_plane_state_add(struct tegra_plane *plane, int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap); bool tegra_plane_format_is_indexed(unsigned int format); -bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int *bpc); +bool tegra_plane_format_is_yuv(unsigned int format, unsigned int *planes, unsigned int *bpc); int tegra_plane_setup_legacy_state(struct tegra_plane *tegra, struct tegra_plane_state *state); int tegra_plane_interconnect_init(struct tegra_plane *plane); diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 712e0004e96e..627d637a1e7e 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -51,6 +51,21 @@ config DRM_GM12U320 This is a KMS driver for projectors which use the GM12U320 chipset for video transfer over USB2/3, such as the Acer C120 mini projector. +config DRM_PANEL_MIPI_DBI + tristate "DRM support for MIPI DBI compatible panels" + depends on DRM && SPI + select DRM_KMS_HELPER + select DRM_GEM_CMA_HELPER + select DRM_MIPI_DBI + select BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + help + Say Y here if you want to enable support for MIPI DBI compatible + panels. The controller command setup can be provided using a + firmware file. For more information see + https://github.com/notro/panel-mipi-dbi/wiki. + To compile this driver as a module, choose M here. + config DRM_SIMPLEDRM tristate "Simple framebuffer driver" depends on DRM && MMU diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile index 5d5505d40e7b..1d9d6227e7ab 100644 --- a/drivers/gpu/drm/tiny/Makefile +++ b/drivers/gpu/drm/tiny/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_ARCPGU) += arcpgu.o obj-$(CONFIG_DRM_BOCHS) += bochs.o obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o obj-$(CONFIG_DRM_GM12U320) += gm12u320.o +obj-$(CONFIG_DRM_PANEL_MIPI_DBI) += panel-mipi-dbi.o obj-$(CONFIG_DRM_SIMPLEDRM) += simpledrm.o obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o obj-$(CONFIG_TINYDRM_ILI9163) += ili9163.o diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c new file mode 100644 index 000000000000..7f8c6c51387f --- /dev/null +++ b/drivers/gpu/drm/tiny/panel-mipi-dbi.c @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DRM driver for MIPI DBI compatible display panels + * + * Copyright 2022 Noralf Trønnes + */ + +#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/firmware.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/property.h> +#include <linux/regulator/consumer.h> +#include <linux/spi/spi.h> + +#include <drm/drm_atomic_helper.h> +#include <drm/drm_drv.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_gem_atomic_helper.h> +#include <drm/drm_gem_cma_helper.h> +#include <drm/drm_managed.h> +#include <drm/drm_mipi_dbi.h> +#include <drm/drm_modes.h> +#include <drm/drm_modeset_helper.h> + +#include <video/mipi_display.h> + +static const u8 panel_mipi_dbi_magic[15] = { 'M', 'I', 'P', 'I', ' ', 'D', 'B', 'I', + 0, 0, 0, 0, 0, 0, 0 }; + +/* + * The display controller configuration is stored in a firmware file. + * The Device Tree 'compatible' property value with a '.bin' suffix is passed + * to request_firmware() to fetch this file. + */ +struct panel_mipi_dbi_config { + /* Magic string: panel_mipi_dbi_magic */ + u8 magic[15]; + + /* Config file format version */ + u8 file_format_version; + + /* + * MIPI commands to execute when the display pipeline is enabled. + * This is used to configure the display controller. + * + * The commands are stored in a byte array with the format: + * command, num_parameters, [ parameter, ...], command, ... + * + * Some commands require a pause before the next command can be received. + * Inserting a delay in the command sequence is done by using the NOP command with one + * parameter: delay in miliseconds (the No Operation command is part of the MIPI Display + * Command Set where it has no parameters). + * + * Example: + * command 0x11 + * sleep 120ms + * command 0xb1 parameters 0x01, 0x2c, 0x2d + * command 0x29 + * + * Byte sequence: + * 0x11 0x00 + * 0x00 0x01 0x78 + * 0xb1 0x03 0x01 0x2c 0x2d + * 0x29 0x00 + */ + u8 commands[]; +}; + +struct panel_mipi_dbi_commands { + const u8 *buf; + size_t len; +}; + +static struct panel_mipi_dbi_commands * +panel_mipi_dbi_check_commands(struct device *dev, const struct firmware *fw) +{ + const struct panel_mipi_dbi_config *config = (struct panel_mipi_dbi_config *)fw->data; + struct panel_mipi_dbi_commands *commands; + size_t size = fw->size, commands_len; + unsigned int i = 0; + + if (size < sizeof(*config) + 2) { /* At least 1 command */ + dev_err(dev, "config: file size=%zu is too small\n", size); + return ERR_PTR(-EINVAL); + } + + if (memcmp(config->magic, panel_mipi_dbi_magic, sizeof(config->magic))) { + dev_err(dev, "config: Bad magic: %15ph\n", config->magic); + return ERR_PTR(-EINVAL); + } + + if (config->file_format_version != 1) { + dev_err(dev, "config: version=%u is not supported\n", config->file_format_version); + return ERR_PTR(-EINVAL); + } + + drm_dev_dbg(dev, DRM_UT_DRIVER, "size=%zu version=%u\n", size, config->file_format_version); + + commands_len = size - sizeof(*config); + + while ((i + 1) < commands_len) { + u8 command = config->commands[i++]; + u8 num_parameters = config->commands[i++]; + const u8 *parameters = &config->commands[i]; + + i += num_parameters; + if (i > commands_len) { + dev_err(dev, "config: command=0x%02x num_parameters=%u overflows\n", + command, num_parameters); + return ERR_PTR(-EINVAL); + } + + if (command == 0x00 && num_parameters == 1) + drm_dev_dbg(dev, DRM_UT_DRIVER, "sleep %ums\n", parameters[0]); + else + drm_dev_dbg(dev, DRM_UT_DRIVER, "command %02x %*ph\n", + command, num_parameters, parameters); + } + + if (i != commands_len) { + dev_err(dev, "config: malformed command array\n"); + return ERR_PTR(-EINVAL); + } + + commands = devm_kzalloc(dev, sizeof(*commands), GFP_KERNEL); + if (!commands) + return ERR_PTR(-ENOMEM); + + commands->len = commands_len; + commands->buf = devm_kmemdup(dev, config->commands, commands->len, GFP_KERNEL); + if (!commands->buf) + return ERR_PTR(-ENOMEM); + + return commands; +} + +static struct panel_mipi_dbi_commands *panel_mipi_dbi_commands_from_fw(struct device *dev) +{ + struct panel_mipi_dbi_commands *commands; + const struct firmware *fw; + const char *compatible; + char fw_name[40]; + int ret; + + ret = of_property_read_string_index(dev->of_node, "compatible", 0, &compatible); + if (ret) + return ERR_PTR(ret); + + snprintf(fw_name, sizeof(fw_name), "%s.bin", compatible); + ret = request_firmware(&fw, fw_name, dev); + if (ret) { + dev_err(dev, "No config file found for compatible '%s' (error=%d)\n", + compatible, ret); + + return ERR_PTR(ret); + } + + commands = panel_mipi_dbi_check_commands(dev, fw); + release_firmware(fw); + + return commands; +} + +static void panel_mipi_dbi_commands_execute(struct mipi_dbi *dbi, + struct panel_mipi_dbi_commands *commands) +{ + unsigned int i = 0; + + if (!commands) + return; + + while (i < commands->len) { + u8 command = commands->buf[i++]; + u8 num_parameters = commands->buf[i++]; + const u8 *parameters = &commands->buf[i]; + + if (command == 0x00 && num_parameters == 1) + msleep(parameters[0]); + else if (num_parameters) + mipi_dbi_command_stackbuf(dbi, command, parameters, num_parameters); + else + mipi_dbi_command(dbi, command); + + i += num_parameters; + } +} + +static void panel_mipi_dbi_enable(struct drm_simple_display_pipe *pipe, + struct drm_crtc_state *crtc_state, + struct drm_plane_state *plane_state) +{ + struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); + struct mipi_dbi *dbi = &dbidev->dbi; + int ret, idx; + + if (!drm_dev_enter(pipe->crtc.dev, &idx)) + return; + + drm_dbg(pipe->crtc.dev, "\n"); + + ret = mipi_dbi_poweron_conditional_reset(dbidev); + if (ret < 0) + goto out_exit; + if (!ret) + panel_mipi_dbi_commands_execute(dbi, dbidev->driver_private); + + mipi_dbi_enable_flush(dbidev, crtc_state, plane_state); +out_exit: + drm_dev_exit(idx); +} + +static const struct drm_simple_display_pipe_funcs panel_mipi_dbi_pipe_funcs = { + .enable = panel_mipi_dbi_enable, + .disable = mipi_dbi_pipe_disable, + .update = mipi_dbi_pipe_update, +}; + +DEFINE_DRM_GEM_CMA_FOPS(panel_mipi_dbi_fops); + +static const struct drm_driver panel_mipi_dbi_driver = { + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, + .fops = &panel_mipi_dbi_fops, + DRM_GEM_CMA_DRIVER_OPS_VMAP, + .debugfs_init = mipi_dbi_debugfs_init, + .name = "panel-mipi-dbi", + .desc = "MIPI DBI compatible display panel", + .date = "20220103", + .major = 1, + .minor = 0, +}; + +static int panel_mipi_dbi_get_mode(struct mipi_dbi_dev *dbidev, struct drm_display_mode *mode) +{ + struct device *dev = dbidev->drm.dev; + u16 hback_porch, vback_porch; + int ret; + + ret = of_get_drm_panel_display_mode(dev->of_node, mode, NULL); + if (ret) { + dev_err(dev, "%pOF: failed to get panel-timing (error=%d)\n", dev->of_node, ret); + return ret; + } + + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + + hback_porch = mode->htotal - mode->hsync_end; + vback_porch = mode->vtotal - mode->vsync_end; + + /* + * Make sure width and height are set and that only back porch and + * pixelclock are set in the other timing values. Also check that + * width and height don't exceed the 16-bit value specified by MIPI DCS. + */ + if (!mode->hdisplay || !mode->vdisplay || mode->flags || + mode->hsync_end > mode->hdisplay || (hback_porch + mode->hdisplay) > 0xffff || + mode->vsync_end > mode->vdisplay || (vback_porch + mode->vdisplay) > 0xffff) { + dev_err(dev, "%pOF: panel-timing out of bounds\n", dev->of_node); + return -EINVAL; + } + + /* The driver doesn't use the pixel clock but it is mandatory so fake one if not set */ + if (!mode->clock) + mode->clock = mode->htotal * mode->vtotal * 60 / 1000; + + dbidev->top_offset = vback_porch; + dbidev->left_offset = hback_porch; + + return 0; +} + +static int panel_mipi_dbi_spi_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct drm_display_mode mode; + struct mipi_dbi_dev *dbidev; + struct drm_device *drm; + struct mipi_dbi *dbi; + struct gpio_desc *dc; + int ret; + + dbidev = devm_drm_dev_alloc(dev, &panel_mipi_dbi_driver, struct mipi_dbi_dev, drm); + if (IS_ERR(dbidev)) + return PTR_ERR(dbidev); + + dbi = &dbidev->dbi; + drm = &dbidev->drm; + + ret = panel_mipi_dbi_get_mode(dbidev, &mode); + if (ret) + return ret; + + dbidev->regulator = devm_regulator_get(dev, "power"); + if (IS_ERR(dbidev->regulator)) + return dev_err_probe(dev, PTR_ERR(dbidev->regulator), + "Failed to get regulator 'power'\n"); + + dbidev->backlight = devm_of_find_backlight(dev); + if (IS_ERR(dbidev->backlight)) + return dev_err_probe(dev, PTR_ERR(dbidev->backlight), "Failed to get backlight\n"); + + dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(dbi->reset)) + return dev_err_probe(dev, PTR_ERR(dbi->reset), "Failed to get GPIO 'reset'\n"); + + dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW); + if (IS_ERR(dc)) + return dev_err_probe(dev, PTR_ERR(dc), "Failed to get GPIO 'dc'\n"); + + ret = mipi_dbi_spi_init(spi, dbi, dc); + if (ret) + return ret; + + if (device_property_present(dev, "write-only")) + dbi->read_commands = NULL; + + dbidev->driver_private = panel_mipi_dbi_commands_from_fw(dev); + if (IS_ERR(dbidev->driver_private)) + return PTR_ERR(dbidev->driver_private); + + ret = mipi_dbi_dev_init(dbidev, &panel_mipi_dbi_pipe_funcs, &mode, 0); + if (ret) + return ret; + + drm_mode_config_reset(drm); + + ret = drm_dev_register(drm, 0); + if (ret) + return ret; + + spi_set_drvdata(spi, drm); + + drm_fbdev_generic_setup(drm, 0); + + return 0; +} + +static int panel_mipi_dbi_spi_remove(struct spi_device *spi) +{ + struct drm_device *drm = spi_get_drvdata(spi); + + drm_dev_unplug(drm); + drm_atomic_helper_shutdown(drm); + + return 0; +} + +static void panel_mipi_dbi_spi_shutdown(struct spi_device *spi) +{ + drm_atomic_helper_shutdown(spi_get_drvdata(spi)); +} + +static int __maybe_unused panel_mipi_dbi_pm_suspend(struct device *dev) +{ + return drm_mode_config_helper_suspend(dev_get_drvdata(dev)); +} + +static int __maybe_unused panel_mipi_dbi_pm_resume(struct device *dev) +{ + drm_mode_config_helper_resume(dev_get_drvdata(dev)); + + return 0; +} + +static const struct dev_pm_ops panel_mipi_dbi_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(panel_mipi_dbi_pm_suspend, panel_mipi_dbi_pm_resume) +}; + +static const struct of_device_id panel_mipi_dbi_spi_of_match[] = { + { .compatible = "panel-mipi-dbi-spi" }, + {}, +}; +MODULE_DEVICE_TABLE(of, panel_mipi_dbi_spi_of_match); + +static const struct spi_device_id panel_mipi_dbi_spi_id[] = { + { "panel-mipi-dbi-spi", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(spi, panel_mipi_dbi_spi_id); + +static struct spi_driver panel_mipi_dbi_spi_driver = { + .driver = { + .name = "panel-mipi-dbi-spi", + .owner = THIS_MODULE, + .of_match_table = panel_mipi_dbi_spi_of_match, + .pm = &panel_mipi_dbi_pm_ops, + }, + .id_table = panel_mipi_dbi_spi_id, + .probe = panel_mipi_dbi_spi_probe, + .remove = panel_mipi_dbi_spi_remove, + .shutdown = panel_mipi_dbi_spi_shutdown, +}; +module_spi_driver(panel_mipi_dbi_spi_driver); + +MODULE_DESCRIPTION("MIPI DBI compatible display panel driver"); +MODULE_AUTHOR("Noralf Trønnes"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c index 97a775c48cea..5c74e236b16d 100644 --- a/drivers/gpu/drm/tiny/repaper.c +++ b/drivers/gpu/drm/tiny/repaper.c @@ -508,26 +508,6 @@ static void repaper_get_temperature(struct repaper_epd *epd) epd->factored_stage_time = epd->stage_time * factor10x / 10; } -static void repaper_gray8_to_mono_reversed(u8 *buf, u32 width, u32 height) -{ - u8 *gray8 = buf, *mono = buf; - int y, xb, i; - - for (y = 0; y < height; y++) - for (xb = 0; xb < width / 8; xb++) { - u8 byte = 0x00; - - for (i = 0; i < 8; i++) { - int x = xb * 8 + i; - - byte >>= 1; - if (gray8[y * width + x] >> 7) - byte |= BIT(7); - } - *mono++ = byte; - } -} - static int repaper_fb_dirty(struct drm_framebuffer *fb) { struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0); @@ -560,12 +540,10 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb) if (ret) goto out_free; - drm_fb_xrgb8888_to_gray8(buf, 0, cma_obj->vaddr, fb, &clip); + drm_fb_xrgb8888_to_mono_reversed(buf, 0, cma_obj->vaddr, fb, &clip); drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); - repaper_gray8_to_mono_reversed(buf, fb->width, fb->height); - if (epd->partial) { repaper_frame_data_repeat(epd, buf, epd->current_frame, REPAPER_NORMAL); diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c index d191e87a37b5..f5b8e864a5cd 100644 --- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -810,6 +810,9 @@ static int simpledrm_device_init_modeset(struct simpledrm_device *sdev) if (ret) return ret; drm_connector_helper_add(connector, &simpledrm_connector_helper_funcs); + drm_connector_set_panel_orientation_with_quirk(connector, + DRM_MODE_PANEL_ORIENTATION_UNKNOWN, + mode->hdisplay, mode->vdisplay); formats = simpledrm_device_formats(sdev, &nformats); diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c index 39459ae96f30..06238e6d7f5c 100644 --- a/drivers/gpu/drm/v3d/v3d_sched.c +++ b/drivers/gpu/drm/v3d/v3d_sched.c @@ -392,34 +392,24 @@ v3d_sched_init(struct v3d_dev *v3d) hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), NULL, NULL, "v3d_bin", v3d->drm.dev); - if (ret) { - dev_err(v3d->drm.dev, "Failed to create bin scheduler: %d.", ret); + if (ret) return ret; - } ret = drm_sched_init(&v3d->queue[V3D_RENDER].sched, &v3d_render_sched_ops, hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), NULL, NULL, "v3d_render", v3d->drm.dev); - if (ret) { - dev_err(v3d->drm.dev, "Failed to create render scheduler: %d.", - ret); - v3d_sched_fini(v3d); - return ret; - } + if (ret) + goto fail; ret = drm_sched_init(&v3d->queue[V3D_TFU].sched, &v3d_tfu_sched_ops, hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), NULL, NULL, "v3d_tfu", v3d->drm.dev); - if (ret) { - dev_err(v3d->drm.dev, "Failed to create TFU scheduler: %d.", - ret); - v3d_sched_fini(v3d); - return ret; - } + if (ret) + goto fail; if (v3d_has_csd(v3d)) { ret = drm_sched_init(&v3d->queue[V3D_CSD].sched, @@ -427,27 +417,23 @@ v3d_sched_init(struct v3d_dev *v3d) hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), NULL, NULL, "v3d_csd", v3d->drm.dev); - if (ret) { - dev_err(v3d->drm.dev, "Failed to create CSD scheduler: %d.", - ret); - v3d_sched_fini(v3d); - return ret; - } + if (ret) + goto fail; ret = drm_sched_init(&v3d->queue[V3D_CACHE_CLEAN].sched, &v3d_cache_clean_sched_ops, hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), NULL, NULL, "v3d_cache_clean", v3d->drm.dev); - if (ret) { - dev_err(v3d->drm.dev, "Failed to create CACHE_CLEAN scheduler: %d.", - ret); - v3d_sched_fini(v3d); - return ret; - } + if (ret) + goto fail; } return 0; + +fail: + v3d_sched_fini(v3d); + return ret; } void diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 6994f8c0e02e..80c685ab3e30 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -447,7 +447,6 @@ static int host1x_probe(struct platform_device *pdev) if (syncpt_irq < 0) return syncpt_irq; - host1x_bo_cache_init(&host->cache); mutex_init(&host->devices_lock); INIT_LIST_HEAD(&host->devices); INIT_LIST_HEAD(&host->list); @@ -489,10 +488,12 @@ static int host1x_probe(struct platform_device *pdev) if (err) return err; + host1x_bo_cache_init(&host->cache); + err = host1x_iommu_init(host); if (err < 0) { dev_err(&pdev->dev, "failed to setup IOMMU: %d\n", err); - return err; + goto destroy_cache; } err = host1x_channel_list_init(&host->channel_list, @@ -553,6 +554,8 @@ free_channels: host1x_channel_list_free(&host->channel_list); iommu_exit: host1x_iommu_exit(host); +destroy_cache: + host1x_bo_cache_destroy(&host->cache); return err; } @@ -568,6 +571,7 @@ static int host1x_remove(struct platform_device *pdev) host1x_intr_deinit(host); host1x_syncpt_deinit(host); + host1x_channel_list_free(&host->channel_list); host1x_iommu_exit(host); host1x_bo_cache_destroy(&host->cache); diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c index a2bb276a8b24..7361cfabdd85 100644 --- a/drivers/video/fbdev/core/cfbimgblt.c +++ b/drivers/video/fbdev/core/cfbimgblt.c @@ -16,15 +16,15 @@ * must be laid out exactly in the same format as the framebuffer. Yes I know * their are cards with hardware that coverts images of various depths to the * framebuffer depth. But not every card has this. All images must be rounded - * up to the nearest byte. For example a bitmap 12 bits wide must be two - * bytes width. + * up to the nearest byte. For example a bitmap 12 bits wide must be two + * bytes width. * - * Tony: - * Incorporate mask tables similar to fbcon-cfb*.c in 2.4 API. This speeds + * Tony: + * Incorporate mask tables similar to fbcon-cfb*.c in 2.4 API. This speeds * up the code significantly. - * + * * Code for depths not multiples of BITS_PER_LONG is still kludgy, which is - * still processed a bit at a time. + * still processed a bit at a time. * * Also need to add code to deal with cards endians that are different than * the native cpu endians. I also need to deal with MSB position in the word. @@ -72,8 +72,8 @@ static const u32 cfb_tab32[] = { #define FB_WRITEL fb_writel #define FB_READL fb_readl -static inline void color_imageblit(const struct fb_image *image, - struct fb_info *p, u8 __iomem *dst1, +static inline void color_imageblit(const struct fb_image *image, + struct fb_info *p, u8 __iomem *dst1, u32 start_index, u32 pitch_index) { @@ -92,7 +92,7 @@ static inline void color_imageblit(const struct fb_image *image, dst = (u32 __iomem *) dst1; shift = 0; val = 0; - + if (start_index) { u32 start_mask = ~fb_shifted_pixels_mask_u32(p, start_index, bswapmask); @@ -109,8 +109,8 @@ static inline void color_imageblit(const struct fb_image *image, val |= FB_SHIFT_HIGH(p, color, shift ^ bswapmask); if (shift >= null_bits) { FB_WRITEL(val, dst++); - - val = (shift == null_bits) ? 0 : + + val = (shift == null_bits) ? 0 : FB_SHIFT_LOW(p, color, 32 - shift); } shift += bpp; @@ -134,9 +134,9 @@ static inline void color_imageblit(const struct fb_image *image, } } -static inline void slow_imageblit(const struct fb_image *image, struct fb_info *p, +static inline void slow_imageblit(const struct fb_image *image, struct fb_info *p, u8 __iomem *dst1, u32 fgcolor, - u32 bgcolor, + u32 bgcolor, u32 start_index, u32 pitch_index) { @@ -172,7 +172,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * l--; color = (*s & (1 << l)) ? fgcolor : bgcolor; val |= FB_SHIFT_HIGH(p, color, shift ^ bswapmask); - + /* Did the bitshift spill bits to the next long? */ if (shift >= null_bits) { FB_WRITEL(val, dst++); @@ -191,16 +191,16 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); } - + dst1 += pitch; - src += spitch; + src += spitch; if (pitch_index) { dst2 += pitch; dst1 = (u8 __iomem *)((long __force)dst2 & ~(sizeof(u32) - 1)); start_index += pitch_index; start_index &= 32 - 1; } - + } } @@ -212,29 +212,35 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * * fix->line_legth is divisible by 4; * beginning and end of a scanline is dword aligned */ -static inline void fast_imageblit(const struct fb_image *image, struct fb_info *p, - u8 __iomem *dst1, u32 fgcolor, - u32 bgcolor) +static inline void fast_imageblit(const struct fb_image *image, struct fb_info *p, + u8 __iomem *dst1, u32 fgcolor, + u32 bgcolor) { u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; u32 ppw = 32/bpp, spitch = (image->width + 7)/8; - u32 bit_mask, end_mask, eorx, shift; + u32 bit_mask, eorx; const char *s = image->data, *src; u32 __iomem *dst; const u32 *tab = NULL; + size_t tablen; + u32 colortab[16]; int i, j, k; switch (bpp) { case 8: tab = fb_be_math(p) ? cfb_tab8_be : cfb_tab8_le; + tablen = 16; break; case 16: tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; + tablen = 4; break; case 32: - default: tab = cfb_tab32; + tablen = 2; break; + default: + return; } for (i = ppw-1; i--; ) { @@ -243,25 +249,52 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * fgx |= fgcolor; bgx |= bgcolor; } - + bit_mask = (1 << ppw) - 1; eorx = fgx ^ bgx; k = image->width/ppw; + for (i = 0; i < tablen; ++i) + colortab[i] = (tab[i] & eorx) ^ bgx; + for (i = image->height; i--; ) { - dst = (u32 __iomem *) dst1, shift = 8; src = s; - - for (j = k; j--; ) { - shift -= ppw; - end_mask = tab[(*src >> shift) & bit_mask]; - FB_WRITEL((end_mask & eorx)^bgx, dst++); - if (!shift) { shift = 8; src++; } + dst = (u32 __iomem *)dst1; + src = s; + + switch (ppw) { + case 4: /* 8 bpp */ + for (j = k; j; j -= 2, ++src) { + FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 0) & bit_mask], dst++); + } + break; + case 2: /* 16 bpp */ + for (j = k; j; j -= 4, ++src) { + FB_WRITEL(colortab[(*src >> 6) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 2) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 0) & bit_mask], dst++); + } + break; + case 1: /* 32 bpp */ + for (j = k; j; j -= 8, ++src) { + FB_WRITEL(colortab[(*src >> 7) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 6) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 5) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 3) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 2) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 1) & bit_mask], dst++); + FB_WRITEL(colortab[(*src >> 0) & bit_mask], dst++); + } + break; } + dst1 += p->fix.line_length; s += spitch; } -} - +} + void cfb_imageblit(struct fb_info *p, const struct fb_image *image) { u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; @@ -292,13 +325,13 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) } else { fgcolor = image->fg_color; bgcolor = image->bg_color; - } - - if (32 % bpp == 0 && !start_index && !pitch_index && + } + + if (32 % bpp == 0 && !start_index && !pitch_index && ((width & (32/bpp-1)) == 0) && - bpp >= 8 && bpp <= 32) + bpp >= 8 && bpp <= 32) fast_imageblit(image, p, dst1, fgcolor, bgcolor); - else + else slow_imageblit(image, p, dst1, fgcolor, bgcolor, start_index, pitch_index); } else diff --git a/drivers/video/fbdev/core/sysfillrect.c b/drivers/video/fbdev/core/sysfillrect.c index 33ee3d34f9d2..bcdcaeae6538 100644 --- a/drivers/video/fbdev/core/sysfillrect.c +++ b/drivers/video/fbdev/core/sysfillrect.c @@ -50,19 +50,9 @@ bitfill_aligned(struct fb_info *p, unsigned long *dst, int dst_idx, /* Main chunk */ n /= bits; - while (n >= 8) { - *dst++ = pat; - *dst++ = pat; - *dst++ = pat; - *dst++ = pat; - *dst++ = pat; - *dst++ = pat; - *dst++ = pat; - *dst++ = pat; - n -= 8; - } - while (n--) - *dst++ = pat; + memset_l(dst, pat, n); + dst += n; + /* Trailing bits */ if (last) *dst = comp(pat, *dst, last); diff --git a/drivers/video/fbdev/core/sysimgblt.c b/drivers/video/fbdev/core/sysimgblt.c index a4d05b1b17d7..722c327a381b 100644 --- a/drivers/video/fbdev/core/sysimgblt.c +++ b/drivers/video/fbdev/core/sysimgblt.c @@ -188,23 +188,29 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, { u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; u32 ppw = 32/bpp, spitch = (image->width + 7)/8; - u32 bit_mask, end_mask, eorx, shift; + u32 bit_mask, eorx; const char *s = image->data, *src; u32 *dst; - const u32 *tab = NULL; + const u32 *tab; + size_t tablen; + u32 colortab[16]; int i, j, k; switch (bpp) { case 8: tab = fb_be_math(p) ? cfb_tab8_be : cfb_tab8_le; + tablen = 16; break; case 16: tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; + tablen = 4; break; case 32: - default: tab = cfb_tab32; + tablen = 2; break; + default: + return; } for (i = ppw-1; i--; ) { @@ -218,19 +224,40 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, eorx = fgx ^ bgx; k = image->width/ppw; + for (i = 0; i < tablen; ++i) + colortab[i] = (tab[i] & eorx) ^ bgx; + for (i = image->height; i--; ) { dst = dst1; - shift = 8; src = s; - for (j = k; j--; ) { - shift -= ppw; - end_mask = tab[(*src >> shift) & bit_mask]; - *dst++ = (end_mask & eorx) ^ bgx; - if (!shift) { - shift = 8; - src++; + switch (ppw) { + case 4: /* 8 bpp */ + for (j = k; j; j -= 2, ++src) { + *dst++ = colortab[(*src >> 4) & bit_mask]; + *dst++ = colortab[(*src >> 0) & bit_mask]; + } + break; + case 2: /* 16 bpp */ + for (j = k; j; j -= 4, ++src) { + *dst++ = colortab[(*src >> 6) & bit_mask]; + *dst++ = colortab[(*src >> 4) & bit_mask]; + *dst++ = colortab[(*src >> 2) & bit_mask]; + *dst++ = colortab[(*src >> 0) & bit_mask]; + } + break; + case 1: /* 32 bpp */ + for (j = k; j; j -= 8, ++src) { + *dst++ = colortab[(*src >> 7) & bit_mask]; + *dst++ = colortab[(*src >> 6) & bit_mask]; + *dst++ = colortab[(*src >> 5) & bit_mask]; + *dst++ = colortab[(*src >> 4) & bit_mask]; + *dst++ = colortab[(*src >> 3) & bit_mask]; + *dst++ = colortab[(*src >> 2) & bit_mask]; + *dst++ = colortab[(*src >> 1) & bit_mask]; + *dst++ = colortab[(*src >> 0) & bit_mask]; } + break; } dst1 += p->fix.line_length; s += spitch; diff --git a/include/drm/dp/drm_dp_helper.h b/include/drm/dp/drm_dp_helper.h index 69487bd8ed56..51e02cf75277 100644 --- a/include/drm/dp/drm_dp_helper.h +++ b/include/drm/dp/drm_dp_helper.h @@ -456,7 +456,7 @@ struct drm_panel; #define DP_FEC_CAPABILITY_1 0x091 /* 2.0 */ /* DP-HDMI2.1 PCON DSC ENCODER SUPPORT */ -#define DP_PCON_DSC_ENCODER_CAP_SIZE 0xC /* 0x9E - 0x92 */ +#define DP_PCON_DSC_ENCODER_CAP_SIZE 0xD /* 0x92 through 0x9E */ #define DP_PCON_DSC_ENCODER 0x092 # define DP_PCON_DSC_ENCODER_SUPPORTED (1 << 0) # define DP_PCON_DSC_PPS_ENC_OVERRIDE (1 << 1) @@ -1530,8 +1530,6 @@ u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SI int lane); u8 drm_dp_get_adjust_tx_ffe_preset(const u8 link_status[DP_LINK_STATUS_SIZE], int lane); -u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZE], - unsigned int lane); #define DP_BRANCH_OUI_HEADER_SIZE 0xc #define DP_RECEIVER_CAP_SIZE 0xf diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h index 6fe13cce2670..dad2f187b64b 100644 --- a/include/drm/drm_mipi_dbi.h +++ b/include/drm/drm_mipi_dbi.h @@ -130,6 +130,14 @@ struct mipi_dbi_dev { * @dbi: MIPI DBI interface */ struct mipi_dbi dbi; + + /** + * @driver_private: Driver private data. + * Necessary for drivers with private data since devm_drm_dev_alloc() + * can't allocate structures that embed a structure which then again + * embeds drm_device. + */ + void *driver_private; }; static inline struct mipi_dbi_dev *drm_to_mipi_dbi_dev(struct drm_device *drm) diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h index c34a3e8030e1..912f1e415685 100644 --- a/include/drm/drm_mode_object.h +++ b/include/drm/drm_mode_object.h @@ -98,6 +98,10 @@ struct drm_object_properties { * Hence atomic drivers should not use drm_object_property_set_value() * and drm_object_property_get_value() on mutable objects, i.e. those * without the DRM_MODE_PROP_IMMUTABLE flag set. + * + * For atomic drivers the default value of properties is stored in this + * array, so drm_object_property_get_default_value can be used to + * retrieve it. */ uint64_t values[DRM_OBJECT_MAX_PROPERTY]; }; @@ -126,6 +130,9 @@ int drm_object_property_set_value(struct drm_mode_object *obj, int drm_object_property_get_value(struct drm_mode_object *obj, struct drm_property *property, uint64_t *value); +int drm_object_property_get_default_value(struct drm_mode_object *obj, + struct drm_property *property, + uint64_t *val); void drm_object_attach_property(struct drm_mode_object *obj, struct drm_property *property, diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 29ba4adf0c53..2fa6b2c33b3f 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -466,6 +466,8 @@ void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags); int of_get_drm_display_mode(struct device_node *np, struct drm_display_mode *dmode, u32 *bus_flags, int index); +int of_get_drm_panel_display_mode(struct device_node *np, + struct drm_display_mode *dmode, u32 *bus_flags); #else static inline int of_get_drm_display_mode(struct device_node *np, struct drm_display_mode *dmode, @@ -473,6 +475,12 @@ static inline int of_get_drm_display_mode(struct device_node *np, { return -EINVAL; } + +static inline int of_get_drm_panel_display_mode(struct device_node *np, + struct drm_display_mode *dmode, u32 *bus_flags) +{ + return -EINVAL; +} #endif void drm_mode_set_name(struct drm_display_mode *mode); diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 914ebd9290e5..05c3642aaece 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -1118,10 +1118,16 @@ struct drm_i915_gem_exec_object2 { /** * When the EXEC_OBJECT_PINNED flag is specified this is populated by * the user with the GTT offset at which this object will be pinned. + * * When the I915_EXEC_NO_RELOC flag is specified this must contain the * presumed_offset of the object. + * * During execbuffer2 the kernel populates it with the value of the * current GTT offset of the object, for future presumed_offset writes. + * + * See struct drm_i915_gem_create_ext for the rules when dealing with + * alignment restrictions with I915_MEMORY_CLASS_DEVICE, on devices with + * minimum page sizes, like DG2. */ __u64 offset; @@ -3144,11 +3150,40 @@ struct drm_i915_gem_create_ext { * * The (page-aligned) allocated size for the object will be returned. * - * Note that for some devices we have might have further minimum - * page-size restrictions(larger than 4K), like for device local-memory. - * However in general the final size here should always reflect any - * rounding up, if for example using the I915_GEM_CREATE_EXT_MEMORY_REGIONS - * extension to place the object in device local-memory. + * + * DG2 64K min page size implications: + * + * On discrete platforms, starting from DG2, we have to contend with GTT + * page size restrictions when dealing with I915_MEMORY_CLASS_DEVICE + * objects. Specifically the hardware only supports 64K or larger GTT + * page sizes for such memory. The kernel will already ensure that all + * I915_MEMORY_CLASS_DEVICE memory is allocated using 64K or larger page + * sizes underneath. + * + * Note that the returned size here will always reflect any required + * rounding up done by the kernel, i.e 4K will now become 64K on devices + * such as DG2. + * + * Special DG2 GTT address alignment requirement: + * + * The GTT alignment will also need to be at least 2M for such objects. + * + * Note that due to how the hardware implements 64K GTT page support, we + * have some further complications: + * + * 1) The entire PDE (which covers a 2MB virtual address range), must + * contain only 64K PTEs, i.e mixing 4K and 64K PTEs in the same + * PDE is forbidden by the hardware. + * + * 2) We still need to support 4K PTEs for I915_MEMORY_CLASS_SYSTEM + * objects. + * + * To keep things simple for userland, we mandate that any GTT mappings + * must be aligned to and rounded up to 2MB. The kernel will internally + * pad them out to the next 2MB boundary. As this only wastes virtual + * address space and avoids userland having to copy any needlessly + * complicated PDE sharing scheme (coloring) and only affects DG2, this + * is deemed to be a good compromise. */ __u64 size; /** diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index 6b8fffc28a50..07efc8033492 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -67,16 +67,21 @@ struct drm_msm_timespec { __s64 tv_nsec; /* nanoseconds */ }; -#define MSM_PARAM_GPU_ID 0x01 -#define MSM_PARAM_GMEM_SIZE 0x02 -#define MSM_PARAM_CHIP_ID 0x03 -#define MSM_PARAM_MAX_FREQ 0x04 -#define MSM_PARAM_TIMESTAMP 0x05 -#define MSM_PARAM_GMEM_BASE 0x06 -#define MSM_PARAM_PRIORITIES 0x07 /* The # of priority levels */ -#define MSM_PARAM_PP_PGTABLE 0x08 /* => 1 for per-process pagetables, else 0 */ -#define MSM_PARAM_FAULTS 0x09 -#define MSM_PARAM_SUSPENDS 0x0a +/* Below "RO" indicates a read-only param, "WO" indicates write-only, and + * "RW" indicates a param that can be both read (GET_PARAM) and written + * (SET_PARAM) + */ +#define MSM_PARAM_GPU_ID 0x01 /* RO */ +#define MSM_PARAM_GMEM_SIZE 0x02 /* RO */ +#define MSM_PARAM_CHIP_ID 0x03 /* RO */ +#define MSM_PARAM_MAX_FREQ 0x04 /* RO */ +#define MSM_PARAM_TIMESTAMP 0x05 /* RO */ +#define MSM_PARAM_GMEM_BASE 0x06 /* RO */ +#define MSM_PARAM_PRIORITIES 0x07 /* RO: The # of priority levels */ +#define MSM_PARAM_PP_PGTABLE 0x08 /* RO: Deprecated, always returns zero */ +#define MSM_PARAM_FAULTS 0x09 /* RO */ +#define MSM_PARAM_SUSPENDS 0x0a /* RO */ +#define MSM_PARAM_SYSPROF 0x0b /* WO: 1 preserves perfcntrs, 2 also disables suspend */ /* For backwards compat. The original support for preemption was based on * a single ring per priority level so # of priority levels equals the # @@ -227,6 +232,7 @@ struct drm_msm_gem_submit_bo { #define MSM_SUBMIT_SUDO 0x10000000 /* run submitted cmds from RB */ #define MSM_SUBMIT_SYNCOBJ_IN 0x08000000 /* enable input syncobj */ #define MSM_SUBMIT_SYNCOBJ_OUT 0x04000000 /* enable output syncobj */ +#define MSM_SUBMIT_FENCE_SN_IN 0x02000000 /* userspace passes in seqno fence */ #define MSM_SUBMIT_FLAGS ( \ MSM_SUBMIT_NO_IMPLICIT | \ MSM_SUBMIT_FENCE_FD_IN | \ @@ -234,6 +240,7 @@ struct drm_msm_gem_submit_bo { MSM_SUBMIT_SUDO | \ MSM_SUBMIT_SYNCOBJ_IN | \ MSM_SUBMIT_SYNCOBJ_OUT | \ + MSM_SUBMIT_FENCE_SN_IN | \ 0) #define MSM_SUBMIT_SYNCOBJ_RESET 0x00000001 /* Reset syncobj after wait. */ @@ -253,7 +260,7 @@ struct drm_msm_gem_submit_syncobj { */ struct drm_msm_gem_submit { __u32 flags; /* MSM_PIPE_x | MSM_SUBMIT_x */ - __u32 fence; /* out */ + __u32 fence; /* out (or in with MSM_SUBMIT_FENCE_SN_IN flag) */ __u32 nr_bos; /* in, number of submit_bo's */ __u32 nr_cmds; /* in, number of submit_cmd's */ __u64 bos; /* in, ptr to array of submit_bo's */ @@ -333,9 +340,7 @@ struct drm_msm_submitqueue_query { }; #define DRM_MSM_GET_PARAM 0x00 -/* placeholder: #define DRM_MSM_SET_PARAM 0x01 - */ #define DRM_MSM_GEM_NEW 0x02 #define DRM_MSM_GEM_INFO 0x03 #define DRM_MSM_GEM_CPU_PREP 0x04 @@ -351,6 +356,7 @@ struct drm_msm_submitqueue_query { #define DRM_MSM_SUBMITQUEUE_QUERY 0x0C #define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param) +#define DRM_IOCTL_MSM_SET_PARAM DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SET_PARAM, struct drm_msm_param) #define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new) #define DRM_IOCTL_MSM_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_INFO, struct drm_msm_gem_info) #define DRM_IOCTL_MSM_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_GEM_CPU_PREP, struct drm_msm_gem_cpu_prep) diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h index c4a93ce1de48..e6966d187591 100644 --- a/include/video/samsung_fimd.h +++ b/include/video/samsung_fimd.h @@ -476,6 +476,10 @@ * 1111 -none- -none- -none- -none- -none- */ +#define WIN_RGB_ORDER(_win) (0x2020 + ((_win) * 4)) +#define WIN_RGB_ORDER_FORWARD (0 << 11) +#define WIN_RGB_ORDER_REVERSE (1 << 11) + /* FIMD Version 8 register offset definitions */ #define FIMD_V8_VIDTCON0 0x20010 #define FIMD_V8_VIDTCON1 0x20014 |