Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm-misc-next-2020-07-16' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for v5.9:

UAPI Changes:

Cross-subsystem Changes:
- Add ckoenig as dma-buf maintainer.
- Revert invalid fix for dma-fence-chain, and fix selftest.
- Add fixmes to amifb about APUS support.
- Use array3_size in fbcon_prepare_logo, and struct_size() in alloc_apertures.
- Fix leaks in neofb, fb/savage and omapfb.
- Other small fixes to fb code.
- Convert some dt bindings to schema for some panels, and fix simple-framebuffer dt example.

Core Changes:
- Add DRM_FORMAT_MOD_GENERIC_16_16_TILE as alias to DRM_FORMAT_MOD_SAMSUNG_16_16_TILE,
as it can be used more generic.
- Add support for multiple DispID extension blocks in edid.
- Use https instead of http for some of the urls.
- Use drm_* macros for logging in mipi-dsi and fb-helper.
- Further cleanup ttm_mem_reg handling.
- Remove duplicated words in comments.

Driver Changes:
- Use __drm_atomic_helper_crtc_reset in all atomic drivers.
- Add Amlogic Video FBC support to meson and fourcc to core.
- Refactor hisilicon's hibmc_drv_vdac.
- Create a TXP CRTC for vc4.
- Rework cursor support in ast.
- Fix runtime PM in STM.
- Allow bigger cursors in vkms.
- Cleanup sg handling in radeon and amdgpu, and stop creating dummy
gtt nodes with ttm fixed.
- Rework crtc handling in mgag200.
- Miscellaneous small fixes to meson, vgem, bridge/dw-hdmi,
panel/auo,b116xw03, panel/LG LB070WV8, lima, bridge/sil_sii8620,
virtio, tilcdc.

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/8b360d65-f228-9286-d247-3004156a5254@linux.intel.com

+3861 -3811
-10
Documentation/devicetree/bindings/display/brcm,bcm2835-dpi.yaml
··· 45 45 - | 46 46 #include <dt-bindings/clock/bcm2835.h> 47 47 48 - panel: panel { 49 - compatible = "ontat,yx700wv03", "simple-panel"; 50 - 51 - port { 52 - panel_in: endpoint { 53 - remote-endpoint = <&dpi_out>; 54 - }; 55 - }; 56 - }; 57 - 58 48 dpi: dpi@7e208000 { 59 49 compatible = "brcm,bcm2835-dpi"; 60 50 reg = <0x7e208000 0x8c>;
-85
Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
··· 1 - Renesas R-Car LVDS Encoder 2 - ========================== 3 - 4 - These DT bindings describe the LVDS encoder embedded in the Renesas R-Car 5 - Gen2, R-Car Gen3 and RZ/G SoCs. 6 - 7 - Required properties: 8 - 9 - - compatible : Shall contain one of 10 - - "renesas,r8a7743-lvds" for R8A7743 (RZ/G1M) compatible LVDS encoders 11 - - "renesas,r8a7744-lvds" for R8A7744 (RZ/G1N) compatible LVDS encoders 12 - - "renesas,r8a774a1-lvds" for R8A774A1 (RZ/G2M) compatible LVDS encoders 13 - - "renesas,r8a774b1-lvds" for R8A774B1 (RZ/G2N) compatible LVDS encoders 14 - - "renesas,r8a774c0-lvds" for R8A774C0 (RZ/G2E) compatible LVDS encoders 15 - - "renesas,r8a7790-lvds" for R8A7790 (R-Car H2) compatible LVDS encoders 16 - - "renesas,r8a7791-lvds" for R8A7791 (R-Car M2-W) compatible LVDS encoders 17 - - "renesas,r8a7793-lvds" for R8A7793 (R-Car M2-N) compatible LVDS encoders 18 - - "renesas,r8a7795-lvds" for R8A7795 (R-Car H3) compatible LVDS encoders 19 - - "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders 20 - - "renesas,r8a77965-lvds" for R8A77965 (R-Car M3-N) compatible LVDS encoders 21 - - "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders 22 - - "renesas,r8a77980-lvds" for R8A77980 (R-Car V3H) compatible LVDS encoders 23 - - "renesas,r8a77990-lvds" for R8A77990 (R-Car E3) compatible LVDS encoders 24 - - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders 25 - 26 - - reg: Base address and length for the memory-mapped registers 27 - - clocks: A list of phandles + clock-specifier pairs, one for each entry in 28 - the clock-names property. 29 - - clock-names: Name of the clocks. This property is model-dependent. 30 - - The functional clock, which mandatory for all models, shall be listed 31 - first, and shall be named "fck". 32 - - On R8A77990, R8A77995 and R8A774C0, the LVDS encoder can use the EXTAL or 33 - DU_DOTCLKINx clocks. Those clocks are optional. When supplied they must be 34 - named "extal" and "dclkin.x" respectively, with "x" being the DU_DOTCLKIN 35 - numerical index. 36 - - When the clocks property only contains the functional clock, the 37 - clock-names property may be omitted. 38 - - resets: A phandle + reset specifier for the module reset 39 - 40 - Required nodes: 41 - 42 - The LVDS encoder has two video ports. Their connections are modelled using the 43 - OF graph bindings specified in Documentation/devicetree/bindings/graph.txt. 44 - 45 - - Video port 0 corresponds to the parallel RGB input 46 - - Video port 1 corresponds to the LVDS output 47 - 48 - Each port shall have a single endpoint. 49 - 50 - Optional properties: 51 - 52 - - renesas,companion : phandle to the companion LVDS encoder. This property is 53 - mandatory for the first LVDS encoder on D3 and E3 SoCs, and shall point to 54 - the second encoder to be used as a companion in dual-link mode. It shall not 55 - be set for any other LVDS encoder. 56 - 57 - 58 - Example: 59 - 60 - lvds0: lvds@feb90000 { 61 - compatible = "renesas,r8a77990-lvds"; 62 - reg = <0 0xfeb90000 0 0x20>; 63 - clocks = <&cpg CPG_MOD 727>; 64 - power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; 65 - resets = <&cpg 727>; 66 - 67 - renesas,companion = <&lvds1>; 68 - 69 - ports { 70 - #address-cells = <1>; 71 - #size-cells = <0>; 72 - 73 - port@0 { 74 - reg = <0>; 75 - lvds0_in: endpoint { 76 - remote-endpoint = <&du_out_lvds0>; 77 - }; 78 - }; 79 - port@1 { 80 - reg = <1>; 81 - lvds0_out: endpoint { 82 - }; 83 - }; 84 - }; 85 - };
+248
Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/bridge/renesas,lvds.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Renesas R-Car LVDS Encoder 8 + 9 + maintainers: 10 + - Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> 11 + 12 + description: | 13 + These DT bindings describe the LVDS encoder embedded in the Renesas R-Car 14 + Gen2, R-Car Gen3, RZ/G1 and RZ/G2 SoCs. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - renesas,r8a7743-lvds # for RZ/G1M compatible LVDS encoders 20 + - renesas,r8a7744-lvds # for RZ/G1N compatible LVDS encoders 21 + - renesas,r8a774a1-lvds # for RZ/G2M compatible LVDS encoders 22 + - renesas,r8a774b1-lvds # for RZ/G2N compatible LVDS encoders 23 + - renesas,r8a774c0-lvds # for RZ/G2E compatible LVDS encoders 24 + - renesas,r8a7790-lvds # for R-Car H2 compatible LVDS encoders 25 + - renesas,r8a7791-lvds # for R-Car M2-W compatible LVDS encoders 26 + - renesas,r8a7793-lvds # for R-Car M2-N compatible LVDS encoders 27 + - renesas,r8a7795-lvds # for R-Car H3 compatible LVDS encoders 28 + - renesas,r8a7796-lvds # for R-Car M3-W compatible LVDS encoders 29 + - renesas,r8a77965-lvds # for R-Car M3-N compatible LVDS encoders 30 + - renesas,r8a77970-lvds # for R-Car V3M compatible LVDS encoders 31 + - renesas,r8a77980-lvds # for R-Car V3H compatible LVDS encoders 32 + - renesas,r8a77990-lvds # for R-Car E3 compatible LVDS encoders 33 + - renesas,r8a77995-lvds # for R-Car D3 compatible LVDS encoders 34 + 35 + reg: 36 + maxItems: 1 37 + 38 + clocks: 39 + minItems: 1 40 + maxItems: 4 41 + 42 + clock-names: 43 + minItems: 1 44 + maxItems: 4 45 + 46 + resets: 47 + maxItems: 1 48 + 49 + ports: 50 + type: object 51 + description: | 52 + This device has two video ports. Their connections are modelled using the 53 + OF graph bindings specified in Documentation/devicetree/bindings/graph.txt. 54 + Each port shall have a single endpoint. 55 + 56 + properties: 57 + '#address-cells': 58 + const: 1 59 + 60 + '#size-cells': 61 + const: 0 62 + 63 + port@0: 64 + type: object 65 + description: Parallel RGB input port 66 + 67 + port@1: 68 + type: object 69 + description: LVDS output port 70 + 71 + required: 72 + - port@0 73 + - port@1 74 + 75 + additionalProperties: false 76 + 77 + power-domains: 78 + maxItems: 1 79 + 80 + renesas,companion: 81 + $ref: /schemas/types.yaml#/definitions/phandle 82 + description: 83 + phandle to the companion LVDS encoder. This property is mandatory 84 + for the first LVDS encoder on D3 and E3 SoCs, and shall point to 85 + the second encoder to be used as a companion in dual-link mode. It 86 + shall not be set for any other LVDS encoder. 87 + 88 + required: 89 + - compatible 90 + - reg 91 + - clocks 92 + - power-domains 93 + - resets 94 + - ports 95 + 96 + if: 97 + properties: 98 + compatible: 99 + enum: 100 + - renesas,r8a774c0-lvds 101 + - renesas,r8a77990-lvds 102 + - renesas,r8a77995-lvds 103 + then: 104 + properties: 105 + clocks: 106 + minItems: 1 107 + maxItems: 4 108 + items: 109 + - description: Functional clock 110 + - description: EXTAL input clock 111 + - description: DU_DOTCLKIN0 input clock 112 + - description: DU_DOTCLKIN1 input clock 113 + 114 + clock-names: 115 + minItems: 1 116 + maxItems: 4 117 + items: 118 + - const: fck 119 + # The LVDS encoder can use the EXTAL or DU_DOTCLKINx clocks. 120 + # These clocks are optional. 121 + - enum: 122 + - extal 123 + - dclkin.0 124 + - dclkin.1 125 + - enum: 126 + - extal 127 + - dclkin.0 128 + - dclkin.1 129 + - enum: 130 + - extal 131 + - dclkin.0 132 + - dclkin.1 133 + 134 + required: 135 + - clock-names 136 + 137 + else: 138 + properties: 139 + clocks: 140 + maxItems: 1 141 + items: 142 + - description: Functional clock 143 + 144 + clock-names: 145 + maxItems: 1 146 + items: 147 + - const: fck 148 + 149 + renesas,companion: false 150 + 151 + additionalProperties: false 152 + 153 + examples: 154 + - | 155 + #include <dt-bindings/clock/renesas-cpg-mssr.h> 156 + #include <dt-bindings/power/r8a7795-sysc.h> 157 + 158 + lvds@feb90000 { 159 + compatible = "renesas,r8a7795-lvds"; 160 + reg = <0xfeb90000 0x14>; 161 + clocks = <&cpg CPG_MOD 727>; 162 + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; 163 + resets = <&cpg 727>; 164 + 165 + ports { 166 + #address-cells = <1>; 167 + #size-cells = <0>; 168 + 169 + port@0 { 170 + reg = <0>; 171 + lvds_in: endpoint { 172 + remote-endpoint = <&du_out_lvds0>; 173 + }; 174 + }; 175 + port@1 { 176 + reg = <1>; 177 + lvds_out: endpoint { 178 + remote-endpoint = <&panel_in>; 179 + }; 180 + }; 181 + }; 182 + }; 183 + 184 + - | 185 + #include <dt-bindings/clock/renesas-cpg-mssr.h> 186 + #include <dt-bindings/power/r8a77990-sysc.h> 187 + 188 + lvds0: lvds@feb90000 { 189 + compatible = "renesas,r8a77990-lvds"; 190 + reg = <0xfeb90000 0x20>; 191 + clocks = <&cpg CPG_MOD 727>, 192 + <&x13_clk>, 193 + <&extal_clk>; 194 + clock-names = "fck", "dclkin.0", "extal"; 195 + power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; 196 + resets = <&cpg 727>; 197 + 198 + renesas,companion = <&lvds1>; 199 + 200 + ports { 201 + #address-cells = <1>; 202 + #size-cells = <0>; 203 + 204 + port@0 { 205 + reg = <0>; 206 + lvds0_in: endpoint { 207 + remote-endpoint = <&du_out_lvds0>; 208 + }; 209 + }; 210 + port@1 { 211 + reg = <1>; 212 + lvds0_out: endpoint { 213 + remote-endpoint = <&panel_in1>; 214 + }; 215 + }; 216 + }; 217 + }; 218 + 219 + lvds1: lvds@feb90100 { 220 + compatible = "renesas,r8a77990-lvds"; 221 + reg = <0xfeb90100 0x20>; 222 + clocks = <&cpg CPG_MOD 727>, 223 + <&x13_clk>, 224 + <&extal_clk>; 225 + clock-names = "fck", "dclkin.0", "extal"; 226 + power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; 227 + resets = <&cpg 726>; 228 + 229 + ports { 230 + #address-cells = <1>; 231 + #size-cells = <0>; 232 + 233 + port@0 { 234 + reg = <0>; 235 + lvds1_in: endpoint { 236 + remote-endpoint = <&du_out_lvds1>; 237 + }; 238 + }; 239 + port@1 { 240 + reg = <1>; 241 + lvds1_out: endpoint { 242 + remote-endpoint = <&panel_in2>; 243 + }; 244 + }; 245 + }; 246 + }; 247 + 248 + ...
-31
Documentation/devicetree/bindings/display/connector/analog-tv-connector.txt
··· 1 - Analog TV Connector 2 - =================== 3 - 4 - Required properties: 5 - - compatible: "composite-video-connector" or "svideo-connector" 6 - 7 - Optional properties: 8 - - label: a symbolic name for the connector 9 - - sdtv-standards: limit the supported TV standards on a connector to the given 10 - ones. If not specified all TV standards are allowed. 11 - Possible TV standards are defined in 12 - include/dt-bindings/display/sdtv-standards.h. 13 - 14 - Required nodes: 15 - - Video port for TV input 16 - 17 - Example 18 - ------- 19 - #include <dt-bindings/display/sdtv-standards.h> 20 - 21 - tv: connector { 22 - compatible = "composite-video-connector"; 23 - label = "tv"; 24 - sdtv-standards = <(SDTV_STD_PAL | SDTV_STD_NTSC)>; 25 - 26 - port { 27 - tv_connector_in: endpoint { 28 - remote-endpoint = <&venc_out>; 29 - }; 30 - }; 31 - };
+52
Documentation/devicetree/bindings/display/connector/analog-tv-connector.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/connector/analog-tv-connector.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Analog TV Connector 8 + 9 + maintainers: 10 + - Laurent Pinchart <Laurent.pinchart@ideasonboard.com> 11 + 12 + properties: 13 + compatible: 14 + enum: 15 + - composite-video-connector 16 + - svideo-connector 17 + 18 + label: true 19 + 20 + sdtv-standards: 21 + description: 22 + Limit the supported TV standards on a connector to the given ones. If 23 + not specified all TV standards are allowed. Possible TV standards are 24 + defined in include/dt-bindings/display/sdtv-standards.h. 25 + $ref: /schemas/types.yaml#/definitions/uint32 26 + 27 + port: 28 + description: Connection to controller providing analog TV signals 29 + 30 + required: 31 + - compatible 32 + - port 33 + 34 + additionalProperties: false 35 + 36 + examples: 37 + - | 38 + #include <dt-bindings/display/sdtv-standards.h> 39 + 40 + connector { 41 + compatible = "composite-video-connector"; 42 + label = "tv"; 43 + sdtv-standards = <(SDTV_STD_PAL | SDTV_STD_NTSC)>; 44 + 45 + port { 46 + tv_connector_in: endpoint { 47 + remote-endpoint = <&venc_out>; 48 + }; 49 + }; 50 + }; 51 + 52 + ...
-36
Documentation/devicetree/bindings/display/connector/dvi-connector.txt
··· 1 - DVI Connector 2 - ============== 3 - 4 - Required properties: 5 - - compatible: "dvi-connector" 6 - 7 - Optional properties: 8 - - label: a symbolic name for the connector 9 - - ddc-i2c-bus: phandle to the i2c bus that is connected to DVI DDC 10 - - analog: the connector has DVI analog pins 11 - - digital: the connector has DVI digital pins 12 - - dual-link: the connector has pins for DVI dual-link 13 - - hpd-gpios: HPD GPIO number 14 - 15 - Required nodes: 16 - - Video port for DVI input 17 - 18 - Note: One (or both) of 'analog' or 'digital' must be set. 19 - 20 - Example 21 - ------- 22 - 23 - dvi0: connector@0 { 24 - compatible = "dvi-connector"; 25 - label = "dvi"; 26 - 27 - digital; 28 - 29 - ddc-i2c-bus = <&i2c3>; 30 - 31 - port { 32 - dvi_connector_in: endpoint { 33 - remote-endpoint = <&tfp410_out>; 34 - }; 35 - }; 36 - };
+70
Documentation/devicetree/bindings/display/connector/dvi-connector.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/connector/dvi-connector.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: DVI Connector 8 + 9 + maintainers: 10 + - Laurent Pinchart <Laurent.pinchart@ideasonboard.com> 11 + 12 + properties: 13 + compatible: 14 + const: dvi-connector 15 + 16 + label: true 17 + 18 + hpd-gpios: 19 + description: A GPIO line connected to HPD 20 + maxItems: 1 21 + 22 + ddc-i2c-bus: 23 + description: phandle link to the I2C controller used for DDC EDID probing 24 + $ref: /schemas/types.yaml#/definitions/phandle 25 + 26 + analog: 27 + type: boolean 28 + description: the connector has DVI analog pins 29 + 30 + digital: 31 + type: boolean 32 + description: the connector has DVI digital pins 33 + 34 + dual-link: 35 + type: boolean 36 + description: the connector has pins for DVI dual-link 37 + 38 + port: 39 + description: Connection to controller providing DVI signals 40 + 41 + required: 42 + - compatible 43 + - port 44 + 45 + anyOf: 46 + - required: 47 + - analog 48 + - required: 49 + - digital 50 + 51 + additionalProperties: false 52 + 53 + examples: 54 + - | 55 + connector { 56 + compatible = "dvi-connector"; 57 + label = "dvi"; 58 + 59 + digital; 60 + 61 + ddc-i2c-bus = <&i2c3>; 62 + 63 + port { 64 + dvi_connector_in: endpoint { 65 + remote-endpoint = <&tfp410_out>; 66 + }; 67 + }; 68 + }; 69 + 70 + ...
-31
Documentation/devicetree/bindings/display/connector/hdmi-connector.txt
··· 1 - HDMI Connector 2 - ============== 3 - 4 - Required properties: 5 - - compatible: "hdmi-connector" 6 - - type: the HDMI connector type: "a", "b", "c", "d" or "e" 7 - 8 - Optional properties: 9 - - label: a symbolic name for the connector 10 - - hpd-gpios: HPD GPIO number 11 - - ddc-i2c-bus: phandle link to the I2C controller used for DDC EDID probing 12 - - ddc-en-gpios: signal to enable DDC bus 13 - 14 - Required nodes: 15 - - Video port for HDMI input 16 - 17 - Example 18 - ------- 19 - 20 - hdmi0: connector@1 { 21 - compatible = "hdmi-connector"; 22 - label = "hdmi"; 23 - 24 - type = "a"; 25 - 26 - port { 27 - hdmi_connector_in: endpoint { 28 - remote-endpoint = <&tpd12s015_out>; 29 - }; 30 - }; 31 - };
+64
Documentation/devicetree/bindings/display/connector/hdmi-connector.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/connector/hdmi-connector.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: HDMI Connector 8 + 9 + maintainers: 10 + - Laurent Pinchart <Laurent.pinchart@ideasonboard.com> 11 + 12 + properties: 13 + compatible: 14 + const: hdmi-connector 15 + 16 + type: 17 + description: The HDMI connector type 18 + enum: 19 + - a # Standard full size 20 + - b # Never deployed? 21 + - c # Mini 22 + - d # Micro 23 + - e # automotive 24 + 25 + label: true 26 + 27 + hpd-gpios: 28 + description: A GPIO line connected to HPD 29 + maxItems: 1 30 + 31 + ddc-i2c-bus: 32 + description: phandle link to the I2C controller used for DDC EDID probing 33 + $ref: /schemas/types.yaml#/definitions/phandle 34 + 35 + ddc-en-gpios: 36 + description: GPIO signal to enable DDC bus 37 + maxItems: 1 38 + 39 + port: 40 + description: Connection to controller providing HDMI signals 41 + 42 + required: 43 + - compatible 44 + - port 45 + - type 46 + 47 + additionalProperties: false 48 + 49 + examples: 50 + - | 51 + connector { 52 + compatible = "hdmi-connector"; 53 + label = "hdmi"; 54 + 55 + type = "a"; 56 + 57 + port { 58 + hdmi_connector_in: endpoint { 59 + remote-endpoint = <&tpd12s015_out>; 60 + }; 61 + }; 62 + }; 63 + 64 + ...
-36
Documentation/devicetree/bindings/display/connector/vga-connector.txt
··· 1 - VGA Connector 2 - ============= 3 - 4 - Required properties: 5 - 6 - - compatible: "vga-connector" 7 - 8 - Optional properties: 9 - 10 - - label: a symbolic name for the connector corresponding to a hardware label 11 - - ddc-i2c-bus: phandle to the I2C bus that is connected to VGA DDC 12 - 13 - Required nodes: 14 - 15 - The VGA connector internal connections are modeled using the OF graph bindings 16 - specified in Documentation/devicetree/bindings/graph.txt. 17 - 18 - The VGA connector has a single port that must be connected to a video source 19 - port. 20 - 21 - 22 - Example 23 - ------- 24 - 25 - vga0: connector@0 { 26 - compatible = "vga-connector"; 27 - label = "vga"; 28 - 29 - ddc-i2c-bus = <&i2c3>; 30 - 31 - port { 32 - vga_connector_in: endpoint { 33 - remote-endpoint = <&adv7123_out>; 34 - }; 35 - }; 36 - };
+46
Documentation/devicetree/bindings/display/connector/vga-connector.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/connector/vga-connector.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: VGA Connector 8 + 9 + maintainers: 10 + - Laurent Pinchart <Laurent.pinchart@ideasonboard.com> 11 + 12 + properties: 13 + compatible: 14 + const: vga-connector 15 + 16 + label: true 17 + 18 + ddc-i2c-bus: 19 + description: phandle link to the I2C controller used for DDC EDID probing 20 + $ref: /schemas/types.yaml#/definitions/phandle 21 + 22 + port: 23 + description: Connection to controller providing VGA signals 24 + 25 + required: 26 + - compatible 27 + - port 28 + 29 + additionalProperties: false 30 + 31 + examples: 32 + - | 33 + connector { 34 + compatible = "vga-connector"; 35 + label = "vga"; 36 + 37 + ddc-i2c-bus = <&i2c3>; 38 + 39 + port { 40 + vga_connector_in: endpoint { 41 + remote-endpoint = <&adv7123_out>; 42 + }; 43 + }; 44 + }; 45 + 46 + ...
-22
Documentation/devicetree/bindings/display/panel/innolux,p079zca.txt
··· 1 - Innolux P079ZCA 7.85" 768x1024 TFT LCD panel 2 - 3 - Required properties: 4 - - compatible: should be "innolux,p079zca" 5 - - reg: DSI virtual channel of the peripheral 6 - - power-supply: phandle of the regulator that provides the supply voltage 7 - - enable-gpios: panel enable gpio 8 - 9 - Optional properties: 10 - - backlight: phandle of the backlight device attached to the panel 11 - 12 - Example: 13 - 14 - &mipi_dsi { 15 - panel@0 { 16 - compatible = "innolux,p079zca"; 17 - reg = <0>; 18 - power-supply = <...>; 19 - backlight = <&backlight>; 20 - enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; 21 - }; 22 - };
+2
Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml
··· 33 33 - auo,b080uan01 34 34 # Boe Corporation 8.0" WUXGA TFT LCD panel 35 35 - boe,tv080wum-nl0 36 + # Innolux P079ZCA 7.85" 768x1024 TFT LCD panel 37 + - innolux,p079zca 36 38 # Kingdisplay KD097D04 9.7" 1536x2048 TFT LCD panel 37 39 - kingdisplay,kd097d04 38 40 # LG ACX467AKM-7 4.95" 1080×1920 LCD Panel
-23
Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.txt
··· 1 - Rocktech jh057n00900 5.5" 720x1440 TFT LCD panel 2 - 3 - Required properties: 4 - - compatible: should be "rocktech,jh057n00900" 5 - - reg: DSI virtual channel of the peripheral 6 - - reset-gpios: panel reset gpio 7 - - backlight: phandle of the backlight device attached to the panel 8 - - vcc-supply: phandle of the regulator that provides the vcc supply voltage. 9 - - iovcc-supply: phandle of the regulator that provides the iovcc supply 10 - voltage. 11 - 12 - Example: 13 - 14 - &mipi_dsi { 15 - panel@0 { 16 - compatible = "rocktech,jh057n00900"; 17 - reg = <0>; 18 - backlight = <&backlight>; 19 - reset-gpios = <&gpio3 13 GPIO_ACTIVE_LOW>; 20 - vcc-supply = <&reg_2v8_p>; 21 - iovcc-supply = <&reg_1v8_p>; 22 - }; 23 - };
+70
Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/panel/rocktech,jh057n00900.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel 8 + 9 + maintainers: 10 + - Ondrej Jirman <megi@xff.cz> 11 + 12 + description: | 13 + Rocktech JH057N00900 is a 720x1440 TFT LCD panel 14 + connected using a MIPI-DSI video interface. 15 + 16 + allOf: 17 + - $ref: panel-common.yaml# 18 + 19 + properties: 20 + compatible: 21 + enum: 22 + # Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel 23 + - rocktech,jh057n00900 24 + # Xingbangda XBD599 5.99" 720x1440 TFT LCD panel 25 + - xingbangda,xbd599 26 + 27 + reg: 28 + maxItems: 1 29 + description: DSI virtual channel 30 + 31 + vcc-supply: 32 + description: Panel power supply 33 + 34 + iovcc-supply: 35 + description: I/O voltage supply 36 + 37 + reset-gpios: 38 + description: GPIO used for the reset pin 39 + maxItems: 1 40 + 41 + backlight: 42 + description: Backlight used by the panel 43 + $ref: "/schemas/types.yaml#/definitions/phandle" 44 + 45 + required: 46 + - compatible 47 + - reg 48 + - vcc-supply 49 + - iovcc-supply 50 + - reset-gpios 51 + 52 + additionalProperties: false 53 + 54 + examples: 55 + - | 56 + #include <dt-bindings/gpio/gpio.h> 57 + 58 + dsi { 59 + #address-cells = <1>; 60 + #size-cells = <0>; 61 + panel@0 { 62 + compatible = "rocktech,jh057n00900"; 63 + reg = <0>; 64 + vcc-supply = <&reg_2v8_p>; 65 + iovcc-supply = <&reg_1v8_p>; 66 + reset-gpios = <&gpio3 13 GPIO_ACTIVE_LOW>; 67 + backlight = <&backlight>; 68 + }; 69 + }; 70 + ...
-56
Documentation/devicetree/bindings/display/panel/samsung,s6e8aa0.txt
··· 1 - Samsung S6E8AA0 AMOLED LCD 5.3 inch panel 2 - 3 - Required properties: 4 - - compatible: "samsung,s6e8aa0" 5 - - reg: the virtual channel number of a DSI peripheral 6 - - vdd3-supply: core voltage supply 7 - - vci-supply: voltage supply for analog circuits 8 - - reset-gpios: a GPIO spec for the reset pin 9 - - display-timings: timings for the connected panel as described by [1] 10 - 11 - Optional properties: 12 - - power-on-delay: delay after turning regulators on [ms] 13 - - reset-delay: delay after reset sequence [ms] 14 - - init-delay: delay after initialization sequence [ms] 15 - - panel-width-mm: physical panel width [mm] 16 - - panel-height-mm: physical panel height [mm] 17 - - flip-horizontal: boolean to flip image horizontally 18 - - flip-vertical: boolean to flip image vertically 19 - 20 - The device node can contain one 'port' child node with one child 21 - 'endpoint' node, according to the bindings defined in [2]. This 22 - node should describe panel's video bus. 23 - 24 - [1]: Documentation/devicetree/bindings/display/panel/display-timing.txt 25 - [2]: Documentation/devicetree/bindings/media/video-interfaces.txt 26 - 27 - Example: 28 - 29 - panel { 30 - compatible = "samsung,s6e8aa0"; 31 - reg = <0>; 32 - vdd3-supply = <&vcclcd_reg>; 33 - vci-supply = <&vlcd_reg>; 34 - reset-gpios = <&gpy4 5 0>; 35 - power-on-delay= <50>; 36 - reset-delay = <100>; 37 - init-delay = <100>; 38 - panel-width-mm = <58>; 39 - panel-height-mm = <103>; 40 - flip-horizontal; 41 - flip-vertical; 42 - 43 - display-timings { 44 - timing0: timing-0 { 45 - clock-frequency = <57153600>; 46 - hactive = <720>; 47 - vactive = <1280>; 48 - hfront-porch = <5>; 49 - hback-porch = <5>; 50 - hsync-len = <5>; 51 - vfront-porch = <13>; 52 - vback-porch = <1>; 53 - vsync-len = <2>; 54 - }; 55 - }; 56 - };
+100
Documentation/devicetree/bindings/display/panel/samsung,s6e8aa0.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/panel/samsung,s6e8aa0.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Samsung S6E8AA0 AMOLED LCD 5.3 inch panel 8 + 9 + maintainers: 10 + - Andrzej Hajda <a.hajda@samsung.com> 11 + 12 + allOf: 13 + - $ref: panel-common.yaml# 14 + 15 + properties: 16 + compatible: 17 + const: samsung,s6e8aa0 18 + 19 + reg: true 20 + reset-gpios: true 21 + display-timings: true 22 + 23 + vdd3-supply: 24 + description: core voltage supply 25 + 26 + vci-supply: 27 + description: voltage supply for analog circuits 28 + 29 + power-on-delay: 30 + description: delay after turning regulators on [ms] 31 + $ref: /schemas/types.yaml#/definitions/uint32 32 + 33 + reset-delay: 34 + description: delay after reset sequence [ms] 35 + $ref: /schemas/types.yaml#/definitions/uint32 36 + 37 + init-delay: 38 + description: delay after initialization sequence [ms] 39 + 40 + panel-width-mm: 41 + description: physical panel width [mm] 42 + 43 + panel-height-mm: 44 + description: physical panel height [mm] 45 + 46 + flip-horizontal: 47 + description: boolean to flip image horizontally 48 + type: boolean 49 + 50 + flip-vertical: 51 + description: boolean to flip image vertically 52 + type: boolean 53 + 54 + required: 55 + - compatible 56 + - reg 57 + - vdd3-supply 58 + - vci-supply 59 + - reset-gpios 60 + - display-timings 61 + 62 + additionalProperties: false 63 + 64 + examples: 65 + - | 66 + dsi { 67 + #address-cells = <1>; 68 + #size-cells = <0>; 69 + 70 + panel@0 { 71 + compatible = "samsung,s6e8aa0"; 72 + reg = <0>; 73 + vdd3-supply = <&vcclcd_reg>; 74 + vci-supply = <&vlcd_reg>; 75 + reset-gpios = <&gpy4 5 0>; 76 + power-on-delay= <50>; 77 + reset-delay = <100>; 78 + init-delay = <100>; 79 + panel-width-mm = <58>; 80 + panel-height-mm = <103>; 81 + flip-horizontal; 82 + flip-vertical; 83 + 84 + display-timings { 85 + timing0: timing-0 { 86 + clock-frequency = <57153600>; 87 + hactive = <720>; 88 + vactive = <1280>; 89 + hfront-porch = <5>; 90 + hback-porch = <5>; 91 + hsync-len = <5>; 92 + vfront-porch = <13>; 93 + vback-porch = <1>; 94 + vsync-len = <2>; 95 + }; 96 + }; 97 + }; 98 + }; 99 + 100 + ...
-49
Documentation/devicetree/bindings/display/panel/sharp,lq101r1sx01.txt
··· 1 - Sharp Microelectronics 10.1" WQXGA TFT LCD panel 2 - 3 - This panel requires a dual-channel DSI host to operate. It supports two modes: 4 - - left-right: each channel drives the left or right half of the screen 5 - - even-odd: each channel drives the even or odd lines of the screen 6 - 7 - Each of the DSI channels controls a separate DSI peripheral. The peripheral 8 - driven by the first link (DSI-LINK1), left or even, is considered the primary 9 - peripheral and controls the device. The 'link2' property contains a phandle 10 - to the peripheral driven by the second link (DSI-LINK2, right or odd). 11 - 12 - Note that in video mode the DSI-LINK1 interface always provides the left/even 13 - pixels and DSI-LINK2 always provides the right/odd pixels. In command mode it 14 - is possible to program either link to drive the left/even or right/odd pixels 15 - but for the sake of consistency this binding assumes that the same assignment 16 - is chosen as for video mode. 17 - 18 - Required properties: 19 - - compatible: should be "sharp,lq101r1sx01" 20 - - reg: DSI virtual channel of the peripheral 21 - 22 - Required properties (for DSI-LINK1 only): 23 - - link2: phandle to the DSI peripheral on the secondary link. Note that the 24 - presence of this property marks the containing node as DSI-LINK1. 25 - - power-supply: phandle of the regulator that provides the supply voltage 26 - 27 - Optional properties (for DSI-LINK1 only): 28 - - backlight: phandle of the backlight device attached to the panel 29 - 30 - Example: 31 - 32 - dsi@54300000 { 33 - panel: panel@0 { 34 - compatible = "sharp,lq101r1sx01"; 35 - reg = <0>; 36 - 37 - link2 = <&secondary>; 38 - 39 - power-supply = <...>; 40 - backlight = <...>; 41 - }; 42 - }; 43 - 44 - dsi@54400000 { 45 - secondary: panel@0 { 46 - compatible = "sharp,lq101r1sx01"; 47 - reg = <0>; 48 - }; 49 - };
+87
Documentation/devicetree/bindings/display/panel/sharp,lq101r1sx01.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/panel/sharp,lq101r1sx01.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Sharp Microelectronics 10.1" WQXGA TFT LCD panel 8 + 9 + maintainers: 10 + - Thierry Reding <treding@nvidia.com> 11 + 12 + description: | 13 + This panel requires a dual-channel DSI host to operate. It supports two modes: 14 + - left-right: each channel drives the left or right half of the screen 15 + - even-odd: each channel drives the even or odd lines of the screen 16 + 17 + Each of the DSI channels controls a separate DSI peripheral. The peripheral 18 + driven by the first link (DSI-LINK1), left or even, is considered the primary 19 + peripheral and controls the device. The 'link2' property contains a phandle 20 + to the peripheral driven by the second link (DSI-LINK2, right or odd). 21 + 22 + Note that in video mode the DSI-LINK1 interface always provides the left/even 23 + pixels and DSI-LINK2 always provides the right/odd pixels. In command mode it 24 + is possible to program either link to drive the left/even or right/odd pixels 25 + but for the sake of consistency this binding assumes that the same assignment 26 + is chosen as for video mode. 27 + 28 + allOf: 29 + - $ref: panel-common.yaml# 30 + 31 + properties: 32 + compatible: 33 + const: sharp,lq101r1sx01 34 + 35 + reg: true 36 + power-supply: true 37 + backlight: true 38 + 39 + link2: 40 + $ref: /schemas/types.yaml#/definitions/phandle 41 + description: | 42 + phandle to the DSI peripheral on the secondary link. Note that the 43 + presence of this property marks the containing node as DSI-LINK1 44 + 45 + required: 46 + - compatible 47 + - reg 48 + 49 + if: 50 + required: 51 + - link2 52 + then: 53 + required: 54 + - power-supply 55 + 56 + additionalProperties: false 57 + 58 + examples: 59 + - | 60 + dsi0: dsi@fd922800 { 61 + #address-cells = <1>; 62 + #size-cells = <0>; 63 + reg = <0xfd922800 0x200>; 64 + 65 + panel: panel@0 { 66 + compatible = "sharp,lq101r1sx01"; 67 + reg = <0>; 68 + 69 + link2 = <&secondary>; 70 + 71 + power-supply = <&power>; 72 + backlight = <&backlight>; 73 + }; 74 + }; 75 + 76 + dsi1: dsi@fd922a00 { 77 + #address-cells = <1>; 78 + #size-cells = <0>; 79 + reg = <0xfd922a00 0x200>; 80 + 81 + secondary: panel@0 { 82 + compatible = "sharp,lq101r1sx01"; 83 + reg = <0>; 84 + }; 85 + }; 86 + 87 + ...
+21 -21
Documentation/devicetree/bindings/display/simple-framebuffer.yaml
··· 152 152 153 153 examples: 154 154 - | 155 - aliases { 156 - display0 = &lcdc0; 157 - }; 155 + / { 156 + compatible = "foo"; 157 + model = "foo"; 158 + #address-cells = <1>; 159 + #size-cells = <1>; 158 160 159 - chosen { 160 - #address-cells = <1>; 161 - #size-cells = <1>; 162 - stdout-path = "display0"; 163 - framebuffer0: framebuffer@1d385000 { 164 - compatible = "allwinner,simple-framebuffer", "simple-framebuffer"; 165 - allwinner,pipeline = "de_be0-lcd0"; 166 - reg = <0x1d385000 3840000>; 167 - width = <1600>; 168 - height = <1200>; 169 - stride = <3200>; 170 - format = "r5g6b5"; 171 - clocks = <&ahb_gates 36>, <&ahb_gates 43>, <&ahb_gates 44>; 172 - lcd-supply = <&reg_dc1sw>; 173 - display = <&lcdc0>; 174 - }; 161 + chosen { 162 + #address-cells = <1>; 163 + #size-cells = <1>; 164 + framebuffer0: framebuffer@1d385000 { 165 + compatible = "allwinner,simple-framebuffer", "simple-framebuffer"; 166 + allwinner,pipeline = "de_be0-lcd0"; 167 + reg = <0x1d385000 3840000>; 168 + width = <1600>; 169 + height = <1200>; 170 + stride = <3200>; 171 + format = "r5g6b5"; 172 + clocks = <&ahb_gates 36>, <&ahb_gates 43>, <&ahb_gates 44>; 173 + lcd-supply = <&reg_dc1sw>; 174 + display = <&lcdc0>; 175 + }; 176 + }; 175 177 }; 176 - 177 - lcdc0: lcdc { }; 178 178 179 179 ...
+2
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 1157 1157 description: Xiaomi Technology Co., Ltd. 1158 1158 "^xillybus,.*": 1159 1159 description: Xillybus Ltd. 1160 + "^xingbangda,.*": 1161 + description: Shenzhen Xingbangda Display Technology Co., Ltd 1160 1162 "^xinpeng,.*": 1161 1163 description: Shenzhen Xinpeng Technology Co., Ltd 1162 1164 "^xlnx,.*":
+1 -5
MAINTAINERS
··· 1448 1448 F: drivers/amba/ 1449 1449 F: include/linux/amba/bus.h 1450 1450 1451 - ARM PRIMECELL CLCD PL110 DRIVER 1452 - M: Russell King <linux@armlinux.org.uk> 1453 - S: Odd Fixes 1454 - F: drivers/video/fbdev/amba-clcd.* 1455 - 1456 1451 ARM PRIMECELL KMI PL050 DRIVER 1457 1452 M: Russell King <linux@armlinux.org.uk> 1458 1453 S: Odd Fixes ··· 5089 5094 5090 5095 DMA BUFFER SHARING FRAMEWORK 5091 5096 M: Sumit Semwal <sumit.semwal@linaro.org> 5097 + M: Christian König <christian.koenig@amd.com> 5092 5098 L: linux-media@vger.kernel.org 5093 5099 L: dri-devel@lists.freedesktop.org 5094 5100 L: linaro-mm-sig@lists.linaro.org (moderated for non-subscribers)
-7
drivers/dma-buf/dma-fence-chain.c
··· 99 99 return -EINVAL; 100 100 101 101 dma_fence_chain_for_each(*pfence, &chain->base) { 102 - if ((*pfence)->seqno < seqno) { /* already signaled */ 103 - dma_fence_put(*pfence); 104 - *pfence = NULL; 105 - break; 106 - } 107 - 108 102 if ((*pfence)->context != chain->base.context || 109 103 to_dma_fence_chain(*pfence)->prev_seqno < seqno) 110 104 break; ··· 222 228 * @chain: the chain node to initialize 223 229 * @prev: the previous fence 224 230 * @fence: the current fence 225 - * @seqno: the sequence number (syncpt) of the fence within the chain 226 231 * 227 232 * Initialize a new chain node and either start a new chain or add the node to 228 233 * the existing chain of the previous fence.
+21 -22
drivers/dma-buf/st-dma-fence-chain.c
··· 318 318 goto err; 319 319 } 320 320 321 - if (fence && fence != fc.chains[1]) { 321 + /* 322 + * We signaled the middle fence (2) of the 1-2-3 chain. The behavior 323 + * of the dma-fence-chain is to make us wait for all the fences up to 324 + * the point we want. Since fence 1 is still not signaled, this what 325 + * we should get as fence to wait upon (fence 2 being garbage 326 + * collected during the traversal of the chain). 327 + */ 328 + if (fence != fc.chains[0]) { 322 329 pr_err("Incorrect chain-fence.seqno:%lld reported for completed seqno:2\n", 323 - fence->seqno); 324 - 325 - dma_fence_get(fence); 326 - err = dma_fence_chain_find_seqno(&fence, 2); 327 - dma_fence_put(fence); 328 - if (err) 329 - pr_err("Reported %d for finding self!\n", err); 330 + fence ? fence->seqno : 0); 330 331 331 332 err = -EINVAL; 332 333 } ··· 416 415 if (!fence) 417 416 goto signal; 418 417 419 - err = dma_fence_chain_find_seqno(&fence, seqno); 420 - if (err) { 421 - pr_err("Reported an invalid fence for find-self:%d\n", 422 - seqno); 423 - dma_fence_put(fence); 424 - break; 425 - } 426 - 427 - if (fence->seqno < seqno) { 428 - pr_err("Reported an earlier fence.seqno:%lld for seqno:%d\n", 429 - fence->seqno, seqno); 430 - err = -EINVAL; 431 - dma_fence_put(fence); 432 - break; 418 + /* 419 + * We can only find ourselves if we are on fence we were 420 + * looking for. 421 + */ 422 + if (fence->seqno == seqno) { 423 + err = dma_fence_chain_find_seqno(&fence, seqno); 424 + if (err) { 425 + pr_err("Reported an invalid fence for find-self:%d\n", 426 + seqno); 427 + dma_fence_put(fence); 428 + break; 429 + } 433 430 } 434 431 435 432 dma_fence_put(fence);
+3 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
··· 307 307 if (IS_ERR(sgt)) 308 308 return sgt; 309 309 310 - if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, 311 - DMA_ATTR_SKIP_CPU_SYNC)) 310 + if (dma_map_sgtable(attach->dev, sgt, dir, 311 + DMA_ATTR_SKIP_CPU_SYNC)) 312 312 goto error_free; 313 313 break; 314 314 ··· 349 349 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 350 350 351 351 if (sgt->sgl->page_link) { 352 - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); 352 + dma_unmap_sgtable(attach->dev, sgt, dir, 0); 353 353 sg_free_table(sgt); 354 354 kfree(sgt); 355 355 } else {
+29 -78
drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
··· 150 150 */ 151 151 bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_mem_reg *mem) 152 152 { 153 - struct amdgpu_gtt_node *node = mem->mm_node; 154 - 155 - return (node->node.start != AMDGPU_BO_INVALID_OFFSET); 156 - } 157 - 158 - /** 159 - * amdgpu_gtt_mgr_alloc - allocate new ranges 160 - * 161 - * @man: TTM memory type manager 162 - * @tbo: TTM BO we need this range for 163 - * @place: placement flags and restrictions 164 - * @mem: the resulting mem object 165 - * 166 - * Allocate the address space for a node. 167 - */ 168 - static int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man, 169 - struct ttm_buffer_object *tbo, 170 - const struct ttm_place *place, 171 - struct ttm_mem_reg *mem) 172 - { 173 - struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev); 174 - struct amdgpu_gtt_mgr *mgr = man->priv; 175 - struct amdgpu_gtt_node *node = mem->mm_node; 176 - enum drm_mm_insert_mode mode; 177 - unsigned long fpfn, lpfn; 178 - int r; 179 - 180 - if (amdgpu_gtt_mgr_has_gart_addr(mem)) 181 - return 0; 182 - 183 - if (place) 184 - fpfn = place->fpfn; 185 - else 186 - fpfn = 0; 187 - 188 - if (place && place->lpfn) 189 - lpfn = place->lpfn; 190 - else 191 - lpfn = adev->gart.num_cpu_pages; 192 - 193 - mode = DRM_MM_INSERT_BEST; 194 - if (place && place->flags & TTM_PL_FLAG_TOPDOWN) 195 - mode = DRM_MM_INSERT_HIGH; 196 - 197 - spin_lock(&mgr->lock); 198 - r = drm_mm_insert_node_in_range(&mgr->mm, &node->node, mem->num_pages, 199 - mem->page_alignment, 0, fpfn, lpfn, 200 - mode); 201 - spin_unlock(&mgr->lock); 202 - 203 - if (!r) 204 - mem->start = node->node.start; 205 - 206 - return r; 153 + return mem->mm_node != NULL; 207 154 } 208 155 209 156 /** ··· 176 229 if ((&tbo->mem == mem || tbo->mem.mem_type != TTM_PL_TT) && 177 230 atomic64_read(&mgr->available) < mem->num_pages) { 178 231 spin_unlock(&mgr->lock); 179 - return 0; 232 + return -ENOSPC; 180 233 } 181 234 atomic64_sub(mem->num_pages, &mgr->available); 182 235 spin_unlock(&mgr->lock); 236 + 237 + if (!place->lpfn) { 238 + mem->mm_node = NULL; 239 + mem->start = AMDGPU_BO_INVALID_OFFSET; 240 + return 0; 241 + } 183 242 184 243 node = kzalloc(sizeof(*node), GFP_KERNEL); 185 244 if (!node) { ··· 193 240 goto err_out; 194 241 } 195 242 196 - node->node.start = AMDGPU_BO_INVALID_OFFSET; 197 - node->node.size = mem->num_pages; 198 243 node->tbo = tbo; 199 - mem->mm_node = node; 200 244 201 - if (place->fpfn || place->lpfn || place->flags & TTM_PL_FLAG_TOPDOWN) { 202 - r = amdgpu_gtt_mgr_alloc(man, tbo, place, mem); 203 - if (unlikely(r)) { 204 - kfree(node); 205 - mem->mm_node = NULL; 206 - r = 0; 207 - goto err_out; 208 - } 209 - } else { 210 - mem->start = node->node.start; 211 - } 245 + spin_lock(&mgr->lock); 246 + r = drm_mm_insert_node_in_range(&mgr->mm, &node->node, mem->num_pages, 247 + mem->page_alignment, 0, place->fpfn, 248 + place->lpfn, DRM_MM_INSERT_BEST); 249 + spin_unlock(&mgr->lock); 250 + 251 + if (unlikely(r)) 252 + goto err_free; 253 + 254 + mem->mm_node = node; 255 + mem->start = node->node.start; 212 256 213 257 return 0; 258 + 259 + err_free: 260 + kfree(node); 261 + 214 262 err_out: 215 263 atomic64_add(mem->num_pages, &mgr->available); 216 264 ··· 232 278 struct amdgpu_gtt_mgr *mgr = man->priv; 233 279 struct amdgpu_gtt_node *node = mem->mm_node; 234 280 235 - if (!node) 236 - return; 237 - 238 - spin_lock(&mgr->lock); 239 - if (node->node.start != AMDGPU_BO_INVALID_OFFSET) 281 + if (node) { 282 + spin_lock(&mgr->lock); 240 283 drm_mm_remove_node(&node->node); 241 - spin_unlock(&mgr->lock); 242 - atomic64_add(mem->num_pages, &mgr->available); 284 + spin_unlock(&mgr->lock); 285 + kfree(node); 286 + } 243 287 244 - kfree(node); 245 - mem->mm_node = NULL; 288 + atomic64_add(mem->num_pages, &mgr->available); 246 289 } 247 290 248 291 /**
+17 -10
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 430 430 } 431 431 432 432 src_offset = src->offset; 433 - src_mm = amdgpu_find_mm_node(src->mem, &src_offset); 434 - src_node_size = (src_mm->size << PAGE_SHIFT) - src_offset; 433 + if (src->mem->mm_node) { 434 + src_mm = amdgpu_find_mm_node(src->mem, &src_offset); 435 + src_node_size = (src_mm->size << PAGE_SHIFT) - src_offset; 436 + } else { 437 + src_mm = NULL; 438 + src_node_size = ULLONG_MAX; 439 + } 435 440 436 441 dst_offset = dst->offset; 437 - dst_mm = amdgpu_find_mm_node(dst->mem, &dst_offset); 438 - dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst_offset; 442 + if (dst->mem->mm_node) { 443 + dst_mm = amdgpu_find_mm_node(dst->mem, &dst_offset); 444 + dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst_offset; 445 + } else { 446 + dst_mm = NULL; 447 + dst_node_size = ULLONG_MAX; 448 + } 439 449 440 450 mutex_lock(&adev->mman.gtt_window_lock); 441 451 ··· 1054 1044 { 1055 1045 struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); 1056 1046 struct amdgpu_ttm_tt *gtt = (void *)ttm; 1057 - unsigned nents; 1058 1047 int r; 1059 1048 1060 1049 int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); ··· 1068 1059 goto release_sg; 1069 1060 1070 1061 /* Map SG to device */ 1071 - r = -ENOMEM; 1072 - nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); 1073 - if (nents == 0) 1062 + r = dma_map_sgtable(adev->dev, ttm->sg, direction, 0); 1063 + if (r) 1074 1064 goto release_sg; 1075 1065 1076 1066 /* convert SG to linear array of pages and dma addresses */ ··· 1100 1092 return; 1101 1093 1102 1094 /* unmap the pages mapped to the device */ 1103 - dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); 1104 - 1095 + dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0); 1105 1096 sg_free_table(ttm->sg); 1106 1097 1107 1098 #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
··· 144 144 145 145 src += p->num_dw_left * 4; 146 146 147 - pe += amdgpu_bo_gpu_offset_no_check(bo); 147 + pe += amdgpu_gmc_sign_extend(amdgpu_bo_gpu_offset_no_check(bo)); 148 148 trace_amdgpu_vm_copy_ptes(pe, src, count, p->immediate); 149 149 150 150 amdgpu_vm_copy_pte(p->adev, ib, pe, src, count); ··· 171 171 { 172 172 struct amdgpu_ib *ib = p->job->ibs; 173 173 174 - pe += amdgpu_bo_gpu_offset_no_check(bo); 174 + pe += amdgpu_gmc_sign_extend(amdgpu_bo_gpu_offset_no_check(bo)); 175 175 trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->immediate); 176 176 if (count < 3) { 177 177 amdgpu_vm_write_pte(p->adev, ib, pe, addr | flags,
+6 -7
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
··· 319 319 mem_bytes = (u64)mem->num_pages << PAGE_SHIFT; 320 320 if (atomic64_add_return(mem_bytes, &mgr->usage) > max_bytes) { 321 321 atomic64_sub(mem_bytes, &mgr->usage); 322 - mem->mm_node = NULL; 323 - return 0; 322 + return -ENOSPC; 324 323 } 325 324 326 325 if (place->flags & TTM_PL_FLAG_CONTIGUOUS) { ··· 399 400 atomic64_sub(mem->num_pages << PAGE_SHIFT, &mgr->usage); 400 401 401 402 kvfree(nodes); 402 - return r == -ENOSPC ? 0 : r; 403 + return r; 403 404 } 404 405 405 406 /** ··· 474 475 if (r) 475 476 goto error_free; 476 477 477 - for_each_sg((*sgt)->sgl, sg, num_entries, i) 478 + for_each_sgtable_sg((*sgt), sg, i) 478 479 sg->length = 0; 479 480 480 481 node = mem->mm_node; 481 - for_each_sg((*sgt)->sgl, sg, num_entries, i) { 482 + for_each_sgtable_sg((*sgt), sg, i) { 482 483 phys_addr_t phys = (node->start << PAGE_SHIFT) + 483 484 adev->gmc.aper_base; 484 485 size_t size = node->size << PAGE_SHIFT; ··· 498 499 return 0; 499 500 500 501 error_unmap: 501 - for_each_sg((*sgt)->sgl, sg, num_entries, i) { 502 + for_each_sgtable_sg((*sgt), sg, i) { 502 503 if (!sg->length) 503 504 continue; 504 505 ··· 529 530 struct scatterlist *sg; 530 531 int i; 531 532 532 - for_each_sg(sgt->sgl, sg, sgt->nents, i) 533 + for_each_sgtable_sg(sgt, sg, i) 533 534 dma_unmap_resource(dev, sg->dma_address, 534 535 sg->length, dir, 535 536 DMA_ATTR_SKIP_CPU_SYNC);
+1 -3
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 4614 4614 if (WARN_ON(!state)) 4615 4615 return; 4616 4616 4617 - crtc->state = &state->base; 4618 - crtc->state->crtc = crtc; 4619 - 4617 + __drm_atomic_helper_crtc_reset(crtc, &state->base); 4620 4618 } 4621 4619 4622 4620 static struct drm_crtc_state *
+2 -5
drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
··· 492 492 crtc->state = NULL; 493 493 494 494 state = kzalloc(sizeof(*state), GFP_KERNEL); 495 - if (state) { 496 - crtc->state = &state->base; 497 - crtc->state->crtc = crtc; 498 - } 495 + if (state) 496 + __drm_atomic_helper_crtc_reset(crtc, &state->base); 499 497 } 500 498 501 499 static struct drm_crtc_state * ··· 614 616 return err; 615 617 616 618 drm_crtc_helper_add(crtc, &komeda_crtc_helper_funcs); 617 - drm_crtc_vblank_reset(crtc); 618 619 619 620 crtc->port = kcrtc->master->of_output_port; 620 621
-1
drivers/gpu/drm/arm/malidp_drv.c
··· 848 848 drm->irq_enabled = true; 849 849 850 850 ret = drm_vblank_init(drm, drm->mode_config.num_crtc); 851 - drm_crtc_vblank_reset(&malidp->crtc); 852 851 if (ret < 0) { 853 852 DRM_ERROR("failed to initialise vblank\n"); 854 853 goto vblank_fail;
+2 -1
drivers/gpu/drm/ast/Makefile
··· 3 3 # Makefile for the drm device driver. This driver provides support for the 4 4 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 5 5 6 - ast-y := ast_drv.o ast_main.o ast_mode.o ast_ttm.o ast_post.o ast_dp501.o 6 + ast-y := ast_cursor.o ast_drv.o ast_main.o ast_mode.o ast_ttm.o ast_post.o \ 7 + ast_dp501.o 7 8 8 9 obj-$(CONFIG_DRM_AST) := ast.o
+289
drivers/gpu/drm/ast/ast_cursor.c
··· 1 + /* 2 + * Copyright 2012 Red Hat Inc. 3 + * Parts based on xf86-video-ast 4 + * Copyright (c) 2005 ASPEED Technology Inc. 5 + * 6 + * Permission is hereby granted, free of charge, to any person obtaining a 7 + * copy of this software and associated documentation files (the 8 + * "Software"), to deal in the Software without restriction, including 9 + * without limitation the rights to use, copy, modify, merge, publish, 10 + * distribute, sub license, and/or sell copies of the Software, and to 11 + * permit persons to whom the Software is furnished to do so, subject to 12 + * the following conditions: 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 + * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 + * 22 + * The above copyright notice and this permission notice (including the 23 + * next paragraph) shall be included in all copies or substantial portions 24 + * of the Software. 25 + */ 26 + /* 27 + * Authors: Dave Airlie <airlied@redhat.com> 28 + */ 29 + 30 + #include <drm/drm_gem_vram_helper.h> 31 + #include <drm/drm_managed.h> 32 + 33 + #include "ast_drv.h" 34 + 35 + static void ast_cursor_fini(struct ast_private *ast) 36 + { 37 + size_t i; 38 + struct drm_gem_vram_object *gbo; 39 + 40 + for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) { 41 + gbo = ast->cursor.gbo[i]; 42 + drm_gem_vram_vunmap(gbo, ast->cursor.vaddr[i]); 43 + drm_gem_vram_unpin(gbo); 44 + drm_gem_vram_put(gbo); 45 + } 46 + } 47 + 48 + static void ast_cursor_release(struct drm_device *dev, void *ptr) 49 + { 50 + struct ast_private *ast = dev->dev_private; 51 + 52 + ast_cursor_fini(ast); 53 + } 54 + 55 + /* 56 + * Allocate cursor BOs and pins them at the end of VRAM. 57 + */ 58 + int ast_cursor_init(struct ast_private *ast) 59 + { 60 + struct drm_device *dev = ast->dev; 61 + size_t size, i; 62 + struct drm_gem_vram_object *gbo; 63 + void __iomem *vaddr; 64 + int ret; 65 + 66 + size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE); 67 + 68 + for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) { 69 + gbo = drm_gem_vram_create(dev, size, 0); 70 + if (IS_ERR(gbo)) { 71 + ret = PTR_ERR(gbo); 72 + goto err_drm_gem_vram_put; 73 + } 74 + ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM | 75 + DRM_GEM_VRAM_PL_FLAG_TOPDOWN); 76 + if (ret) { 77 + drm_gem_vram_put(gbo); 78 + goto err_drm_gem_vram_put; 79 + } 80 + vaddr = drm_gem_vram_vmap(gbo); 81 + if (IS_ERR(vaddr)) { 82 + ret = PTR_ERR(vaddr); 83 + drm_gem_vram_unpin(gbo); 84 + drm_gem_vram_put(gbo); 85 + goto err_drm_gem_vram_put; 86 + } 87 + 88 + ast->cursor.gbo[i] = gbo; 89 + ast->cursor.vaddr[i] = vaddr; 90 + } 91 + 92 + return drmm_add_action_or_reset(dev, ast_cursor_release, NULL); 93 + 94 + err_drm_gem_vram_put: 95 + while (i) { 96 + --i; 97 + gbo = ast->cursor.gbo[i]; 98 + drm_gem_vram_vunmap(gbo, ast->cursor.vaddr[i]); 99 + drm_gem_vram_unpin(gbo); 100 + drm_gem_vram_put(gbo); 101 + } 102 + return ret; 103 + } 104 + 105 + static void update_cursor_image(u8 __iomem *dst, const u8 *src, int width, int height) 106 + { 107 + union { 108 + u32 ul; 109 + u8 b[4]; 110 + } srcdata32[2], data32; 111 + union { 112 + u16 us; 113 + u8 b[2]; 114 + } data16; 115 + u32 csum = 0; 116 + s32 alpha_dst_delta, last_alpha_dst_delta; 117 + u8 __iomem *dstxor; 118 + const u8 *srcxor; 119 + int i, j; 120 + u32 per_pixel_copy, two_pixel_copy; 121 + 122 + alpha_dst_delta = AST_MAX_HWC_WIDTH << 1; 123 + last_alpha_dst_delta = alpha_dst_delta - (width << 1); 124 + 125 + srcxor = src; 126 + dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta; 127 + per_pixel_copy = width & 1; 128 + two_pixel_copy = width >> 1; 129 + 130 + for (j = 0; j < height; j++) { 131 + for (i = 0; i < two_pixel_copy; i++) { 132 + srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0; 133 + srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0; 134 + data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); 135 + data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); 136 + data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4); 137 + data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4); 138 + 139 + writel(data32.ul, dstxor); 140 + csum += data32.ul; 141 + 142 + dstxor += 4; 143 + srcxor += 8; 144 + 145 + } 146 + 147 + for (i = 0; i < per_pixel_copy; i++) { 148 + srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0; 149 + data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); 150 + data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); 151 + writew(data16.us, dstxor); 152 + csum += (u32)data16.us; 153 + 154 + dstxor += 2; 155 + srcxor += 4; 156 + } 157 + dstxor += last_alpha_dst_delta; 158 + } 159 + 160 + /* write checksum + signature */ 161 + dst += AST_HWC_SIZE; 162 + writel(csum, dst); 163 + writel(width, dst + AST_HWC_SIGNATURE_SizeX); 164 + writel(height, dst + AST_HWC_SIGNATURE_SizeY); 165 + writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX); 166 + writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY); 167 + } 168 + 169 + int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb) 170 + { 171 + struct drm_device *dev = ast->dev; 172 + struct drm_gem_vram_object *gbo; 173 + int ret; 174 + void *src; 175 + void __iomem *dst; 176 + 177 + if (drm_WARN_ON_ONCE(dev, fb->width > AST_MAX_HWC_WIDTH) || 178 + drm_WARN_ON_ONCE(dev, fb->height > AST_MAX_HWC_HEIGHT)) 179 + return -EINVAL; 180 + 181 + gbo = drm_gem_vram_of_gem(fb->obj[0]); 182 + 183 + ret = drm_gem_vram_pin(gbo, 0); 184 + if (ret) 185 + return ret; 186 + src = drm_gem_vram_vmap(gbo); 187 + if (IS_ERR(src)) { 188 + ret = PTR_ERR(src); 189 + goto err_drm_gem_vram_unpin; 190 + } 191 + 192 + dst = ast->cursor.vaddr[ast->cursor.next_index]; 193 + 194 + /* do data transfer to cursor BO */ 195 + update_cursor_image(dst, src, fb->width, fb->height); 196 + 197 + drm_gem_vram_vunmap(gbo, src); 198 + drm_gem_vram_unpin(gbo); 199 + 200 + return 0; 201 + 202 + err_drm_gem_vram_unpin: 203 + drm_gem_vram_unpin(gbo); 204 + return ret; 205 + } 206 + 207 + static void ast_cursor_set_base(struct ast_private *ast, u64 address) 208 + { 209 + u8 addr0 = (address >> 3) & 0xff; 210 + u8 addr1 = (address >> 11) & 0xff; 211 + u8 addr2 = (address >> 19) & 0xff; 212 + 213 + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0); 214 + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1); 215 + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2); 216 + } 217 + 218 + void ast_cursor_page_flip(struct ast_private *ast) 219 + { 220 + struct drm_device *dev = ast->dev; 221 + struct drm_gem_vram_object *gbo; 222 + s64 off; 223 + 224 + gbo = ast->cursor.gbo[ast->cursor.next_index]; 225 + 226 + off = drm_gem_vram_offset(gbo); 227 + if (drm_WARN_ON_ONCE(dev, off < 0)) 228 + return; /* Bug: we didn't pin the cursor HW BO to VRAM. */ 229 + 230 + ast_cursor_set_base(ast, off); 231 + 232 + ++ast->cursor.next_index; 233 + ast->cursor.next_index %= ARRAY_SIZE(ast->cursor.gbo); 234 + } 235 + 236 + static void ast_cursor_set_location(struct ast_private *ast, u16 x, u16 y, 237 + u8 x_offset, u8 y_offset) 238 + { 239 + u8 x0 = (x & 0x00ff); 240 + u8 x1 = (x & 0x0f00) >> 8; 241 + u8 y0 = (y & 0x00ff); 242 + u8 y1 = (y & 0x0700) >> 8; 243 + 244 + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset); 245 + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset); 246 + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0); 247 + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1); 248 + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0); 249 + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1); 250 + } 251 + 252 + void ast_cursor_show(struct ast_private *ast, int x, int y, 253 + unsigned int offset_x, unsigned int offset_y) 254 + { 255 + u8 x_offset, y_offset; 256 + u8 __iomem *dst, __iomem *sig; 257 + u8 jreg; 258 + 259 + dst = ast->cursor.vaddr[ast->cursor.next_index]; 260 + 261 + sig = dst + AST_HWC_SIZE; 262 + writel(x, sig + AST_HWC_SIGNATURE_X); 263 + writel(y, sig + AST_HWC_SIGNATURE_Y); 264 + 265 + if (x < 0) { 266 + x_offset = (-x) + offset_x; 267 + x = 0; 268 + } else { 269 + x_offset = offset_x; 270 + } 271 + if (y < 0) { 272 + y_offset = (-y) + offset_y; 273 + y = 0; 274 + } else { 275 + y_offset = offset_y; 276 + } 277 + 278 + ast_cursor_set_location(ast, x, y, x_offset, y_offset); 279 + 280 + /* dummy write to fire HWC */ 281 + jreg = 0x02 | 282 + 0x01; /* enable ARGB4444 cursor */ 283 + ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg); 284 + } 285 + 286 + void ast_cursor_hide(struct ast_private *ast) 287 + { 288 + ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00); 289 + }
+11 -8
drivers/gpu/drm/ast/ast_drv.h
··· 116 116 117 117 struct { 118 118 struct drm_gem_vram_object *gbo[AST_DEFAULT_HWC_NUM]; 119 + void __iomem *vaddr[AST_DEFAULT_HWC_NUM]; 119 120 unsigned int next_index; 120 121 } cursor; 121 122 ··· 238 237 struct ast_i2c_chan *i2c; 239 238 }; 240 239 241 - struct ast_crtc { 242 - struct drm_crtc base; 243 - u8 offset_x, offset_y; 244 - }; 245 - 246 - #define to_ast_crtc(x) container_of(x, struct ast_crtc, base) 247 240 #define to_ast_connector(x) container_of(x, struct ast_connector, base) 248 241 249 242 struct ast_vbios_stdtable { ··· 286 291 287 292 #define to_ast_crtc_state(state) container_of(state, struct ast_crtc_state, base) 288 293 289 - extern int ast_mode_init(struct drm_device *dev); 290 - extern void ast_mode_fini(struct drm_device *dev); 294 + int ast_mode_config_init(struct ast_private *ast); 291 295 292 296 #define AST_MM_ALIGN_SHIFT 4 293 297 #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1) ··· 308 314 u8 ast_get_dp501_max_clk(struct drm_device *dev); 309 315 void ast_init_3rdtx(struct drm_device *dev); 310 316 void ast_release_firmware(struct drm_device *dev); 317 + 318 + /* ast_cursor.c */ 319 + int ast_cursor_init(struct ast_private *ast); 320 + int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb); 321 + void ast_cursor_page_flip(struct ast_private *ast); 322 + void ast_cursor_show(struct ast_private *ast, int x, int y, 323 + unsigned int offset_x, unsigned int offset_y); 324 + void ast_cursor_hide(struct ast_private *ast); 325 + 311 326 #endif
+1 -34
drivers/gpu/drm/ast/ast_main.c
··· 31 31 #include <drm/drm_atomic_helper.h> 32 32 #include <drm/drm_crtc_helper.h> 33 33 #include <drm/drm_gem.h> 34 - #include <drm/drm_gem_framebuffer_helper.h> 35 34 #include <drm/drm_gem_vram_helper.h> 36 35 37 36 #include "ast_drv.h" ··· 378 379 return 0; 379 380 } 380 381 381 - static const struct drm_mode_config_funcs ast_mode_funcs = { 382 - .fb_create = drm_gem_fb_create, 383 - .mode_valid = drm_vram_helper_mode_valid, 384 - .atomic_check = drm_atomic_helper_check, 385 - .atomic_commit = drm_atomic_helper_commit, 386 - }; 387 - 388 382 static u32 ast_get_vram_info(struct drm_device *dev) 389 383 { 390 384 struct ast_private *ast = to_ast_private(dev); ··· 465 473 if (ret) 466 474 goto out_free; 467 475 468 - drm_mode_config_init(dev); 469 - 470 - dev->mode_config.funcs = (void *)&ast_mode_funcs; 471 - dev->mode_config.min_width = 0; 472 - dev->mode_config.min_height = 0; 473 - dev->mode_config.preferred_depth = 24; 474 - dev->mode_config.prefer_shadow = 1; 475 - dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0); 476 - 477 - if (ast->chip == AST2100 || 478 - ast->chip == AST2200 || 479 - ast->chip == AST2300 || 480 - ast->chip == AST2400 || 481 - ast->chip == AST2500) { 482 - dev->mode_config.max_width = 1920; 483 - dev->mode_config.max_height = 2048; 484 - } else { 485 - dev->mode_config.max_width = 1600; 486 - dev->mode_config.max_height = 1200; 487 - } 488 - 489 - ret = ast_mode_init(dev); 476 + ret = ast_mode_config_init(ast); 490 477 if (ret) 491 478 goto out_free; 492 - 493 - drm_mode_config_reset(dev); 494 479 495 480 return 0; 496 481 out_free: ··· 485 516 486 517 ast_release_firmware(dev); 487 518 kfree(ast->dp501_fw_addr); 488 - ast_mode_fini(dev); 489 - drm_mode_config_cleanup(dev); 490 519 491 520 ast_mm_fini(ast); 492 521 kfree(ast);
+56 -266
drivers/gpu/drm/ast/ast_mode.c
··· 37 37 #include <drm/drm_crtc.h> 38 38 #include <drm/drm_crtc_helper.h> 39 39 #include <drm/drm_fourcc.h> 40 + #include <drm/drm_gem_framebuffer_helper.h> 40 41 #include <drm/drm_gem_vram_helper.h> 41 42 #include <drm/drm_plane_helper.h> 42 43 #include <drm/drm_probe_helper.h> ··· 48 47 49 48 static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev); 50 49 static void ast_i2c_destroy(struct ast_i2c_chan *i2c); 51 - static int ast_cursor_move(struct drm_crtc *crtc, 52 - int x, int y); 53 - 54 - 55 - static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height); 56 - static int ast_cursor_update(void *dst, void *src, unsigned int width, 57 - unsigned int height); 58 - static void ast_cursor_set_base(struct ast_private *ast, u64 address); 59 - static int ast_cursor_move(struct drm_crtc *crtc, 60 - int x, int y); 61 50 62 51 static inline void ast_load_palette_index(struct ast_private *ast, 63 52 u8 index, u8 red, u8 green, ··· 612 621 ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, 613 622 struct drm_plane_state *new_state) 614 623 { 615 - struct drm_device *dev = plane->dev; 616 624 struct drm_framebuffer *fb = new_state->fb; 617 625 struct drm_crtc *crtc = new_state->crtc; 618 - struct drm_gem_vram_object *gbo; 619 626 struct ast_private *ast; 620 627 int ret; 621 - void *src, *dst; 622 628 623 629 if (!crtc || !fb) 624 630 return 0; 625 631 626 - if (drm_WARN_ON_ONCE(dev, fb->width > AST_MAX_HWC_WIDTH) || 627 - drm_WARN_ON_ONCE(dev, fb->height > AST_MAX_HWC_HEIGHT)) 628 - return -EINVAL; /* BUG: didn't test in atomic_check() */ 632 + ast = to_ast_private(plane->dev); 629 633 630 - ast = to_ast_private(dev); 631 - 632 - gbo = drm_gem_vram_of_gem(fb->obj[0]); 633 - src = drm_gem_vram_vmap(gbo); 634 - if (IS_ERR(src)) { 635 - ret = PTR_ERR(src); 636 - goto err_drm_gem_vram_unpin; 637 - } 638 - 639 - dst = drm_gem_vram_vmap(ast->cursor.gbo[ast->cursor.next_index]); 640 - if (IS_ERR(dst)) { 641 - ret = PTR_ERR(dst); 642 - goto err_drm_gem_vram_vunmap_src; 643 - } 644 - 645 - ret = ast_cursor_update(dst, src, fb->width, fb->height); 634 + ret = ast_cursor_blit(ast, fb); 646 635 if (ret) 647 - goto err_drm_gem_vram_vunmap_dst; 648 - 649 - /* Always unmap buffers here. Destination buffers are 650 - * perma-pinned while the driver is active. We're only 651 - * changing ref-counters here. 652 - */ 653 - drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst); 654 - drm_gem_vram_vunmap(gbo, src); 636 + return ret; 655 637 656 638 return 0; 657 - 658 - err_drm_gem_vram_vunmap_dst: 659 - drm_gem_vram_vunmap(ast->cursor.gbo[ast->cursor.next_index], dst); 660 - err_drm_gem_vram_vunmap_src: 661 - drm_gem_vram_vunmap(gbo, src); 662 - err_drm_gem_vram_unpin: 663 - drm_gem_vram_unpin(gbo); 664 - return ret; 665 639 } 666 640 667 641 static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane, ··· 661 705 ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, 662 706 struct drm_plane_state *old_state) 663 707 { 664 - struct drm_device *dev = plane->dev; 665 708 struct drm_plane_state *state = plane->state; 666 - struct drm_crtc *crtc = state->crtc; 667 709 struct drm_framebuffer *fb = state->fb; 668 - struct ast_private *ast = to_ast_private(plane->dev); 669 - struct ast_crtc *ast_crtc = to_ast_crtc(crtc); 670 - struct drm_gem_vram_object *gbo; 671 - s64 off; 672 - u8 jreg; 710 + struct ast_private *ast = plane->dev->dev_private; 711 + unsigned int offset_x, offset_y; 673 712 674 - ast_crtc->offset_x = AST_MAX_HWC_WIDTH - fb->width; 675 - ast_crtc->offset_y = AST_MAX_HWC_WIDTH - fb->height; 713 + offset_x = AST_MAX_HWC_WIDTH - fb->width; 714 + offset_y = AST_MAX_HWC_WIDTH - fb->height; 676 715 677 716 if (state->fb != old_state->fb) { 678 717 /* A new cursor image was installed. */ 679 - gbo = ast->cursor.gbo[ast->cursor.next_index]; 680 - off = drm_gem_vram_offset(gbo); 681 - if (drm_WARN_ON_ONCE(dev, off < 0)) 682 - return; /* Bug: we didn't pin cursor HW BO to VRAM. */ 683 - ast_cursor_set_base(ast, off); 684 - 685 - ++ast->cursor.next_index; 686 - ast->cursor.next_index %= ARRAY_SIZE(ast->cursor.gbo); 718 + ast_cursor_page_flip(ast); 687 719 } 688 720 689 - ast_cursor_move(crtc, state->crtc_x, state->crtc_y); 690 - 691 - jreg = 0x2; 692 - /* enable ARGB cursor */ 693 - jreg |= 1; 694 - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg); 721 + ast_cursor_show(ast, state->crtc_x, state->crtc_y, 722 + offset_x, offset_y); 695 723 } 696 724 697 725 static void ··· 684 744 { 685 745 struct ast_private *ast = to_ast_private(plane->dev); 686 746 687 - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00); 747 + ast_cursor_hide(ast); 688 748 } 689 749 690 750 static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = { ··· 882 942 static int ast_crtc_init(struct drm_device *dev) 883 943 { 884 944 struct ast_private *ast = to_ast_private(dev); 885 - struct ast_crtc *crtc; 945 + struct drm_crtc *crtc; 886 946 int ret; 887 947 888 - crtc = kzalloc(sizeof(struct ast_crtc), GFP_KERNEL); 948 + crtc = kzalloc(sizeof(*crtc), GFP_KERNEL); 889 949 if (!crtc) 890 950 return -ENOMEM; 891 951 892 - ret = drm_crtc_init_with_planes(dev, &crtc->base, &ast->primary_plane, 952 + ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane, 893 953 &ast->cursor_plane, &ast_crtc_funcs, 894 954 NULL); 895 955 if (ret) 896 956 goto err_kfree; 897 957 898 - drm_mode_crtc_set_gamma_size(&crtc->base, 256); 899 - drm_crtc_helper_add(&crtc->base, &ast_crtc_helper_funcs); 958 + drm_mode_crtc_set_gamma_size(crtc, 256); 959 + drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs); 960 + 900 961 return 0; 901 962 902 963 err_kfree: ··· 1070 1129 return 0; 1071 1130 } 1072 1131 1073 - /* allocate cursor cache and pin at start of VRAM */ 1074 - static int ast_cursor_init(struct drm_device *dev) 1132 + /* 1133 + * Mode config 1134 + */ 1135 + 1136 + static const struct drm_mode_config_funcs ast_mode_config_funcs = { 1137 + .fb_create = drm_gem_fb_create, 1138 + .mode_valid = drm_vram_helper_mode_valid, 1139 + .atomic_check = drm_atomic_helper_check, 1140 + .atomic_commit = drm_atomic_helper_commit, 1141 + }; 1142 + 1143 + int ast_mode_config_init(struct ast_private *ast) 1075 1144 { 1076 - struct ast_private *ast = to_ast_private(dev); 1077 - size_t size, i; 1078 - struct drm_gem_vram_object *gbo; 1145 + struct drm_device *dev = ast->dev; 1079 1146 int ret; 1080 1147 1081 - size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE); 1148 + ret = ast_cursor_init(ast); 1149 + if (ret) 1150 + return ret; 1082 1151 1083 - for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) { 1084 - gbo = drm_gem_vram_create(dev, size, 0); 1085 - if (IS_ERR(gbo)) { 1086 - ret = PTR_ERR(gbo); 1087 - goto err_drm_gem_vram_put; 1088 - } 1089 - ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM | 1090 - DRM_GEM_VRAM_PL_FLAG_TOPDOWN); 1091 - if (ret) { 1092 - drm_gem_vram_put(gbo); 1093 - goto err_drm_gem_vram_put; 1094 - } 1152 + ret = drmm_mode_config_init(dev); 1153 + if (ret) 1154 + return ret; 1095 1155 1096 - ast->cursor.gbo[i] = gbo; 1156 + dev->mode_config.funcs = &ast_mode_config_funcs; 1157 + dev->mode_config.min_width = 0; 1158 + dev->mode_config.min_height = 0; 1159 + dev->mode_config.preferred_depth = 24; 1160 + dev->mode_config.prefer_shadow = 1; 1161 + dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0); 1162 + 1163 + if (ast->chip == AST2100 || 1164 + ast->chip == AST2200 || 1165 + ast->chip == AST2300 || 1166 + ast->chip == AST2400 || 1167 + ast->chip == AST2500) { 1168 + dev->mode_config.max_width = 1920; 1169 + dev->mode_config.max_height = 2048; 1170 + } else { 1171 + dev->mode_config.max_width = 1600; 1172 + dev->mode_config.max_height = 1200; 1097 1173 } 1098 - 1099 - return 0; 1100 - 1101 - err_drm_gem_vram_put: 1102 - while (i) { 1103 - --i; 1104 - gbo = ast->cursor.gbo[i]; 1105 - drm_gem_vram_unpin(gbo); 1106 - drm_gem_vram_put(gbo); 1107 - ast->cursor.gbo[i] = NULL; 1108 - } 1109 - return ret; 1110 - } 1111 - 1112 - static void ast_cursor_fini(struct drm_device *dev) 1113 - { 1114 - struct ast_private *ast = to_ast_private(dev); 1115 - size_t i; 1116 - struct drm_gem_vram_object *gbo; 1117 - 1118 - for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) { 1119 - gbo = ast->cursor.gbo[i]; 1120 - drm_gem_vram_unpin(gbo); 1121 - drm_gem_vram_put(gbo); 1122 - } 1123 - } 1124 - 1125 - int ast_mode_init(struct drm_device *dev) 1126 - { 1127 - struct ast_private *ast = to_ast_private(dev); 1128 - int ret; 1129 1174 1130 1175 memset(&ast->primary_plane, 0, sizeof(ast->primary_plane)); 1131 1176 ret = drm_universal_plane_init(dev, &ast->primary_plane, 0x01, ··· 1138 1211 drm_plane_helper_add(&ast->cursor_plane, 1139 1212 &ast_cursor_plane_helper_funcs); 1140 1213 1141 - ast_cursor_init(dev); 1142 1214 ast_crtc_init(dev); 1143 1215 ast_encoder_init(dev); 1144 1216 ast_connector_init(dev); 1145 1217 1146 - return 0; 1147 - } 1218 + drm_mode_config_reset(dev); 1148 1219 1149 - void ast_mode_fini(struct drm_device *dev) 1150 - { 1151 - ast_cursor_fini(dev); 1220 + return 0; 1152 1221 } 1153 1222 1154 1223 static int get_clock(void *i2c_priv) ··· 1266 1343 return; 1267 1344 i2c_del_adapter(&i2c->adapter); 1268 1345 kfree(i2c); 1269 - } 1270 - 1271 - static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height) 1272 - { 1273 - union { 1274 - u32 ul; 1275 - u8 b[4]; 1276 - } srcdata32[2], data32; 1277 - union { 1278 - u16 us; 1279 - u8 b[2]; 1280 - } data16; 1281 - u32 csum = 0; 1282 - s32 alpha_dst_delta, last_alpha_dst_delta; 1283 - u8 *srcxor, *dstxor; 1284 - int i, j; 1285 - u32 per_pixel_copy, two_pixel_copy; 1286 - 1287 - alpha_dst_delta = AST_MAX_HWC_WIDTH << 1; 1288 - last_alpha_dst_delta = alpha_dst_delta - (width << 1); 1289 - 1290 - srcxor = src; 1291 - dstxor = (u8 *)dst + last_alpha_dst_delta + (AST_MAX_HWC_HEIGHT - height) * alpha_dst_delta; 1292 - per_pixel_copy = width & 1; 1293 - two_pixel_copy = width >> 1; 1294 - 1295 - for (j = 0; j < height; j++) { 1296 - for (i = 0; i < two_pixel_copy; i++) { 1297 - srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0; 1298 - srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0; 1299 - data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); 1300 - data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); 1301 - data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4); 1302 - data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4); 1303 - 1304 - writel(data32.ul, dstxor); 1305 - csum += data32.ul; 1306 - 1307 - dstxor += 4; 1308 - srcxor += 8; 1309 - 1310 - } 1311 - 1312 - for (i = 0; i < per_pixel_copy; i++) { 1313 - srcdata32[0].ul = *((u32 *)srcxor) & 0xf0f0f0f0; 1314 - data16.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); 1315 - data16.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); 1316 - writew(data16.us, dstxor); 1317 - csum += (u32)data16.us; 1318 - 1319 - dstxor += 2; 1320 - srcxor += 4; 1321 - } 1322 - dstxor += last_alpha_dst_delta; 1323 - } 1324 - return csum; 1325 - } 1326 - 1327 - static int ast_cursor_update(void *dst, void *src, unsigned int width, 1328 - unsigned int height) 1329 - { 1330 - u32 csum; 1331 - 1332 - /* do data transfer to cursor cache */ 1333 - csum = copy_cursor_image(src, dst, width, height); 1334 - 1335 - /* write checksum + signature */ 1336 - dst += AST_HWC_SIZE; 1337 - writel(csum, dst); 1338 - writel(width, dst + AST_HWC_SIGNATURE_SizeX); 1339 - writel(height, dst + AST_HWC_SIGNATURE_SizeY); 1340 - writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTX); 1341 - writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY); 1342 - 1343 - return 0; 1344 - } 1345 - 1346 - static void ast_cursor_set_base(struct ast_private *ast, u64 address) 1347 - { 1348 - u8 addr0 = (address >> 3) & 0xff; 1349 - u8 addr1 = (address >> 11) & 0xff; 1350 - u8 addr2 = (address >> 19) & 0xff; 1351 - 1352 - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0); 1353 - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1); 1354 - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2); 1355 - } 1356 - 1357 - static int ast_cursor_move(struct drm_crtc *crtc, 1358 - int x, int y) 1359 - { 1360 - struct ast_crtc *ast_crtc = to_ast_crtc(crtc); 1361 - struct ast_private *ast = to_ast_private(crtc->dev); 1362 - struct drm_gem_vram_object *gbo; 1363 - int x_offset, y_offset; 1364 - u8 *dst, *sig; 1365 - u8 jreg; 1366 - 1367 - gbo = ast->cursor.gbo[ast->cursor.next_index]; 1368 - dst = drm_gem_vram_vmap(gbo); 1369 - if (IS_ERR(dst)) 1370 - return PTR_ERR(dst); 1371 - 1372 - sig = dst + AST_HWC_SIZE; 1373 - writel(x, sig + AST_HWC_SIGNATURE_X); 1374 - writel(y, sig + AST_HWC_SIGNATURE_Y); 1375 - 1376 - x_offset = ast_crtc->offset_x; 1377 - y_offset = ast_crtc->offset_y; 1378 - if (x < 0) { 1379 - x_offset = (-x) + ast_crtc->offset_x; 1380 - x = 0; 1381 - } 1382 - 1383 - if (y < 0) { 1384 - y_offset = (-y) + ast_crtc->offset_y; 1385 - y = 0; 1386 - } 1387 - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset); 1388 - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset); 1389 - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, (x & 0xff)); 1390 - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, ((x >> 8) & 0x0f)); 1391 - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, (y & 0xff)); 1392 - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, ((y >> 8) & 0x07)); 1393 - 1394 - /* dummy write to fire HWC */ 1395 - jreg = 0x02 | 1396 - 0x01; /* enable ARGB4444 cursor */ 1397 - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, jreg); 1398 - 1399 - drm_gem_vram_vunmap(gbo, dst); 1400 - 1401 - return 0; 1402 1346 }
+2 -5
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
··· 411 411 } 412 412 413 413 state = kzalloc(sizeof(*state), GFP_KERNEL); 414 - if (state) { 415 - crtc->state = &state->base; 416 - crtc->state->crtc = crtc; 417 - } 414 + if (state) 415 + __drm_atomic_helper_crtc_reset(crtc, &state->base); 418 416 } 419 417 420 418 static struct drm_crtc_state * ··· 526 528 } 527 529 528 530 drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs); 529 - drm_crtc_vblank_reset(&crtc->base); 530 531 531 532 drm_mode_crtc_set_gamma_size(&crtc->base, ATMEL_HLCDC_CLUT_SIZE); 532 533 drm_crtc_enable_color_mgmt(&crtc->base, 0, false,
+1 -1
drivers/gpu/drm/bridge/sil-sii8620.c
··· 178 178 179 179 static u8 sii8620_readb(struct sii8620 *ctx, u16 addr) 180 180 { 181 - u8 ret; 181 + u8 ret = 0; 182 182 183 183 sii8620_read_buf(ctx, addr, &ret, 1); 184 184 return ret;
+13 -36
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
··· 3179 3179 hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data); 3180 3180 } 3181 3181 3182 - static struct dw_hdmi * 3183 - __dw_hdmi_probe(struct platform_device *pdev, 3184 - const struct dw_hdmi_plat_data *plat_data) 3182 + /* ----------------------------------------------------------------------------- 3183 + * Probe/remove API, used from platforms based on the DRM bridge API. 3184 + */ 3185 + struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, 3186 + const struct dw_hdmi_plat_data *plat_data) 3185 3187 { 3186 3188 struct device *dev = &pdev->dev; 3187 3189 struct device_node *np = dev->of_node; ··· 3440 3438 hdmi->cec = platform_device_register_full(&pdevinfo); 3441 3439 } 3442 3440 3441 + drm_bridge_add(&hdmi->bridge); 3442 + 3443 3443 return hdmi; 3444 3444 3445 3445 err_iahb: 3446 - if (hdmi->i2c) { 3447 - i2c_del_adapter(&hdmi->i2c->adap); 3448 - hdmi->ddc = NULL; 3449 - } 3450 - 3451 3446 clk_disable_unprepare(hdmi->iahb_clk); 3452 3447 if (hdmi->cec_clk) 3453 3448 clk_disable_unprepare(hdmi->cec_clk); ··· 3455 3456 3456 3457 return ERR_PTR(ret); 3457 3458 } 3459 + EXPORT_SYMBOL_GPL(dw_hdmi_probe); 3458 3460 3459 - static void __dw_hdmi_remove(struct dw_hdmi *hdmi) 3461 + void dw_hdmi_remove(struct dw_hdmi *hdmi) 3460 3462 { 3463 + drm_bridge_remove(&hdmi->bridge); 3464 + 3461 3465 if (hdmi->audio && !IS_ERR(hdmi->audio)) 3462 3466 platform_device_unregister(hdmi->audio); 3463 3467 if (!IS_ERR(hdmi->cec)) ··· 3479 3477 else 3480 3478 i2c_put_adapter(hdmi->ddc); 3481 3479 } 3482 - 3483 - /* ----------------------------------------------------------------------------- 3484 - * Probe/remove API, used from platforms based on the DRM bridge API. 3485 - */ 3486 - struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, 3487 - const struct dw_hdmi_plat_data *plat_data) 3488 - { 3489 - struct dw_hdmi *hdmi; 3490 - 3491 - hdmi = __dw_hdmi_probe(pdev, plat_data); 3492 - if (IS_ERR(hdmi)) 3493 - return hdmi; 3494 - 3495 - drm_bridge_add(&hdmi->bridge); 3496 - 3497 - return hdmi; 3498 - } 3499 - EXPORT_SYMBOL_GPL(dw_hdmi_probe); 3500 - 3501 - void dw_hdmi_remove(struct dw_hdmi *hdmi) 3502 - { 3503 - drm_bridge_remove(&hdmi->bridge); 3504 - 3505 - __dw_hdmi_remove(hdmi); 3506 - } 3507 3480 EXPORT_SYMBOL_GPL(dw_hdmi_remove); 3508 3481 3509 3482 /* ----------------------------------------------------------------------------- ··· 3491 3514 struct dw_hdmi *hdmi; 3492 3515 int ret; 3493 3516 3494 - hdmi = __dw_hdmi_probe(pdev, plat_data); 3517 + hdmi = dw_hdmi_probe(pdev, plat_data); 3495 3518 if (IS_ERR(hdmi)) 3496 3519 return hdmi; 3497 3520 ··· 3508 3531 3509 3532 void dw_hdmi_unbind(struct dw_hdmi *hdmi) 3510 3533 { 3511 - __dw_hdmi_remove(hdmi); 3534 + dw_hdmi_remove(hdmi); 3512 3535 } 3513 3536 EXPORT_SYMBOL_GPL(dw_hdmi_unbind); 3514 3537
+1 -1
drivers/gpu/drm/bridge/tc358768.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com 3 + * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com 4 4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> 5 5 */ 6 6
+3 -1
drivers/gpu/drm/bridge/ti-sn65dsi86.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 3 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 - * datasheet: http://www.ti.com/lit/ds/symlink/sn65dsi86.pdf 4 + * datasheet: https://www.ti.com/lit/ds/symlink/sn65dsi86.pdf 5 5 */ 6 6 7 7 #include <linux/bits.h> ··· 212 212 213 213 static const struct dev_pm_ops ti_sn_bridge_pm_ops = { 214 214 SET_RUNTIME_PM_OPS(ti_sn_bridge_suspend, ti_sn_bridge_resume, NULL) 215 + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 216 + pm_runtime_force_resume) 215 217 }; 216 218 217 219 static int status_show(struct seq_file *s, void *data)
+1
drivers/gpu/drm/drm_atomic.c
··· 575 575 fb->modifier); 576 576 if (ret) { 577 577 struct drm_format_name_buf format_name; 578 + 578 579 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid pixel format %s, modifier 0x%llx\n", 579 580 plane->base.id, plane->name, 580 581 drm_get_format_name(fb->format->format,
+4
drivers/gpu/drm/drm_atomic_state_helper.c
··· 32 32 #include <drm/drm_device.h> 33 33 #include <drm/drm_plane.h> 34 34 #include <drm/drm_print.h> 35 + #include <drm/drm_vblank.h> 35 36 #include <drm/drm_writeback.h> 36 37 37 38 #include <linux/slab.h> ··· 93 92 { 94 93 if (crtc_state) 95 94 __drm_atomic_helper_crtc_state_reset(crtc_state, crtc); 95 + 96 + if (drm_dev_has_vblank(crtc->dev)) 97 + drm_crtc_vblank_reset(crtc); 96 98 97 99 crtc->state = crtc_state; 98 100 }
+7
drivers/gpu/drm/drm_atomic_uapi.c
··· 522 522 523 523 if (property == config->prop_fb_id) { 524 524 struct drm_framebuffer *fb; 525 + 525 526 fb = drm_framebuffer_lookup(dev, file_priv, val); 526 527 drm_atomic_set_fb_for_plane(state, fb); 527 528 if (fb) ··· 540 539 541 540 } else if (property == config->prop_crtc_id) { 542 541 struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val); 542 + 543 543 if (val && !crtc) 544 544 return -EACCES; 545 545 return drm_atomic_set_crtc_for_plane(state, crtc); ··· 683 681 684 682 if (property == config->prop_crtc_id) { 685 683 struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val); 684 + 686 685 if (val && !crtc) 687 686 return -EACCES; 688 687 return drm_atomic_set_crtc_for_connector(state, crtc); ··· 757 754 } else if (property == config->writeback_fb_id_property) { 758 755 struct drm_framebuffer *fb; 759 756 int ret; 757 + 760 758 fb = drm_framebuffer_lookup(dev, file_priv, val); 761 759 ret = drm_atomic_set_writeback_fb_for_connector(state, fb); 762 760 if (fb) ··· 865 861 switch (obj->type) { 866 862 case DRM_MODE_OBJECT_CONNECTOR: { 867 863 struct drm_connector *connector = obj_to_connector(obj); 864 + 868 865 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); 869 866 ret = drm_atomic_connector_get_property(connector, 870 867 connector->state, property, val); ··· 873 868 } 874 869 case DRM_MODE_OBJECT_CRTC: { 875 870 struct drm_crtc *crtc = obj_to_crtc(obj); 871 + 876 872 WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); 877 873 ret = drm_atomic_crtc_get_property(crtc, 878 874 crtc->state, property, val); ··· 881 875 } 882 876 case DRM_MODE_OBJECT_PLANE: { 883 877 struct drm_plane *plane = obj_to_plane(obj); 878 + 884 879 WARN_ON(!drm_modeset_is_locked(&plane->mutex)); 885 880 ret = drm_atomic_plane_get_property(plane, 886 881 plane->state, property, val);
+6
drivers/gpu/drm/drm_bufs.c
··· 53 53 struct drm_local_map *map) 54 54 { 55 55 struct drm_map_list *entry; 56 + 56 57 list_for_each_entry(entry, &dev->maplist, head) { 57 58 /* 58 59 * Because the kernel-userspace ABI is fixed at a 32-bit offset ··· 103 102 104 103 if (!use_hashed_handle) { 105 104 int ret; 105 + 106 106 hash->key = user_token >> PAGE_SHIFT; 107 107 ret = drm_ht_insert_item(&dev->map_hash, hash); 108 108 if (ret != -EINVAL) ··· 393 391 unsigned int token) 394 392 { 395 393 struct drm_map_list *_entry; 394 + 396 395 list_for_each_entry(_entry, &dev->maplist, head) 397 396 if (_entry->user_token == token) 398 397 return _entry->map; ··· 1326 1323 if (*p >= count) { 1327 1324 for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { 1328 1325 struct drm_buf_entry *from = &dma->bufs[i]; 1326 + 1329 1327 if (from->buf_count) { 1330 1328 if (f(data, count, from) < 0) 1331 1329 return -EFAULT; ··· 1363 1359 struct drm_file *file_priv) 1364 1360 { 1365 1361 struct drm_buf_info *request = data; 1362 + 1366 1363 return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf); 1367 1364 } 1368 1365 ··· 1575 1570 struct drm_file *file_priv) 1576 1571 { 1577 1572 struct drm_buf_map *request = data; 1573 + 1578 1574 return __drm_legacy_mapbufs(dev, data, &request->count, 1579 1575 &request->virtual, map_one_buf, 1580 1576 file_priv);
+29 -11
drivers/gpu/drm/drm_connector.c
··· 38 38 * DOC: overview 39 39 * 40 40 * In DRM connectors are the general abstraction for display sinks, and include 41 - * als fixed panels or anything else that can display pixels in some form. As 41 + * also fixed panels or anything else that can display pixels in some form. As 42 42 * opposed to all other KMS objects representing hardware (like CRTC, encoder or 43 43 * plane abstractions) connectors can be hotplugged and unplugged at runtime. 44 44 * Hence they are reference-counted using drm_connector_get() and ··· 129 129 130 130 /** 131 131 * drm_connector_get_cmdline_mode - reads the user's cmdline mode 132 - * @connector: connector to quwery 132 + * @connector: connector to query 133 133 * 134 134 * The kernel supports per-connector configuration of its consoles through 135 135 * use of the video= parameter. This function parses that option and ··· 269 269 INIT_LIST_HEAD(&connector->modes); 270 270 mutex_init(&connector->mutex); 271 271 connector->edid_blob_ptr = NULL; 272 + connector->epoch_counter = 0; 272 273 connector->tile_blob_ptr = NULL; 273 274 connector->status = connector_status_unknown; 274 275 connector->display_info.panel_orientation = ··· 991 990 * DP MST sinks), or high-res integrated panels (like dual-link DSI) which 992 991 * are not gen-locked. Note that for tiled panels which are genlocked, like 993 992 * dual-link LVDS or dual-link DSI, the driver should try to not expose the 994 - * tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers 993 + * tiling and virtualise both &drm_crtc and &drm_plane if needed. Drivers 995 994 * should update this value using drm_connector_set_tile_property(). 996 995 * Userspace cannot change this property. 997 996 * link-status: ··· 1157 1156 * 1158 1157 * It will even need to do colorspace conversion and get all layers 1159 1158 * to one common colorspace for blending. It can use either GL, Media 1160 - * or display engine to get this done based on the capabilties of the 1159 + * or display engine to get this done based on the capabilities of the 1161 1160 * associated hardware. 1162 1161 * 1163 1162 * Driver expects metadata to be put in &struct hdr_output_metadata ··· 1640 1639 * variable refresh rate capability for a connector. 1641 1640 * 1642 1641 * Returns: 1643 - * Zero on success, negative errono on failure. 1642 + * Zero on success, negative errno on failure. 1644 1643 */ 1645 1644 int drm_connector_attach_vrr_capable_property( 1646 1645 struct drm_connector *connector) ··· 1785 1784 * HDMI connectors. 1786 1785 * 1787 1786 * Returns: 1788 - * Zero on success, negative errono on failure. 1787 + * Zero on success, negative errno on failure. 1789 1788 */ 1790 1789 int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector) 1791 1790 { ··· 1814 1813 * DP connectors. 1815 1814 * 1816 1815 * Returns: 1817 - * Zero on success, negative errono on failure. 1816 + * Zero on success, negative errno on failure. 1818 1817 */ 1819 1818 int drm_mode_create_dp_colorspace_property(struct drm_connector *connector) 1820 1819 { ··· 1866 1865 * drm_mode_create_suggested_offset_properties - create suggests offset properties 1867 1866 * @dev: DRM device 1868 1867 * 1869 - * Create the the suggested x/y offset property for connectors. 1868 + * Create the suggested x/y offset property for connectors. 1870 1869 */ 1871 1870 int drm_mode_create_suggested_offset_properties(struct drm_device *dev) 1872 1871 { ··· 1980 1979 struct drm_device *dev = connector->dev; 1981 1980 size_t size = 0; 1982 1981 int ret; 1982 + const struct edid *old_edid; 1983 1983 1984 1984 /* ignore requests to set edid when overridden */ 1985 1985 if (connector->override_edid) ··· 1990 1988 size = EDID_LENGTH * (1 + edid->extensions); 1991 1989 1992 1990 /* Set the display info, using edid if available, otherwise 1993 - * reseting the values to defaults. This duplicates the work 1991 + * resetting the values to defaults. This duplicates the work 1994 1992 * done in drm_add_edid_modes, but that function is not 1995 1993 * consistently called before this one in all drivers and the 1996 1994 * computation is cheap enough that it seems better to ··· 2003 2001 drm_reset_display_info(connector); 2004 2002 2005 2003 drm_update_tile_info(connector, edid); 2004 + 2005 + if (connector->edid_blob_ptr) { 2006 + old_edid = (const struct edid *)connector->edid_blob_ptr->data; 2007 + if (old_edid) { 2008 + if (!drm_edid_are_equal(edid, old_edid)) { 2009 + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Edid was changed.\n", 2010 + connector->base.id, connector->name); 2011 + 2012 + connector->epoch_counter += 1; 2013 + DRM_DEBUG_KMS("Updating change counter to %llu\n", 2014 + connector->epoch_counter); 2015 + } 2016 + } 2017 + } 2006 2018 2007 2019 drm_object_property_set_value(&connector->base, 2008 2020 dev->mode_config.non_desktop_property, ··· 2117 2101 EXPORT_SYMBOL(drm_connector_set_vrr_capable_property); 2118 2102 2119 2103 /** 2120 - * drm_connector_set_panel_orientation - sets the connecter's panel_orientation 2104 + * drm_connector_set_panel_orientation - sets the connector's panel_orientation 2121 2105 * @connector: connector for which to set the panel-orientation property. 2122 2106 * @panel_orientation: drm_panel_orientation value to set 2123 2107 * ··· 2172 2156 2173 2157 /** 2174 2158 * drm_connector_set_panel_orientation_with_quirk - 2175 - * set the connecter's panel_orientation after checking for quirks 2159 + * set the connector's panel_orientation after checking for quirks 2176 2160 * @connector: connector for which to init the panel-orientation property. 2177 2161 * @panel_orientation: drm_panel_orientation value to set 2178 2162 * @width: width in pixels of the panel, used for panel quirk detection ··· 2409 2393 { 2410 2394 struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount); 2411 2395 struct drm_device *dev = tg->dev; 2396 + 2412 2397 mutex_lock(&dev->mode_config.idr_mutex); 2413 2398 idr_remove(&dev->mode_config.tile_idr, tg->id); 2414 2399 mutex_unlock(&dev->mode_config.idr_mutex); ··· 2445 2428 { 2446 2429 struct drm_tile_group *tg; 2447 2430 int id; 2431 + 2448 2432 mutex_lock(&dev->mode_config.idr_mutex); 2449 2433 idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) { 2450 2434 if (!memcmp(tg->group_data, topology, 8)) {
+1
drivers/gpu/drm/drm_crtc.c
··· 656 656 fb->modifier); 657 657 if (ret) { 658 658 struct drm_format_name_buf format_name; 659 + 659 660 DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n", 660 661 drm_get_format_name(fb->format->format, 661 662 &format_name),
+3
drivers/gpu/drm/drm_crtc_helper.c
··· 185 185 186 186 drm_for_each_crtc(crtc, dev) { 187 187 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 188 + 188 189 crtc->enabled = drm_helper_crtc_in_use(crtc); 189 190 if (!crtc->enabled) { 190 191 if (crtc_funcs->disable) ··· 885 884 if (mode < old_dpms) { 886 885 if (crtc) { 887 886 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 887 + 888 888 if (crtc_funcs->dpms) 889 889 (*crtc_funcs->dpms) (crtc, 890 890 drm_helper_choose_crtc_dpms(crtc)); ··· 900 898 drm_helper_encoder_dpms(encoder, encoder_dpms); 901 899 if (crtc) { 902 900 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 901 + 903 902 if (crtc_funcs->dpms) 904 903 (*crtc_funcs->dpms) (crtc, 905 904 drm_helper_choose_crtc_dpms(crtc));
+38 -30
drivers/gpu/drm/drm_dp_helper.c
··· 57 57 int i = DP_LANE0_1_STATUS + (lane >> 1); 58 58 int s = (lane & 1) * 4; 59 59 u8 l = dp_link_status(link_status, i); 60 + 60 61 return (l >> s) & 0xf; 61 62 } 62 63 ··· 258 257 err = ret; 259 258 } 260 259 261 - DRM_DEBUG_KMS("Too many retries, giving up. First error: %d\n", err); 260 + DRM_DEBUG_KMS("%s: Too many retries, giving up. First error: %d\n", 261 + aux->name, err); 262 262 ret = err; 263 263 264 264 unlock: ··· 378 376 379 377 if (drm_dp_dpcd_read(aux, DP_DEVICE_SERVICE_IRQ_VECTOR, 380 378 &auto_test_req, 1) < 1) { 381 - DRM_ERROR("DPCD failed read at register 0x%x\n", 382 - DP_DEVICE_SERVICE_IRQ_VECTOR); 379 + DRM_ERROR("%s: DPCD failed read at register 0x%x\n", 380 + aux->name, DP_DEVICE_SERVICE_IRQ_VECTOR); 383 381 return false; 384 382 } 385 383 auto_test_req &= DP_AUTOMATED_TEST_REQUEST; 386 384 387 385 if (drm_dp_dpcd_read(aux, DP_TEST_REQUEST, &link_edid_read, 1) < 1) { 388 - DRM_ERROR("DPCD failed read at register 0x%x\n", 389 - DP_TEST_REQUEST); 386 + DRM_ERROR("%s: DPCD failed read at register 0x%x\n", 387 + aux->name, DP_TEST_REQUEST); 390 388 return false; 391 389 } 392 390 link_edid_read &= DP_TEST_LINK_EDID_READ; 393 391 394 392 if (!auto_test_req || !link_edid_read) { 395 - DRM_DEBUG_KMS("Source DUT does not support TEST_EDID_READ\n"); 393 + DRM_DEBUG_KMS("%s: Source DUT does not support TEST_EDID_READ\n", 394 + aux->name); 396 395 return false; 397 396 } 398 397 399 398 if (drm_dp_dpcd_write(aux, DP_DEVICE_SERVICE_IRQ_VECTOR, 400 399 &auto_test_req, 1) < 1) { 401 - DRM_ERROR("DPCD failed write at register 0x%x\n", 402 - DP_DEVICE_SERVICE_IRQ_VECTOR); 400 + DRM_ERROR("%s: DPCD failed write at register 0x%x\n", 401 + aux->name, DP_DEVICE_SERVICE_IRQ_VECTOR); 403 402 return false; 404 403 } 405 404 406 405 /* send back checksum for the last edid extension block data */ 407 406 if (drm_dp_dpcd_write(aux, DP_TEST_EDID_CHECKSUM, 408 407 &real_edid_checksum, 1) < 1) { 409 - DRM_ERROR("DPCD failed write at register 0x%x\n", 410 - DP_TEST_EDID_CHECKSUM); 408 + DRM_ERROR("%s: DPCD failed write at register 0x%x\n", 409 + aux->name, DP_TEST_EDID_CHECKSUM); 411 410 return false; 412 411 } 413 412 414 413 test_resp |= DP_TEST_EDID_CHECKSUM_WRITE; 415 414 if (drm_dp_dpcd_write(aux, DP_TEST_RESPONSE, &test_resp, 1) < 1) { 416 - DRM_ERROR("DPCD failed write at register 0x%x\n", 417 - DP_TEST_RESPONSE); 415 + DRM_ERROR("%s: DPCD failed write at register 0x%x\n", 416 + aux->name, DP_TEST_RESPONSE); 418 417 return false; 419 418 } 420 419 ··· 740 737 * Avoid spamming the kernel log with timeout errors. 741 738 */ 742 739 if (ret == -ETIMEDOUT) 743 - DRM_DEBUG_KMS_RATELIMITED("transaction timed out\n"); 740 + DRM_DEBUG_KMS_RATELIMITED("%s: transaction timed out\n", 741 + aux->name); 744 742 else 745 - DRM_DEBUG_KMS("transaction failed: %d\n", ret); 746 - 743 + DRM_DEBUG_KMS("%s: transaction failed: %d\n", 744 + aux->name, ret); 747 745 return ret; 748 746 } 749 747 ··· 758 754 break; 759 755 760 756 case DP_AUX_NATIVE_REPLY_NACK: 761 - DRM_DEBUG_KMS("native nack (result=%d, size=%zu)\n", ret, msg->size); 757 + DRM_DEBUG_KMS("%s: native nack (result=%d, size=%zu)\n", 758 + aux->name, ret, msg->size); 762 759 return -EREMOTEIO; 763 760 764 761 case DP_AUX_NATIVE_REPLY_DEFER: 765 - DRM_DEBUG_KMS("native defer\n"); 762 + DRM_DEBUG_KMS("%s: native defer\n", aux->name); 766 763 /* 767 764 * We could check for I2C bit rate capabilities and if 768 765 * available adjust this interval. We could also be ··· 777 772 continue; 778 773 779 774 default: 780 - DRM_ERROR("invalid native reply %#04x\n", msg->reply); 775 + DRM_ERROR("%s: invalid native reply %#04x\n", 776 + aux->name, msg->reply); 781 777 return -EREMOTEIO; 782 778 } 783 779 ··· 793 787 return ret; 794 788 795 789 case DP_AUX_I2C_REPLY_NACK: 796 - DRM_DEBUG_KMS("I2C nack (result=%d, size=%zu)\n", 797 - ret, msg->size); 790 + DRM_DEBUG_KMS("%s: I2C nack (result=%d, size=%zu)\n", 791 + aux->name, ret, msg->size); 798 792 aux->i2c_nack_count++; 799 793 return -EREMOTEIO; 800 794 801 795 case DP_AUX_I2C_REPLY_DEFER: 802 - DRM_DEBUG_KMS("I2C defer\n"); 796 + DRM_DEBUG_KMS("%s: I2C defer\n", aux->name); 803 797 /* DP Compliance Test 4.2.2.5 Requirement: 804 798 * Must have at least 7 retries for I2C defers on the 805 799 * transaction to pass this test ··· 813 807 continue; 814 808 815 809 default: 816 - DRM_ERROR("invalid I2C reply %#04x\n", msg->reply); 810 + DRM_ERROR("%s: invalid I2C reply %#04x\n", 811 + aux->name, msg->reply); 817 812 return -EREMOTEIO; 818 813 } 819 814 } 820 815 821 - DRM_DEBUG_KMS("too many retries, giving up\n"); 816 + DRM_DEBUG_KMS("%s: Too many retries, giving up\n", aux->name); 822 817 return -EREMOTEIO; 823 818 } 824 819 ··· 848 841 return err == 0 ? -EPROTO : err; 849 842 850 843 if (err < msg.size && err < ret) { 851 - DRM_DEBUG_KMS("Partial I2C reply: requested %zu bytes got %d bytes\n", 852 - msg.size, err); 844 + DRM_DEBUG_KMS("%s: Partial I2C reply: requested %zu bytes got %d bytes\n", 845 + aux->name, msg.size, err); 853 846 ret = err; 854 847 } 855 848 ··· 1028 1021 } 1029 1022 1030 1023 if (ret == -EAGAIN) { 1031 - DRM_DEBUG_KMS("Get CRC failed after retrying: %d\n", 1032 - ret); 1024 + DRM_DEBUG_KMS("%s: Get CRC failed after retrying: %d\n", 1025 + aux->name, ret); 1033 1026 continue; 1034 1027 } else if (ret) { 1035 - DRM_DEBUG_KMS("Failed to get a CRC: %d\n", ret); 1028 + DRM_DEBUG_KMS("%s: Failed to get a CRC: %d\n", 1029 + aux->name, ret); 1036 1030 continue; 1037 1031 } 1038 1032 ··· 1396 1388 1397 1389 dev_id_len = strnlen(ident->device_id, sizeof(ident->device_id)); 1398 1390 1399 - DRM_DEBUG_KMS("DP %s: OUI %*phD dev-ID %*pE HW-rev %d.%d SW-rev %d.%d quirks 0x%04x\n", 1400 - is_branch ? "branch" : "sink", 1391 + DRM_DEBUG_KMS("%s: DP %s: OUI %*phD dev-ID %*pE HW-rev %d.%d SW-rev %d.%d quirks 0x%04x\n", 1392 + aux->name, is_branch ? "branch" : "sink", 1401 1393 (int)sizeof(ident->oui), ident->oui, 1402 1394 dev_id_len, ident->device_id, 1403 1395 ident->hw_rev >> 4, ident->hw_rev & 0xf,
+20
drivers/gpu/drm/drm_dp_mst_topology.c
··· 259 259 static inline u8 drm_dp_calc_sb_hdr_size(struct drm_dp_sideband_msg_hdr *hdr) 260 260 { 261 261 u8 size = 3; 262 + 262 263 size += (hdr->lct / 2); 263 264 return size; 264 265 } ··· 270 269 int idx = 0; 271 270 int i; 272 271 u8 crc4; 272 + 273 273 buf[idx++] = ((hdr->lct & 0xf) << 4) | (hdr->lcr & 0xf); 274 274 for (i = 0; i < (hdr->lct / 2); i++) 275 275 buf[idx++] = hdr->rad[i]; ··· 291 289 u8 len; 292 290 int i; 293 291 u8 idx; 292 + 294 293 if (buf[0] == 0) 295 294 return false; 296 295 len = 3; ··· 329 326 int idx = 0; 330 327 int i; 331 328 u8 *buf = raw->msg; 329 + 332 330 buf[idx++] = req->req_type & 0x7f; 333 331 334 332 switch (req->req_type) { ··· 677 673 static void drm_dp_crc_sideband_chunk_req(u8 *msg, u8 len) 678 674 { 679 675 u8 crc4; 676 + 680 677 crc4 = drm_dp_msg_data_crc4(msg, len); 681 678 msg[len] = crc4; 682 679 } ··· 752 747 { 753 748 int idx = 1; 754 749 int i; 750 + 755 751 memcpy(repmsg->u.link_addr.guid, &raw->msg[idx], 16); 756 752 idx += 16; 757 753 repmsg->u.link_addr.nports = raw->msg[idx] & 0xf; ··· 804 798 struct drm_dp_sideband_msg_reply_body *repmsg) 805 799 { 806 800 int idx = 1; 801 + 807 802 repmsg->u.remote_dpcd_read_ack.port_number = raw->msg[idx] & 0xf; 808 803 idx++; 809 804 if (idx > raw->curlen) ··· 825 818 struct drm_dp_sideband_msg_reply_body *repmsg) 826 819 { 827 820 int idx = 1; 821 + 828 822 repmsg->u.remote_dpcd_write_ack.port_number = raw->msg[idx] & 0xf; 829 823 idx++; 830 824 if (idx > raw->curlen) ··· 859 851 struct drm_dp_sideband_msg_reply_body *repmsg) 860 852 { 861 853 int idx = 1; 854 + 862 855 repmsg->u.path_resources.port_number = (raw->msg[idx] >> 4) & 0xf; 863 856 repmsg->u.path_resources.fec_capable = raw->msg[idx] & 0x1; 864 857 idx++; ··· 883 874 struct drm_dp_sideband_msg_reply_body *repmsg) 884 875 { 885 876 int idx = 1; 877 + 886 878 repmsg->u.allocate_payload.port_number = (raw->msg[idx] >> 4) & 0xf; 887 879 idx++; 888 880 if (idx > raw->curlen) ··· 906 896 struct drm_dp_sideband_msg_reply_body *repmsg) 907 897 { 908 898 int idx = 1; 899 + 909 900 repmsg->u.query_payload.port_number = (raw->msg[idx] >> 4) & 0xf; 910 901 idx++; 911 902 if (idx > raw->curlen) ··· 1093 1082 u8 *sdp_stream_sink) 1094 1083 { 1095 1084 struct drm_dp_sideband_msg_req_body req; 1085 + 1096 1086 memset(&req, 0, sizeof(req)); 1097 1087 req.req_type = DP_ALLOCATE_PAYLOAD; 1098 1088 req.u.allocate_payload.port_number = port_num; ··· 1154 1142 int vcpi) 1155 1143 { 1156 1144 int i; 1145 + 1157 1146 if (vcpi == 0) 1158 1147 return; 1159 1148 ··· 1953 1940 int parent_lct = port->parent->lct; 1954 1941 int shift = 4; 1955 1942 int idx = (parent_lct - 1) / 2; 1943 + 1956 1944 if (parent_lct > 1) { 1957 1945 memcpy(rad, port->parent->rad, idx + 1); 1958 1946 shift = (parent_lct % 2) ? 4 : 0; ··· 2132 2118 { 2133 2119 int i; 2134 2120 char temp[8]; 2121 + 2135 2122 snprintf(proppath, proppath_size, "mst:%d", mstb->mgr->conn_base_id); 2136 2123 for (i = 0; i < (mstb->lct - 1); i++) { 2137 2124 int shift = (i % 2) ? 0 : 4; 2138 2125 int port_num = (mstb->rad[i / 2] >> shift) & 0xf; 2126 + 2139 2127 snprintf(temp, sizeof(temp), "-%d", port_num); 2140 2128 strlcat(proppath, temp, proppath_size); 2141 2129 } ··· 3174 3158 struct drm_dp_payload *payload) 3175 3159 { 3176 3160 int ret; 3161 + 3177 3162 ret = drm_dp_payload_send_msg(mgr, port, id, port->vcpi.pbn); 3178 3163 if (ret < 0) 3179 3164 return ret; ··· 3331 3314 struct drm_dp_mst_port *port; 3332 3315 int i; 3333 3316 int ret = 0; 3317 + 3334 3318 mutex_lock(&mgr->payload_lock); 3335 3319 for (i = 0; i < mgr->max_payloads; i++) { 3336 3320 ··· 3797 3779 /* Were we actually expecting a response, and from this mstb? */ 3798 3780 if (!txmsg || txmsg->dst != mstb) { 3799 3781 struct drm_dp_sideband_msg_hdr *hdr; 3782 + 3800 3783 hdr = &msg->initial_hdr; 3801 3784 DRM_DEBUG_KMS("Got MST reply with no msg %p %d %d %02x %02x\n", 3802 3785 mstb, hdr->seqno, hdr->lct, hdr->rad[0], ··· 4345 4326 int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) 4346 4327 { 4347 4328 int slots = 0; 4329 + 4348 4330 port = drm_dp_mst_topology_get_port_validated(mgr, port); 4349 4331 if (!port) 4350 4332 return slots;
+111 -56
drivers/gpu/drm/drm_edid.c
··· 1616 1616 } 1617 1617 1618 1618 /** 1619 + * drm_edid_are_equal - compare two edid blobs. 1620 + * @edid1: pointer to first blob 1621 + * @edid2: pointer to second blob 1622 + * This helper can be used during probing to determine if 1623 + * edid had changed. 1624 + */ 1625 + bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2) 1626 + { 1627 + int edid1_len, edid2_len; 1628 + bool edid1_present = edid1 != NULL; 1629 + bool edid2_present = edid2 != NULL; 1630 + 1631 + if (edid1_present != edid2_present) 1632 + return false; 1633 + 1634 + if (edid1) { 1635 + edid1_len = EDID_LENGTH * (1 + edid1->extensions); 1636 + edid2_len = EDID_LENGTH * (1 + edid2->extensions); 1637 + 1638 + if (edid1_len != edid2_len) 1639 + return false; 1640 + 1641 + if (memcmp(edid1, edid2, edid1_len)) 1642 + return false; 1643 + } 1644 + 1645 + return true; 1646 + } 1647 + EXPORT_SYMBOL(drm_edid_are_equal); 1648 + 1649 + /** 1619 1650 * drm_edid_block_valid - Sanity check the EDID block (base or extension) 1620 1651 * @raw_edid: pointer to raw EDID block 1621 1652 * @block: type of block to validate (0 for base, extension otherwise) ··· 1672 1641 1673 1642 if (block == 0) { 1674 1643 int score = drm_edid_header_is_valid(raw_edid); 1644 + 1675 1645 if (score == 8) { 1676 1646 if (edid_corrupt) 1677 1647 *edid_corrupt = false; ··· 2049 2017 struct edid *drm_get_edid(struct drm_connector *connector, 2050 2018 struct i2c_adapter *adapter) 2051 2019 { 2020 + struct edid *edid; 2021 + 2052 2022 if (connector->force == DRM_FORCE_OFF) 2053 2023 return NULL; 2054 2024 2055 2025 if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter)) 2056 2026 return NULL; 2057 2027 2058 - return drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter); 2028 + edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter); 2029 + drm_connector_update_edid_property(connector, edid); 2030 + return edid; 2059 2031 } 2060 2032 EXPORT_SYMBOL(drm_get_edid); 2061 2033 ··· 2224 2188 2225 2189 for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) { 2226 2190 const struct drm_display_mode *ptr = &drm_dmt_modes[i]; 2191 + 2227 2192 if (hsize != ptr->hdisplay) 2228 2193 continue; 2229 2194 if (vsize != ptr->vdisplay) ··· 2296 2259 2297 2260 for (i = 1; i <= raw_edid[0x7e]; i++) { 2298 2261 u8 *ext = raw_edid + (i * EDID_LENGTH); 2262 + 2299 2263 switch (*ext) { 2300 2264 case CEA_EXT: 2301 2265 cea_for_each_detailed_block(ext, cb, closure); ··· 2328 2290 { 2329 2291 if (edid->revision >= 4) { 2330 2292 bool ret = false; 2293 + 2331 2294 drm_for_each_detailed_block((u8 *)edid, is_rb, &ret); 2332 2295 return ret; 2333 2296 } ··· 2353 2314 drm_gtf2_hbreak(struct edid *edid) 2354 2315 { 2355 2316 u8 *r = NULL; 2317 + 2356 2318 drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); 2357 2319 return r ? (r[12] * 2) : 0; 2358 2320 } ··· 2362 2322 drm_gtf2_2c(struct edid *edid) 2363 2323 { 2364 2324 u8 *r = NULL; 2325 + 2365 2326 drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); 2366 2327 return r ? r[13] : 0; 2367 2328 } ··· 2371 2330 drm_gtf2_m(struct edid *edid) 2372 2331 { 2373 2332 u8 *r = NULL; 2333 + 2374 2334 drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); 2375 2335 return r ? (r[15] << 8) + r[14] : 0; 2376 2336 } ··· 2380 2338 drm_gtf2_k(struct edid *edid) 2381 2339 { 2382 2340 u8 *r = NULL; 2341 + 2383 2342 drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); 2384 2343 return r ? r[16] : 0; 2385 2344 } ··· 2389 2346 drm_gtf2_2j(struct edid *edid) 2390 2347 { 2391 2348 u8 *r = NULL; 2349 + 2392 2350 drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); 2393 2351 return r ? r[17] : 0; 2394 2352 } ··· 2841 2797 2842 2798 for (i = 0; i < ARRAY_SIZE(extra_modes); i++) { 2843 2799 const struct minimode *m = &extra_modes[i]; 2800 + 2844 2801 newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0); 2845 2802 if (!newmode) 2846 2803 return modes; ··· 2871 2826 2872 2827 for (i = 0; i < ARRAY_SIZE(extra_modes); i++) { 2873 2828 const struct minimode *m = &extra_modes[i]; 2829 + 2874 2830 newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0); 2875 2831 if (!newmode) 2876 2832 return modes; ··· 3007 2961 for (i = 0; i <= EDID_EST_TIMINGS; i++) { 3008 2962 if (est_bits & (1<<i)) { 3009 2963 struct drm_display_mode *newmode; 2964 + 3010 2965 newmode = drm_mode_duplicate(dev, &edid_est_modes[i]); 3011 2966 if (newmode) { 3012 2967 drm_mode_probed_add(connector, newmode); ··· 3096 3049 3097 3050 for (i = 0; i < 4; i++) { 3098 3051 int uninitialized_var(width), height; 3052 + 3099 3053 cvt = &(timing->data.other_data.data.cvt[i]); 3100 3054 3101 3055 if (!memcmp(cvt->code, empty, 3)) ··· 3236 3188 /* 3237 3189 * Search EDID for CEA extension block. 3238 3190 */ 3239 - static u8 *drm_find_edid_extension(const struct edid *edid, int ext_id) 3191 + static u8 *drm_find_edid_extension(const struct edid *edid, 3192 + int ext_id, int *ext_index) 3240 3193 { 3241 3194 u8 *edid_ext = NULL; 3242 3195 int i; ··· 3247 3198 return NULL; 3248 3199 3249 3200 /* Find CEA extension */ 3250 - for (i = 0; i < edid->extensions; i++) { 3201 + for (i = *ext_index; i < edid->extensions; i++) { 3251 3202 edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1); 3252 3203 if (edid_ext[0] == ext_id) 3253 3204 break; 3254 3205 } 3255 3206 3256 - if (i == edid->extensions) 3207 + if (i >= edid->extensions) 3257 3208 return NULL; 3209 + 3210 + *ext_index = i + 1; 3258 3211 3259 3212 return edid_ext; 3260 3213 } 3261 3214 3262 3215 3263 3216 static u8 *drm_find_displayid_extension(const struct edid *edid, 3264 - int *length, int *idx) 3217 + int *length, int *idx, 3218 + int *ext_index) 3265 3219 { 3266 - u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT); 3220 + u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, ext_index); 3267 3221 struct displayid_hdr *base; 3268 3222 int ret; 3269 3223 ··· 3293 3241 struct displayid_block *block; 3294 3242 u8 *cea; 3295 3243 u8 *displayid; 3244 + int ext_index; 3296 3245 3297 3246 /* Look for a top level CEA extension block */ 3298 - cea = drm_find_edid_extension(edid, CEA_EXT); 3247 + /* FIXME: make callers iterate through multiple CEA ext blocks? */ 3248 + ext_index = 0; 3249 + cea = drm_find_edid_extension(edid, CEA_EXT, &ext_index); 3299 3250 if (cea) 3300 3251 return cea; 3301 3252 3302 3253 /* CEA blocks can also be found embedded in a DisplayID block */ 3303 - displayid = drm_find_displayid_extension(edid, &length, &idx); 3304 - if (!displayid) 3305 - return NULL; 3254 + ext_index = 0; 3255 + for (;;) { 3256 + displayid = drm_find_displayid_extension(edid, &length, &idx, 3257 + &ext_index); 3258 + if (!displayid) 3259 + return NULL; 3306 3260 3307 - idx += sizeof(struct displayid_hdr); 3308 - for_each_displayid_db(displayid, block, idx, length) { 3309 - if (block->tag == DATA_BLOCK_CTA) { 3310 - cea = (u8 *)block; 3311 - break; 3261 + idx += sizeof(struct displayid_hdr); 3262 + for_each_displayid_db(displayid, block, idx, length) { 3263 + if (block->tag == DATA_BLOCK_CTA) 3264 + return (u8 *)block; 3312 3265 } 3313 3266 } 3314 3267 3315 - return cea; 3268 + return NULL; 3316 3269 } 3317 3270 3318 3271 static __always_inline const struct drm_display_mode *cea_mode_for_vic(u8 vic) ··· 3748 3691 3749 3692 for (i = 0; i < len; i++) { 3750 3693 struct drm_display_mode *mode; 3694 + 3751 3695 mode = drm_display_mode_from_vic_index(connector, db, len, i); 3752 3696 if (mode) { 3753 3697 /* ··· 4590 4532 4591 4533 if (cea_db_tag(db) == AUDIO_BLOCK) { 4592 4534 int j; 4535 + 4593 4536 dbl = cea_db_payload_len(db); 4594 4537 4595 4538 count = dbl / 3; /* SAD is 3B */ ··· 5194 5135 unsigned vsync_width = (timings->vsw[0] | timings->vsw[1] << 8) + 1; 5195 5136 bool hsync_positive = (timings->hsync[1] >> 7) & 0x1; 5196 5137 bool vsync_positive = (timings->vsync[1] >> 7) & 0x1; 5138 + 5197 5139 mode = drm_mode_create(dev); 5198 5140 if (!mode) 5199 5141 return NULL; ··· 5255 5195 int length, idx; 5256 5196 struct displayid_block *block; 5257 5197 int num_modes = 0; 5198 + int ext_index = 0; 5258 5199 5259 - displayid = drm_find_displayid_extension(edid, &length, &idx); 5260 - if (!displayid) 5261 - return 0; 5262 - 5263 - idx += sizeof(struct displayid_hdr); 5264 - for_each_displayid_db(displayid, block, idx, length) { 5265 - switch (block->tag) { 5266 - case DATA_BLOCK_TYPE_1_DETAILED_TIMING: 5267 - num_modes += add_displayid_detailed_1_modes(connector, block); 5200 + for (;;) { 5201 + displayid = drm_find_displayid_extension(edid, &length, &idx, 5202 + &ext_index); 5203 + if (!displayid) 5268 5204 break; 5205 + 5206 + idx += sizeof(struct displayid_hdr); 5207 + for_each_displayid_db(displayid, block, idx, length) { 5208 + switch (block->tag) { 5209 + case DATA_BLOCK_TYPE_1_DETAILED_TIMING: 5210 + num_modes += add_displayid_detailed_1_modes(connector, block); 5211 + break; 5212 + } 5269 5213 } 5270 5214 } 5215 + 5271 5216 return num_modes; 5272 5217 } 5273 5218 ··· 5381 5316 5382 5317 for (i = 0; i < count; i++) { 5383 5318 const struct drm_display_mode *ptr = &drm_dmt_modes[i]; 5319 + 5384 5320 if (hdisplay && vdisplay) { 5385 5321 /* 5386 5322 * Only when two are valid, they will be used to check ··· 5853 5787 } 5854 5788 EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode); 5855 5789 5856 - static int drm_parse_tiled_block(struct drm_connector *connector, 5857 - const struct displayid_block *block) 5790 + static void drm_parse_tiled_block(struct drm_connector *connector, 5791 + const struct displayid_block *block) 5858 5792 { 5859 5793 const struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block; 5860 5794 u16 w, h; ··· 5888 5822 DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]); 5889 5823 5890 5824 tg = drm_mode_get_tile_group(connector->dev, tile->topology_id); 5891 - if (!tg) { 5892 - tg = drm_mode_create_tile_group(connector->dev, tile->topology_id); 5893 - } 5894 5825 if (!tg) 5895 - return -ENOMEM; 5826 + tg = drm_mode_create_tile_group(connector->dev, tile->topology_id); 5827 + if (!tg) 5828 + return; 5896 5829 5897 5830 if (connector->tile_group != tg) { 5898 5831 /* if we haven't got a pointer, 5899 5832 take the reference, drop ref to old tile group */ 5900 - if (connector->tile_group) { 5833 + if (connector->tile_group) 5901 5834 drm_mode_put_tile_group(connector->dev, connector->tile_group); 5902 - } 5903 5835 connector->tile_group = tg; 5904 - } else 5836 + } else { 5905 5837 /* if same tile group, then release the ref we just took. */ 5906 5838 drm_mode_put_tile_group(connector->dev, tg); 5907 - return 0; 5839 + } 5908 5840 } 5909 5841 5910 - static int drm_displayid_parse_tiled(struct drm_connector *connector, 5911 - const u8 *displayid, int length, int idx) 5842 + static void drm_displayid_parse_tiled(struct drm_connector *connector, 5843 + const u8 *displayid, int length, int idx) 5912 5844 { 5913 5845 const struct displayid_block *block; 5914 - int ret; 5915 5846 5916 5847 idx += sizeof(struct displayid_hdr); 5917 5848 for_each_displayid_db(displayid, block, idx, length) { ··· 5917 5854 5918 5855 switch (block->tag) { 5919 5856 case DATA_BLOCK_TILED_DISPLAY: 5920 - ret = drm_parse_tiled_block(connector, block); 5921 - if (ret) 5922 - return ret; 5857 + drm_parse_tiled_block(connector, block); 5923 5858 break; 5924 5859 default: 5925 5860 DRM_DEBUG_KMS("found DisplayID tag 0x%x, unhandled\n", block->tag); 5926 5861 break; 5927 5862 } 5928 5863 } 5929 - return 0; 5930 5864 } 5931 5865 5932 5866 void drm_update_tile_info(struct drm_connector *connector, 5933 5867 const struct edid *edid) 5934 5868 { 5935 5869 const void *displayid = NULL; 5870 + int ext_index = 0; 5936 5871 int length, idx; 5937 - int ret; 5938 5872 5939 5873 connector->has_tile = false; 5940 - displayid = drm_find_displayid_extension(edid, &length, &idx); 5941 - if (!displayid) { 5942 - /* drop reference to any tile group we had */ 5943 - goto out_drop_ref; 5874 + for (;;) { 5875 + displayid = drm_find_displayid_extension(edid, &length, &idx, 5876 + &ext_index); 5877 + if (!displayid) 5878 + break; 5879 + 5880 + drm_displayid_parse_tiled(connector, displayid, length, idx); 5944 5881 } 5945 5882 5946 - ret = drm_displayid_parse_tiled(connector, displayid, length, idx); 5947 - if (ret < 0) 5948 - goto out_drop_ref; 5949 - if (!connector->has_tile) 5950 - goto out_drop_ref; 5951 - return; 5952 - out_drop_ref: 5953 - if (connector->tile_group) { 5883 + if (!connector->has_tile && connector->tile_group) { 5954 5884 drm_mode_put_tile_group(connector->dev, connector->tile_group); 5955 5885 connector->tile_group = NULL; 5956 5886 } 5957 - return; 5958 5887 }
+1 -1
drivers/gpu/drm/drm_fb_helper.c
··· 1784 1784 if (ret < 0) 1785 1785 return ret; 1786 1786 1787 - dev_info(dev->dev, "fb%d: %s frame buffer device\n", 1787 + drm_info(dev, "fb%d: %s frame buffer device\n", 1788 1788 info->node, info->fix.id); 1789 1789 1790 1790 mutex_lock(&kernel_fb_helper_lock);
+2
drivers/gpu/drm/drm_file.c
··· 375 375 */ 376 376 if (!dev->hose) { 377 377 struct pci_dev *pci_dev; 378 + 378 379 pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); 379 380 if (pci_dev) { 380 381 dev->hose = pci_dev->sysdata; ··· 759 758 struct drm_pending_event *p) 760 759 { 761 760 unsigned long flags; 761 + 762 762 spin_lock_irqsave(&dev->event_lock, flags); 763 763 if (p->file_priv) { 764 764 p->file_priv->event_space += p->event->length;
+1
drivers/gpu/drm/drm_framebuffer.c
··· 1110 1110 if (drm_framebuffer_read_refcount(fb) > 1) { 1111 1111 if (drm_drv_uses_atomic_modeset(dev)) { 1112 1112 int ret = atomic_remove_fb(fb); 1113 + 1113 1114 WARN(ret, "atomic remove_fb failed with %i\n", ret); 1114 1115 } else 1115 1116 legacy_remove_fb(fb);
+2
drivers/gpu/drm/drm_ioc32.c
··· 388 388 struct drm_file *file_priv) 389 389 { 390 390 drm_buf_info32_t *request = data; 391 + 391 392 return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf32); 392 393 } 393 394 ··· 814 813 unsigned long arg) 815 814 { 816 815 drm_update_draw32_t update32; 816 + 817 817 if (copy_from_user(&update32, (void __user *)arg, sizeof(update32))) 818 818 return -EFAULT; 819 819
+4
drivers/gpu/drm/drm_lease.c
··· 166 166 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 167 167 if (_drm_lease_held_master(master, crtc->base.id)) { 168 168 uint32_t mask_in = 1ul << count_in; 169 + 169 170 if ((crtcs_in & mask_in) != 0) { 170 171 uint32_t mask_out = 1ul << count_out; 172 + 171 173 crtcs_out |= mask_out; 172 174 } 173 175 count_out++; ··· 425 423 for (o = 0; o < object_count; o++) { 426 424 struct drm_mode_object *obj = objects[o]; 427 425 u32 object_id = objects[o]->id; 426 + 428 427 DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id); 429 428 430 429 /* ··· 444 441 } 445 442 if (obj->type == DRM_MODE_OBJECT_CRTC && !universal_planes) { 446 443 struct drm_crtc *crtc = obj_to_crtc(obj); 444 + 447 445 ret = idr_alloc(leases, &drm_lease_idr_object, crtc->primary->base.id, crtc->primary->base.id + 1, GFP_KERNEL); 448 446 if (ret < 0) { 449 447 DRM_DEBUG_LEASE("Object primary plane %d cannot be inserted into leases (%d)\n",
+1
drivers/gpu/drm/drm_lock.c
··· 330 330 struct drm_file *file_priv) 331 331 { 332 332 struct drm_master *master = file_priv->master; 333 + 333 334 return (file_priv->lock_count && master->lock.hw_lock && 334 335 _DRM_LOCK_IS_HELD(master->lock.hw_lock->lock) && 335 336 master->lock.file_priv == file_priv);
+20 -21
drivers/gpu/drm/drm_mipi_dsi.c
··· 34 34 #include <linux/slab.h> 35 35 36 36 #include <drm/drm_dsc.h> 37 + #include <drm/drm_print.h> 37 38 #include <video/mipi_display.h> 38 39 39 40 /** ··· 156 155 static struct mipi_dsi_device * 157 156 of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) 158 157 { 159 - struct device *dev = host->dev; 160 158 struct mipi_dsi_device_info info = { }; 161 159 int ret; 162 160 u32 reg; 163 161 164 162 if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { 165 - dev_err(dev, "modalias failure on %pOF\n", node); 163 + drm_err(host, "modalias failure on %pOF\n", node); 166 164 return ERR_PTR(-EINVAL); 167 165 } 168 166 169 167 ret = of_property_read_u32(node, "reg", &reg); 170 168 if (ret) { 171 - dev_err(dev, "device node %pOF has no valid reg property: %d\n", 169 + drm_err(host, "device node %pOF has no valid reg property: %d\n", 172 170 node, ret); 173 171 return ERR_PTR(-EINVAL); 174 172 } ··· 202 202 const struct mipi_dsi_device_info *info) 203 203 { 204 204 struct mipi_dsi_device *dsi; 205 - struct device *dev = host->dev; 206 205 int ret; 207 206 208 207 if (!info) { 209 - dev_err(dev, "invalid mipi_dsi_device_info pointer\n"); 208 + drm_err(host, "invalid mipi_dsi_device_info pointer\n"); 210 209 return ERR_PTR(-EINVAL); 211 210 } 212 211 213 212 if (info->channel > 3) { 214 - dev_err(dev, "invalid virtual channel: %u\n", info->channel); 213 + drm_err(host, "invalid virtual channel: %u\n", info->channel); 215 214 return ERR_PTR(-EINVAL); 216 215 } 217 216 218 217 dsi = mipi_dsi_device_alloc(host); 219 218 if (IS_ERR(dsi)) { 220 - dev_err(dev, "failed to allocate DSI device %ld\n", 219 + drm_err(host, "failed to allocate DSI device %ld\n", 221 220 PTR_ERR(dsi)); 222 221 return dsi; 223 222 } ··· 227 228 228 229 ret = mipi_dsi_device_add(dsi); 229 230 if (ret) { 230 - dev_err(dev, "failed to add DSI device %d\n", ret); 231 + drm_err(host, "failed to add DSI device %d\n", ret); 231 232 kfree(dsi); 232 233 return ERR_PTR(ret); 233 234 } ··· 747 748 { 748 749 ssize_t err; 749 750 size_t size; 751 + u8 stack_tx[8]; 750 752 u8 *tx; 751 753 752 - if (len > 0) { 753 - size = 1 + len; 754 - 754 + size = 1 + len; 755 + if (len > ARRAY_SIZE(stack_tx) - 1) { 755 756 tx = kmalloc(size, GFP_KERNEL); 756 757 if (!tx) 757 758 return -ENOMEM; 758 - 759 - /* concatenate the DCS command byte and the payload */ 760 - tx[0] = cmd; 761 - memcpy(&tx[1], data, len); 762 759 } else { 763 - tx = &cmd; 764 - size = 1; 760 + tx = stack_tx; 765 761 } 762 + 763 + /* concatenate the DCS command byte and the payload */ 764 + tx[0] = cmd; 765 + if (data) 766 + memcpy(&tx[1], data, len); 766 767 767 768 err = mipi_dsi_dcs_write_buffer(dsi, tx, size); 768 769 769 - if (len > 0) 770 + if (tx != stack_tx) 770 771 kfree(tx); 771 772 772 773 return err; ··· 1081 1082 */ 1082 1083 int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) 1083 1084 { 1084 - u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, scanline >> 8, 1085 - scanline & 0xff }; 1085 + u8 payload[2] = { scanline >> 8, scanline & 0xff }; 1086 1086 ssize_t err; 1087 1087 1088 - err = mipi_dsi_generic_write(dsi, payload, sizeof(payload)); 1088 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_SCANLINE, payload, 1089 + sizeof(payload)); 1089 1090 if (err < 0) 1090 1091 return err; 1091 1092
+1
drivers/gpu/drm/drm_mode_config.c
··· 538 538 WARN_ON(!list_empty(&dev->mode_config.fb_list)); 539 539 list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { 540 540 struct drm_printer p = drm_debug_printer("[leaked fb]"); 541 + 541 542 drm_printf(&p, "framebuffer[%u]:\n", fb->base.id); 542 543 drm_framebuffer_print_info(&p, 1, fb); 543 544 drm_framebuffer_free(&fb->base.refcount);
+9
drivers/gpu/drm/drm_of.c
··· 246 246 if (panel) 247 247 *panel = NULL; 248 248 249 + /* 250 + * of_graph_get_remote_node() produces a noisy error message if port 251 + * node isn't found and the absence of the port is a legit case here, 252 + * so at first we silently check whether graph presents in the 253 + * device-tree node. 254 + */ 255 + if (!of_graph_is_present(np)) 256 + return -ENODEV; 257 + 249 258 remote = of_graph_get_remote_node(np, port, endpoint); 250 259 if (!remote) 251 260 return -ENODEV;
+1
drivers/gpu/drm/drm_pci.c
··· 298 298 void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) 299 299 { 300 300 struct drm_device *dev, *tmp; 301 + 301 302 DRM_DEBUG("\n"); 302 303 303 304 if (!(driver->driver_features & DRIVER_LEGACY)) {
+1
drivers/gpu/drm/drm_plane.c
··· 216 216 217 217 if (format_modifiers) { 218 218 const uint64_t *temp_modifiers = format_modifiers; 219 + 219 220 while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) 220 221 format_modifier_count++; 221 222 }
+1
drivers/gpu/drm/drm_prime.c
··· 1014 1014 { 1015 1015 struct dma_buf_attachment *attach; 1016 1016 struct dma_buf *dma_buf; 1017 + 1017 1018 attach = obj->import_attach; 1018 1019 if (sg) 1019 1020 dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
+33 -5
drivers/gpu/drm/drm_probe_helper.c
··· 292 292 if (WARN_ON(ret < 0)) 293 293 ret = connector_status_unknown; 294 294 295 + if (ret != connector->status) 296 + connector->epoch_counter += 1; 297 + 295 298 drm_modeset_drop_locks(&ctx); 296 299 drm_modeset_acquire_fini(&ctx); 297 300 ··· 328 325 return ret; 329 326 330 327 if (funcs->detect_ctx) 331 - return funcs->detect_ctx(connector, ctx, force); 328 + ret = funcs->detect_ctx(connector, ctx, force); 332 329 else if (connector->funcs->detect) 333 - return connector->funcs->detect(connector, force); 330 + ret = connector->funcs->detect(connector, force); 334 331 else 335 - return connector_status_connected; 332 + ret = connector_status_connected; 333 + 334 + if (ret != connector->status) 335 + connector->epoch_counter += 1; 336 + 337 + return ret; 336 338 } 337 339 EXPORT_SYMBOL(drm_helper_probe_detect); 338 340 ··· 787 779 struct drm_connector_list_iter conn_iter; 788 780 enum drm_connector_status old_status; 789 781 bool changed = false; 782 + u64 old_epoch_counter; 790 783 791 784 if (!dev->mode_config.poll_enabled) 792 785 return false; ··· 801 792 802 793 old_status = connector->status; 803 794 795 + old_epoch_counter = connector->epoch_counter; 796 + 797 + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Old epoch counter %llu\n", connector->base.id, 798 + connector->name, 799 + old_epoch_counter); 800 + 804 801 connector->status = drm_helper_probe_detect(connector, NULL, false); 805 802 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", 806 803 connector->base.id, 807 804 connector->name, 808 805 drm_get_connector_status_name(old_status), 809 806 drm_get_connector_status_name(connector->status)); 810 - if (old_status != connector->status) 807 + 808 + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] New epoch counter %llu\n", 809 + connector->base.id, 810 + connector->name, 811 + connector->epoch_counter); 812 + 813 + /* 814 + * Check if epoch counter had changed, meaning that we need 815 + * to send a uevent. 816 + */ 817 + if (old_epoch_counter != connector->epoch_counter) 811 818 changed = true; 819 + 812 820 } 813 821 drm_connector_list_iter_end(&conn_iter); 814 822 mutex_unlock(&dev->mode_config.mutex); 815 823 816 - if (changed) 824 + if (changed) { 817 825 drm_kms_helper_hotplug_event(dev); 826 + DRM_DEBUG_KMS("Sent hotplug event\n"); 827 + } 818 828 819 829 return changed; 820 830 }
+1
drivers/gpu/drm/drm_syncobj.c
··· 1188 1188 uint32_t count) 1189 1189 { 1190 1190 uint32_t i; 1191 + 1191 1192 for (i = 0; i < count; i++) 1192 1193 drm_syncobj_put(syncobjs[i]); 1193 1194 kfree(syncobjs);
+1
drivers/gpu/drm/drm_vblank.c
··· 1623 1623 e->event.vbl.crtc_id = 0; 1624 1624 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 1625 1625 struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); 1626 + 1626 1627 if (crtc) 1627 1628 e->event.vbl.crtc_id = crtc->base.id; 1628 1629 }
+2 -1
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
··· 20 20 #include <drm/drm_fb_helper.h> 21 21 #include <drm/drm_gem_vram_helper.h> 22 22 #include <drm/drm_irq.h> 23 + #include <drm/drm_managed.h> 23 24 #include <drm/drm_print.h> 24 25 #include <drm/drm_probe_helper.h> 25 26 #include <drm/drm_vblank.h> ··· 268 267 struct hibmc_drm_private *priv; 269 268 int ret; 270 269 271 - priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL); 270 + priv = drmm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 272 271 if (!priv) { 273 272 DRM_ERROR("no memory to allocate for hibmc_drm_private\n"); 274 273 return -ENOMEM;
+2
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h
··· 29 29 30 30 /* drm */ 31 31 struct drm_device *dev; 32 + struct drm_encoder encoder; 33 + struct drm_connector connector; 32 34 bool mode_config_initialized; 33 35 }; 34 36
+11 -41
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
··· 52 52 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 53 53 }; 54 54 55 - static struct drm_connector * 56 - hibmc_connector_init(struct hibmc_drm_private *priv) 57 - { 58 - struct drm_device *dev = priv->dev; 59 - struct drm_connector *connector; 60 - int ret; 61 - 62 - connector = devm_kzalloc(dev->dev, sizeof(*connector), GFP_KERNEL); 63 - if (!connector) { 64 - DRM_ERROR("failed to alloc memory when init connector\n"); 65 - return ERR_PTR(-ENOMEM); 66 - } 67 - 68 - ret = drm_connector_init(dev, connector, 69 - &hibmc_connector_funcs, 70 - DRM_MODE_CONNECTOR_VGA); 71 - if (ret) { 72 - DRM_ERROR("failed to init connector: %d\n", ret); 73 - return ERR_PTR(ret); 74 - } 75 - drm_connector_helper_add(connector, 76 - &hibmc_connector_helper_funcs); 77 - 78 - return connector; 79 - } 80 - 81 55 static void hibmc_encoder_mode_set(struct drm_encoder *encoder, 82 56 struct drm_display_mode *mode, 83 57 struct drm_display_mode *adj_mode) ··· 79 105 int hibmc_vdac_init(struct hibmc_drm_private *priv) 80 106 { 81 107 struct drm_device *dev = priv->dev; 82 - struct drm_encoder *encoder; 83 - struct drm_connector *connector; 108 + struct drm_encoder *encoder = &priv->encoder; 109 + struct drm_connector *connector = &priv->connector; 84 110 int ret; 85 - 86 - connector = hibmc_connector_init(priv); 87 - if (IS_ERR(connector)) { 88 - DRM_ERROR("failed to create connector: %ld\n", 89 - PTR_ERR(connector)); 90 - return PTR_ERR(connector); 91 - } 92 - 93 - encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL); 94 - if (!encoder) { 95 - DRM_ERROR("failed to alloc memory when init encoder\n"); 96 - return -ENOMEM; 97 - } 98 111 99 112 encoder->possible_crtcs = 0x1; 100 113 ret = drm_encoder_init(dev, encoder, &hibmc_encoder_funcs, ··· 92 131 } 93 132 94 133 drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs); 134 + 135 + ret = drm_connector_init(dev, connector, &hibmc_connector_funcs, 136 + DRM_MODE_CONNECTOR_VGA); 137 + if (ret) { 138 + DRM_ERROR("failed to init connector: %d\n", ret); 139 + return ret; 140 + } 141 + drm_connector_helper_add(connector, &hibmc_connector_helper_funcs); 142 + 95 143 drm_connector_attach_encoder(connector, encoder); 96 144 97 145 return 0;
+16 -10
drivers/gpu/drm/i915/display/intel_hotplug.c
··· 283 283 { 284 284 struct drm_device *dev = connector->base.dev; 285 285 enum drm_connector_status old_status; 286 + u64 old_epoch_counter; 287 + bool ret = false; 286 288 287 289 drm_WARN_ON(dev, !mutex_is_locked(&dev->mode_config.mutex)); 288 290 old_status = connector->base.status; 291 + old_epoch_counter = connector->base.epoch_counter; 289 292 290 293 connector->base.status = 291 294 drm_helper_probe_detect(&connector->base, NULL, false); 292 295 293 - if (old_status == connector->base.status) 294 - return INTEL_HOTPLUG_UNCHANGED; 296 + if (old_epoch_counter != connector->base.epoch_counter) 297 + ret = true; 295 298 296 - drm_dbg_kms(&to_i915(dev)->drm, 297 - "[CONNECTOR:%d:%s] status updated from %s to %s\n", 298 - connector->base.base.id, 299 - connector->base.name, 300 - drm_get_connector_status_name(old_status), 301 - drm_get_connector_status_name(connector->base.status)); 302 - 303 - return INTEL_HOTPLUG_CHANGED; 299 + if (ret) { 300 + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s (epoch counter %llu->%llu)\n", 301 + connector->base.base.id, 302 + connector->base.name, 303 + drm_get_connector_status_name(old_status), 304 + drm_get_connector_status_name(connector->base.status), 305 + old_epoch_counter, 306 + connector->base.epoch_counter); 307 + return INTEL_HOTPLUG_CHANGED; 308 + } 309 + return INTEL_HOTPLUG_UNCHANGED; 304 310 } 305 311 306 312 static bool intel_encoder_has_hpd_pulse(struct intel_encoder *encoder)
+7 -12
drivers/gpu/drm/imx/ipuv3-crtc.c
··· 109 109 { 110 110 struct imx_crtc_state *state; 111 111 112 - if (crtc->state) { 113 - if (crtc->state->mode_blob) 114 - drm_property_blob_put(crtc->state->mode_blob); 112 + if (crtc->state) 113 + __drm_atomic_helper_crtc_destroy_state(crtc->state); 115 114 116 - state = to_imx_crtc_state(crtc->state); 117 - memset(state, 0, sizeof(*state)); 118 - } else { 119 - state = kzalloc(sizeof(*state), GFP_KERNEL); 120 - if (!state) 121 - return; 122 - crtc->state = &state->base; 123 - } 115 + kfree(to_imx_crtc_state(crtc->state)); 116 + crtc->state = NULL; 124 117 125 - state->base.crtc = crtc; 118 + state = kzalloc(sizeof(*state), GFP_KERNEL); 119 + if (state) 120 + __drm_atomic_helper_crtc_reset(crtc, &state->base); 126 121 } 127 122 128 123 static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc)
+1 -1
drivers/gpu/drm/ingenic/ingenic-drm.c
··· 419 419 cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW; 420 420 if (info->bus_flags & DRM_BUS_FLAG_DE_LOW) 421 421 cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW; 422 - if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE) 422 + if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) 423 423 cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE; 424 424 425 425 if (!priv->panel_is_sharp) {
+4
drivers/gpu/drm/lima/lima_drv.c
··· 19 19 int lima_sched_timeout_ms; 20 20 uint lima_heap_init_nr_pages = 8; 21 21 uint lima_max_error_tasks; 22 + uint lima_job_hang_limit; 22 23 23 24 MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms"); 24 25 module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444); ··· 29 28 30 29 MODULE_PARM_DESC(max_error_tasks, "max number of error tasks to save"); 31 30 module_param_named(max_error_tasks, lima_max_error_tasks, uint, 0644); 31 + 32 + MODULE_PARM_DESC(job_hang_limit, "number of times to allow a job to hang before dropping it (default 0)"); 33 + module_param_named(job_hang_limit, lima_job_hang_limit, uint, 0444); 32 34 33 35 static int lima_ioctl_get_param(struct drm_device *dev, void *data, struct drm_file *file) 34 36 {
+1
drivers/gpu/drm/lima/lima_drv.h
··· 11 11 extern int lima_sched_timeout_ms; 12 12 extern uint lima_heap_init_nr_pages; 13 13 extern uint lima_max_error_tasks; 14 + extern uint lima_job_hang_limit; 14 15 15 16 struct lima_vm; 16 17 struct lima_bo;
+3 -2
drivers/gpu/drm/lima/lima_sched.c
··· 503 503 504 504 INIT_WORK(&pipe->recover_work, lima_sched_recover_work); 505 505 506 - return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 0, 507 - msecs_to_jiffies(timeout), name); 506 + return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 507 + lima_job_hang_limit, msecs_to_jiffies(timeout), 508 + name); 508 509 } 509 510 510 511 void lima_sched_pipe_fini(struct lima_sched_pipe *pipe)
+6 -10
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
··· 113 113 { 114 114 struct mtk_crtc_state *state; 115 115 116 - if (crtc->state) { 116 + if (crtc->state) 117 117 __drm_atomic_helper_crtc_destroy_state(crtc->state); 118 118 119 - state = to_mtk_crtc_state(crtc->state); 120 - memset(state, 0, sizeof(*state)); 121 - } else { 122 - state = kzalloc(sizeof(*state), GFP_KERNEL); 123 - if (!state) 124 - return; 125 - crtc->state = &state->base; 126 - } 119 + kfree(to_mtk_crtc_state(crtc->state)); 120 + crtc->state = NULL; 127 121 128 - state->base.crtc = crtc; 122 + state = kzalloc(sizeof(*state), GFP_KERNEL); 123 + if (state) 124 + __drm_atomic_helper_crtc_reset(crtc, &state->base); 129 125 } 130 126 131 127 static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc)
+88 -30
drivers/gpu/drm/meson/meson_crtc.c
··· 291 291 VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND | 292 292 VPP_COLOR_MNG_ENABLE, 293 293 priv->io_base + _REG(VPP_MISC)); 294 + 295 + writel_bits_relaxed(VIU_CTRL0_AFBC_TO_VD1, 296 + priv->viu.vd1_afbc ? VIU_CTRL0_AFBC_TO_VD1 : 0, 297 + priv->io_base + _REG(VIU_MISC_CTRL0)); 294 298 } 295 299 296 300 static void meson_g12a_crtc_enable_vd1(struct meson_drm *priv) ··· 304 300 VD_BLEND_POSTBLD_SRC_VD1 | 305 301 VD_BLEND_POSTBLD_PREMULT_EN, 306 302 priv->io_base + _REG(VD1_BLEND_SRC_CTRL)); 303 + 304 + writel_relaxed(priv->viu.vd1_afbc ? 305 + (VD1_AXI_SEL_AFBC | AFBC_VD1_SEL) : 0, 306 + priv->io_base + _REG(VD1_AFBCD0_MISC_CTRL)); 307 307 } 308 308 309 309 void meson_crtc_irq(struct meson_drm *priv) ··· 391 383 /* Update the VD1 registers */ 392 384 if (priv->viu.vd1_enabled && priv->viu.vd1_commit) { 393 385 394 - switch (priv->viu.vd1_planes) { 395 - case 3: 396 - meson_canvas_config(priv->canvas, 397 - priv->canvas_id_vd1_2, 398 - priv->viu.vd1_addr2, 399 - priv->viu.vd1_stride2, 400 - priv->viu.vd1_height2, 401 - MESON_CANVAS_WRAP_NONE, 402 - MESON_CANVAS_BLKMODE_LINEAR, 403 - MESON_CANVAS_ENDIAN_SWAP64); 404 - /* fallthrough */ 405 - case 2: 406 - meson_canvas_config(priv->canvas, 407 - priv->canvas_id_vd1_1, 408 - priv->viu.vd1_addr1, 409 - priv->viu.vd1_stride1, 410 - priv->viu.vd1_height1, 411 - MESON_CANVAS_WRAP_NONE, 412 - MESON_CANVAS_BLKMODE_LINEAR, 413 - MESON_CANVAS_ENDIAN_SWAP64); 414 - /* fallthrough */ 415 - case 1: 416 - meson_canvas_config(priv->canvas, 417 - priv->canvas_id_vd1_0, 418 - priv->viu.vd1_addr0, 419 - priv->viu.vd1_stride0, 420 - priv->viu.vd1_height0, 421 - MESON_CANVAS_WRAP_NONE, 422 - MESON_CANVAS_BLKMODE_LINEAR, 423 - MESON_CANVAS_ENDIAN_SWAP64); 386 + if (priv->viu.vd1_afbc) { 387 + writel_relaxed(priv->viu.vd1_afbc_head_addr, 388 + priv->io_base + 389 + _REG(AFBC_HEAD_BADDR)); 390 + writel_relaxed(priv->viu.vd1_afbc_body_addr, 391 + priv->io_base + 392 + _REG(AFBC_BODY_BADDR)); 393 + writel_relaxed(priv->viu.vd1_afbc_en, 394 + priv->io_base + 395 + _REG(AFBC_ENABLE)); 396 + writel_relaxed(priv->viu.vd1_afbc_mode, 397 + priv->io_base + 398 + _REG(AFBC_MODE)); 399 + writel_relaxed(priv->viu.vd1_afbc_size_in, 400 + priv->io_base + 401 + _REG(AFBC_SIZE_IN)); 402 + writel_relaxed(priv->viu.vd1_afbc_dec_def_color, 403 + priv->io_base + 404 + _REG(AFBC_DEC_DEF_COLOR)); 405 + writel_relaxed(priv->viu.vd1_afbc_conv_ctrl, 406 + priv->io_base + 407 + _REG(AFBC_CONV_CTRL)); 408 + writel_relaxed(priv->viu.vd1_afbc_size_out, 409 + priv->io_base + 410 + _REG(AFBC_SIZE_OUT)); 411 + writel_relaxed(priv->viu.vd1_afbc_vd_cfmt_ctrl, 412 + priv->io_base + 413 + _REG(AFBC_VD_CFMT_CTRL)); 414 + writel_relaxed(priv->viu.vd1_afbc_vd_cfmt_w, 415 + priv->io_base + 416 + _REG(AFBC_VD_CFMT_W)); 417 + writel_relaxed(priv->viu.vd1_afbc_mif_hor_scope, 418 + priv->io_base + 419 + _REG(AFBC_MIF_HOR_SCOPE)); 420 + writel_relaxed(priv->viu.vd1_afbc_mif_ver_scope, 421 + priv->io_base + 422 + _REG(AFBC_MIF_VER_SCOPE)); 423 + writel_relaxed(priv->viu.vd1_afbc_pixel_hor_scope, 424 + priv->io_base+ 425 + _REG(AFBC_PIXEL_HOR_SCOPE)); 426 + writel_relaxed(priv->viu.vd1_afbc_pixel_ver_scope, 427 + priv->io_base + 428 + _REG(AFBC_PIXEL_VER_SCOPE)); 429 + writel_relaxed(priv->viu.vd1_afbc_vd_cfmt_h, 430 + priv->io_base + 431 + _REG(AFBC_VD_CFMT_H)); 432 + } else { 433 + switch (priv->viu.vd1_planes) { 434 + case 3: 435 + meson_canvas_config(priv->canvas, 436 + priv->canvas_id_vd1_2, 437 + priv->viu.vd1_addr2, 438 + priv->viu.vd1_stride2, 439 + priv->viu.vd1_height2, 440 + MESON_CANVAS_WRAP_NONE, 441 + MESON_CANVAS_BLKMODE_LINEAR, 442 + MESON_CANVAS_ENDIAN_SWAP64); 443 + fallthrough; 444 + case 2: 445 + meson_canvas_config(priv->canvas, 446 + priv->canvas_id_vd1_1, 447 + priv->viu.vd1_addr1, 448 + priv->viu.vd1_stride1, 449 + priv->viu.vd1_height1, 450 + MESON_CANVAS_WRAP_NONE, 451 + MESON_CANVAS_BLKMODE_LINEAR, 452 + MESON_CANVAS_ENDIAN_SWAP64); 453 + fallthrough; 454 + case 1: 455 + meson_canvas_config(priv->canvas, 456 + priv->canvas_id_vd1_0, 457 + priv->viu.vd1_addr0, 458 + priv->viu.vd1_stride0, 459 + priv->viu.vd1_height0, 460 + MESON_CANVAS_WRAP_NONE, 461 + MESON_CANVAS_BLKMODE_LINEAR, 462 + MESON_CANVAS_ENDIAN_SWAP64); 463 + } 464 + 465 + writel_relaxed(0, priv->io_base + _REG(AFBC_ENABLE)); 424 466 } 425 467 426 468 writel_relaxed(priv->viu.vd1_if0_gen_reg,
+16
drivers/gpu/drm/meson/meson_drv.h
··· 86 86 87 87 bool vd1_enabled; 88 88 bool vd1_commit; 89 + bool vd1_afbc; 89 90 unsigned int vd1_planes; 90 91 uint32_t vd1_if0_gen_reg; 91 92 uint32_t vd1_if0_luma_x0; ··· 112 111 uint32_t vd1_height0; 113 112 uint32_t vd1_height1; 114 113 uint32_t vd1_height2; 114 + uint32_t vd1_afbc_mode; 115 + uint32_t vd1_afbc_en; 116 + uint32_t vd1_afbc_head_addr; 117 + uint32_t vd1_afbc_body_addr; 118 + uint32_t vd1_afbc_conv_ctrl; 119 + uint32_t vd1_afbc_dec_def_color; 120 + uint32_t vd1_afbc_vd_cfmt_ctrl; 121 + uint32_t vd1_afbc_vd_cfmt_w; 122 + uint32_t vd1_afbc_vd_cfmt_h; 123 + uint32_t vd1_afbc_mif_hor_scope; 124 + uint32_t vd1_afbc_mif_ver_scope; 125 + uint32_t vd1_afbc_size_out; 126 + uint32_t vd1_afbc_pixel_hor_scope; 127 + uint32_t vd1_afbc_pixel_ver_scope; 128 + uint32_t vd1_afbc_size_in; 115 129 uint32_t vpp_pic_in_height; 116 130 uint32_t vpp_postblend_vd1_h_start_end; 117 131 uint32_t vpp_postblend_vd1_v_start_end;
+284 -9
drivers/gpu/drm/meson/meson_overlay.c
··· 58 58 59 59 /* VPP_POSTBLEND_VD1_H_START_END */ 60 60 #define VD_H_END(value) FIELD_PREP(GENMASK(11, 0), value) 61 - #define VD_H_START(value) FIELD_PREP(GENMASK(27, 16), value) 61 + #define VD_H_START(value) FIELD_PREP(GENMASK(27, 16), \ 62 + ((value) & GENMASK(13, 0))) 62 63 63 64 /* VPP_POSTBLEND_VD1_V_START_END */ 64 65 #define VD_V_END(value) FIELD_PREP(GENMASK(11, 0), value) ··· 76 75 /* VPP_HSC_REGION12_STARTP VPP_HSC_REGION34_STARTP */ 77 76 #define VD_REGION24_START(value) FIELD_PREP(GENMASK(11, 0), value) 78 77 #define VD_REGION13_END(value) FIELD_PREP(GENMASK(27, 16), value) 78 + 79 + /* AFBC_ENABLE */ 80 + #define AFBC_DEC_ENABLE BIT(8) 81 + #define AFBC_FRM_START BIT(0) 82 + 83 + /* AFBC_MODE */ 84 + #define AFBC_HORZ_SKIP_UV(value) FIELD_PREP(GENMASK(1, 0), value) 85 + #define AFBC_VERT_SKIP_UV(value) FIELD_PREP(GENMASK(3, 2), value) 86 + #define AFBC_HORZ_SKIP_Y(value) FIELD_PREP(GENMASK(5, 4), value) 87 + #define AFBC_VERT_SKIP_Y(value) FIELD_PREP(GENMASK(7, 6), value) 88 + #define AFBC_COMPBITS_YUV(value) FIELD_PREP(GENMASK(13, 8), value) 89 + #define AFBC_COMPBITS_8BIT 0 90 + #define AFBC_COMPBITS_10BIT (2 | (2 << 2) | (2 << 4)) 91 + #define AFBC_BURST_LEN(value) FIELD_PREP(GENMASK(15, 14), value) 92 + #define AFBC_HOLD_LINE_NUM(value) FIELD_PREP(GENMASK(22, 16), value) 93 + #define AFBC_MIF_URGENT(value) FIELD_PREP(GENMASK(25, 24), value) 94 + #define AFBC_REV_MODE(value) FIELD_PREP(GENMASK(27, 26), value) 95 + #define AFBC_BLK_MEM_MODE BIT(28) 96 + #define AFBC_SCATTER_MODE BIT(29) 97 + #define AFBC_SOFT_RESET BIT(31) 98 + 99 + /* AFBC_SIZE_IN */ 100 + #define AFBC_HSIZE_IN(value) FIELD_PREP(GENMASK(28, 16), value) 101 + #define AFBC_VSIZE_IN(value) FIELD_PREP(GENMASK(12, 0), value) 102 + 103 + /* AFBC_DEC_DEF_COLOR */ 104 + #define AFBC_DEF_COLOR_Y(value) FIELD_PREP(GENMASK(29, 20), value) 105 + #define AFBC_DEF_COLOR_U(value) FIELD_PREP(GENMASK(19, 10), value) 106 + #define AFBC_DEF_COLOR_V(value) FIELD_PREP(GENMASK(9, 0), value) 107 + 108 + /* AFBC_CONV_CTRL */ 109 + #define AFBC_CONV_LBUF_LEN(value) FIELD_PREP(GENMASK(11, 0), value) 110 + 111 + /* AFBC_LBUF_DEPTH */ 112 + #define AFBC_DEC_LBUF_DEPTH(value) FIELD_PREP(GENMASK(27, 16), value) 113 + #define AFBC_MIF_LBUF_DEPTH(value) FIELD_PREP(GENMASK(11, 0), value) 114 + 115 + /* AFBC_OUT_XSCOPE/AFBC_SIZE_OUT */ 116 + #define AFBC_HSIZE_OUT(value) FIELD_PREP(GENMASK(28, 16), value) 117 + #define AFBC_VSIZE_OUT(value) FIELD_PREP(GENMASK(12, 0), value) 118 + #define AFBC_OUT_HORZ_BGN(value) FIELD_PREP(GENMASK(28, 16), value) 119 + #define AFBC_OUT_HORZ_END(value) FIELD_PREP(GENMASK(12, 0), value) 120 + 121 + /* AFBC_OUT_YSCOPE */ 122 + #define AFBC_OUT_VERT_BGN(value) FIELD_PREP(GENMASK(28, 16), value) 123 + #define AFBC_OUT_VERT_END(value) FIELD_PREP(GENMASK(12, 0), value) 124 + 125 + /* AFBC_VD_CFMT_CTRL */ 126 + #define AFBC_HORZ_RPT_PIXEL0 BIT(23) 127 + #define AFBC_HORZ_Y_C_RATIO(value) FIELD_PREP(GENMASK(22, 21), value) 128 + #define AFBC_HORZ_FMT_EN BIT(20) 129 + #define AFBC_VERT_RPT_LINE0 BIT(16) 130 + #define AFBC_VERT_INITIAL_PHASE(value) FIELD_PREP(GENMASK(11, 8), value) 131 + #define AFBC_VERT_PHASE_STEP(value) FIELD_PREP(GENMASK(7, 1), value) 132 + #define AFBC_VERT_FMT_EN BIT(0) 133 + 134 + /* AFBC_VD_CFMT_W */ 135 + #define AFBC_VD_V_WIDTH(value) FIELD_PREP(GENMASK(11, 0), value) 136 + #define AFBC_VD_H_WIDTH(value) FIELD_PREP(GENMASK(27, 16), value) 137 + 138 + /* AFBC_MIF_HOR_SCOPE */ 139 + #define AFBC_MIF_BLK_BGN_H(value) FIELD_PREP(GENMASK(25, 16), value) 140 + #define AFBC_MIF_BLK_END_H(value) FIELD_PREP(GENMASK(9, 0), value) 141 + 142 + /* AFBC_MIF_VER_SCOPE */ 143 + #define AFBC_MIF_BLK_BGN_V(value) FIELD_PREP(GENMASK(27, 16), value) 144 + #define AFBC_MIF_BLK_END_V(value) FIELD_PREP(GENMASK(11, 0), value) 145 + 146 + /* AFBC_PIXEL_HOR_SCOPE */ 147 + #define AFBC_DEC_PIXEL_BGN_H(value) FIELD_PREP(GENMASK(28, 16), \ 148 + ((value) & GENMASK(12, 0))) 149 + #define AFBC_DEC_PIXEL_END_H(value) FIELD_PREP(GENMASK(12, 0), value) 150 + 151 + /* AFBC_PIXEL_VER_SCOPE */ 152 + #define AFBC_DEC_PIXEL_BGN_V(value) FIELD_PREP(GENMASK(28, 16), value) 153 + #define AFBC_DEC_PIXEL_END_V(value) FIELD_PREP(GENMASK(12, 0), value) 154 + 155 + /* AFBC_VD_CFMT_H */ 156 + #define AFBC_VD_HEIGHT(value) FIELD_PREP(GENMASK(12, 0), value) 79 157 80 158 struct meson_overlay { 81 159 struct drm_plane base; ··· 237 157 unsigned int ratio_x, ratio_y; 238 158 int temp_height, temp_width; 239 159 unsigned int w_in, h_in; 160 + int afbc_left, afbc_right; 161 + int afbc_top_src, afbc_bottom_src; 162 + int afbc_top, afbc_bottom; 240 163 int temp, start, end; 241 164 242 165 if (!crtc_state) { ··· 252 169 253 170 w_in = fixed16_to_int(state->src_w); 254 171 h_in = fixed16_to_int(state->src_h); 255 - crop_top = fixed16_to_int(state->src_x); 172 + crop_top = fixed16_to_int(state->src_y); 256 173 crop_left = fixed16_to_int(state->src_x); 257 174 258 175 video_top = state->crtc_y; ··· 326 243 DRM_DEBUG("vsc startp %d endp %d start_lines %d end_lines %d\n", 327 244 vsc_startp, vsc_endp, vd_start_lines, vd_end_lines); 328 245 246 + afbc_top = round_down(vd_start_lines, 4); 247 + afbc_bottom = round_up(vd_end_lines + 1, 4); 248 + afbc_top_src = 0; 249 + afbc_bottom_src = round_up(h_in + 1, 4); 250 + 251 + DRM_DEBUG("afbc top %d (src %d) bottom %d (src %d)\n", 252 + afbc_top, afbc_top_src, afbc_bottom, afbc_bottom_src); 253 + 329 254 /* Horizontal */ 330 255 331 256 start = video_left + video_width / 2 - ((w_in << 17) / ratio_x); ··· 369 278 DRM_DEBUG("hsc startp %d endp %d start_lines %d end_lines %d\n", 370 279 hsc_startp, hsc_endp, hd_start_lines, hd_end_lines); 371 280 281 + if (hd_start_lines > 0 || (hd_end_lines < w_in)) { 282 + afbc_left = 0; 283 + afbc_right = round_up(w_in, 32); 284 + } else { 285 + afbc_left = round_down(hd_start_lines, 32); 286 + afbc_right = round_up(hd_end_lines + 1, 32); 287 + } 288 + 289 + DRM_DEBUG("afbc left %d right %d\n", afbc_left, afbc_right); 290 + 372 291 priv->viu.vpp_vsc_start_phase_step = ratio_y << 6; 373 292 374 293 priv->viu.vpp_vsc_ini_phase = vphase << 8; ··· 393 292 priv->viu.viu_vd1_fmt_w = 394 293 VD_H_WIDTH(hd_end_lines - hd_start_lines + 1) | 395 294 VD_V_WIDTH(hd_end_lines/2 - hd_start_lines/2 + 1); 295 + 296 + priv->viu.vd1_afbc_vd_cfmt_w = 297 + AFBC_VD_H_WIDTH(afbc_right - afbc_left) | 298 + AFBC_VD_V_WIDTH(afbc_right / 2 - afbc_left / 2); 299 + 300 + priv->viu.vd1_afbc_vd_cfmt_h = 301 + AFBC_VD_HEIGHT((afbc_bottom - afbc_top) / 2); 302 + 303 + priv->viu.vd1_afbc_mif_hor_scope = AFBC_MIF_BLK_BGN_H(afbc_left / 32) | 304 + AFBC_MIF_BLK_END_H((afbc_right / 32) - 1); 305 + 306 + priv->viu.vd1_afbc_mif_ver_scope = AFBC_MIF_BLK_BGN_V(afbc_top / 4) | 307 + AFBC_MIF_BLK_END_H((afbc_bottom / 4) - 1); 308 + 309 + priv->viu.vd1_afbc_size_out = 310 + AFBC_HSIZE_OUT(afbc_right - afbc_left) | 311 + AFBC_VSIZE_OUT(afbc_bottom - afbc_top); 312 + 313 + priv->viu.vd1_afbc_pixel_hor_scope = 314 + AFBC_DEC_PIXEL_BGN_H(hd_start_lines - afbc_left) | 315 + AFBC_DEC_PIXEL_END_H(hd_end_lines - afbc_left); 316 + 317 + priv->viu.vd1_afbc_pixel_ver_scope = 318 + AFBC_DEC_PIXEL_BGN_V(vd_start_lines - afbc_top) | 319 + AFBC_DEC_PIXEL_END_V(vd_end_lines - afbc_top); 320 + 321 + priv->viu.vd1_afbc_size_in = 322 + AFBC_HSIZE_IN(afbc_right - afbc_left) | 323 + AFBC_VSIZE_IN(afbc_bottom_src - afbc_top_src); 396 324 397 325 priv->viu.vd1_if0_luma_y0 = VD_Y_START(vd_start_lines) | 398 326 VD_Y_END(vd_end_lines); ··· 480 350 481 351 spin_lock_irqsave(&priv->drm->event_lock, flags); 482 352 483 - priv->viu.vd1_if0_gen_reg = VD_URGENT_CHROMA | 484 - VD_URGENT_LUMA | 485 - VD_HOLD_LINES(9) | 486 - VD_CHRO_RPT_LASTL_CTRL | 487 - VD_ENABLE; 353 + if ((fb->modifier & DRM_FORMAT_MOD_AMLOGIC_FBC(0, 0)) == 354 + DRM_FORMAT_MOD_AMLOGIC_FBC(0, 0)) { 355 + priv->viu.vd1_afbc = true; 356 + 357 + priv->viu.vd1_afbc_mode = AFBC_MIF_URGENT(3) | 358 + AFBC_HOLD_LINE_NUM(8) | 359 + AFBC_BURST_LEN(2); 360 + 361 + if (fb->modifier & DRM_FORMAT_MOD_AMLOGIC_FBC(0, 362 + AMLOGIC_FBC_OPTION_MEM_SAVING)) 363 + priv->viu.vd1_afbc_mode |= AFBC_BLK_MEM_MODE; 364 + 365 + if ((fb->modifier & __fourcc_mod_amlogic_layout_mask) == 366 + AMLOGIC_FBC_LAYOUT_SCATTER) 367 + priv->viu.vd1_afbc_mode |= AFBC_SCATTER_MODE; 368 + 369 + priv->viu.vd1_afbc_en = 0x1600 | AFBC_DEC_ENABLE; 370 + 371 + priv->viu.vd1_afbc_conv_ctrl = AFBC_CONV_LBUF_LEN(256); 372 + 373 + priv->viu.vd1_afbc_dec_def_color = AFBC_DEF_COLOR_Y(1023); 374 + 375 + /* 420: horizontal / 2, vertical / 4 */ 376 + priv->viu.vd1_afbc_vd_cfmt_ctrl = AFBC_HORZ_RPT_PIXEL0 | 377 + AFBC_HORZ_Y_C_RATIO(1) | 378 + AFBC_HORZ_FMT_EN | 379 + AFBC_VERT_RPT_LINE0 | 380 + AFBC_VERT_INITIAL_PHASE(12) | 381 + AFBC_VERT_PHASE_STEP(8) | 382 + AFBC_VERT_FMT_EN; 383 + 384 + switch (fb->format->format) { 385 + /* AFBC Only formats */ 386 + case DRM_FORMAT_YUV420_10BIT: 387 + priv->viu.vd1_afbc_mode |= 388 + AFBC_COMPBITS_YUV(AFBC_COMPBITS_10BIT); 389 + priv->viu.vd1_afbc_dec_def_color |= 390 + AFBC_DEF_COLOR_U(512) | 391 + AFBC_DEF_COLOR_V(512); 392 + break; 393 + case DRM_FORMAT_YUV420_8BIT: 394 + priv->viu.vd1_afbc_dec_def_color |= 395 + AFBC_DEF_COLOR_U(128) | 396 + AFBC_DEF_COLOR_V(128); 397 + break; 398 + } 399 + 400 + priv->viu.vd1_if0_gen_reg = 0; 401 + priv->viu.vd1_if0_canvas0 = 0; 402 + priv->viu.viu_vd1_fmt_ctrl = 0; 403 + } else { 404 + priv->viu.vd1_afbc = false; 405 + 406 + priv->viu.vd1_if0_gen_reg = VD_URGENT_CHROMA | 407 + VD_URGENT_LUMA | 408 + VD_HOLD_LINES(9) | 409 + VD_CHRO_RPT_LASTL_CTRL | 410 + VD_ENABLE; 411 + } 488 412 489 413 /* Setup scaler params */ 490 414 meson_overlay_setup_scaler_params(priv, plane, interlace_mode); ··· 554 370 priv->viu.vd1_if0_gen_reg2 = 0; 555 371 priv->viu.viu_vd1_fmt_ctrl = 0; 556 372 373 + /* None will match for AFBC Only formats */ 557 374 switch (fb->format->format) { 558 375 /* TOFIX DRM_FORMAT_RGB888 should be supported */ 559 376 case DRM_FORMAT_YUYV: ··· 673 488 priv->viu.vd1_stride0 = fb->pitches[0]; 674 489 priv->viu.vd1_height0 = 675 490 drm_format_info_plane_height(fb->format, 676 - fb->height, 0); 491 + fb->height, 0); 677 492 DRM_DEBUG("plane 0 addr 0x%x stride %d height %d\n", 678 493 priv->viu.vd1_addr0, 679 494 priv->viu.vd1_stride0, 680 495 priv->viu.vd1_height0); 496 + } 497 + 498 + if (priv->viu.vd1_afbc) { 499 + if (priv->viu.vd1_afbc_mode & AFBC_SCATTER_MODE) { 500 + /* 501 + * In Scatter mode, the header contains the physical 502 + * body content layout, thus the body content 503 + * size isn't needed. 504 + */ 505 + priv->viu.vd1_afbc_head_addr = priv->viu.vd1_addr0 >> 4; 506 + priv->viu.vd1_afbc_body_addr = 0; 507 + } else { 508 + /* Default mode is 4k per superblock */ 509 + unsigned long block_size = 4096; 510 + unsigned long body_size; 511 + 512 + /* 8bit mem saving mode is 3072bytes per superblock */ 513 + if (priv->viu.vd1_afbc_mode & AFBC_BLK_MEM_MODE) 514 + block_size = 3072; 515 + 516 + body_size = (ALIGN(priv->viu.vd1_stride0, 64) / 64) * 517 + (ALIGN(priv->viu.vd1_height0, 32) / 32) * 518 + block_size; 519 + 520 + priv->viu.vd1_afbc_body_addr = priv->viu.vd1_addr0 >> 4; 521 + /* Header is after body content */ 522 + priv->viu.vd1_afbc_head_addr = (priv->viu.vd1_addr0 + 523 + body_size) >> 4; 524 + } 681 525 } 682 526 683 527 priv->viu.vd1_enabled = true; ··· 745 531 .prepare_fb = drm_gem_fb_prepare_fb, 746 532 }; 747 533 534 + static bool meson_overlay_format_mod_supported(struct drm_plane *plane, 535 + u32 format, u64 modifier) 536 + { 537 + if (modifier == DRM_FORMAT_MOD_LINEAR && 538 + format != DRM_FORMAT_YUV420_8BIT && 539 + format != DRM_FORMAT_YUV420_10BIT) 540 + return true; 541 + 542 + if ((modifier & DRM_FORMAT_MOD_AMLOGIC_FBC(0, 0)) == 543 + DRM_FORMAT_MOD_AMLOGIC_FBC(0, 0)) { 544 + unsigned int layout = modifier & 545 + DRM_FORMAT_MOD_AMLOGIC_FBC( 546 + __fourcc_mod_amlogic_layout_mask, 0); 547 + unsigned int options = 548 + (modifier >> __fourcc_mod_amlogic_options_shift) & 549 + __fourcc_mod_amlogic_options_mask; 550 + 551 + if (format != DRM_FORMAT_YUV420_8BIT && 552 + format != DRM_FORMAT_YUV420_10BIT) { 553 + DRM_DEBUG_KMS("%llx invalid format 0x%08x\n", 554 + modifier, format); 555 + return false; 556 + } 557 + 558 + if (layout != AMLOGIC_FBC_LAYOUT_BASIC && 559 + layout != AMLOGIC_FBC_LAYOUT_SCATTER) { 560 + DRM_DEBUG_KMS("%llx invalid layout %x\n", 561 + modifier, layout); 562 + return false; 563 + } 564 + 565 + if (options && 566 + options != AMLOGIC_FBC_OPTION_MEM_SAVING) { 567 + DRM_DEBUG_KMS("%llx invalid layout %x\n", 568 + modifier, layout); 569 + return false; 570 + } 571 + 572 + return true; 573 + } 574 + 575 + DRM_DEBUG_KMS("invalid modifier %llx for format 0x%08x\n", 576 + modifier, format); 577 + 578 + return false; 579 + } 580 + 748 581 static const struct drm_plane_funcs meson_overlay_funcs = { 749 582 .update_plane = drm_atomic_helper_update_plane, 750 583 .disable_plane = drm_atomic_helper_disable_plane, ··· 799 538 .reset = drm_atomic_helper_plane_reset, 800 539 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 801 540 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 541 + .format_mod_supported = meson_overlay_format_mod_supported, 802 542 }; 803 543 804 544 static const uint32_t supported_drm_formats[] = { ··· 811 549 DRM_FORMAT_YUV420, 812 550 DRM_FORMAT_YUV411, 813 551 DRM_FORMAT_YUV410, 552 + DRM_FORMAT_YUV420_8BIT, /* Amlogic FBC Only */ 553 + DRM_FORMAT_YUV420_10BIT, /* Amlogic FBC Only */ 554 + }; 555 + 556 + static const uint64_t format_modifiers[] = { 557 + DRM_FORMAT_MOD_AMLOGIC_FBC(AMLOGIC_FBC_LAYOUT_SCATTER, 558 + AMLOGIC_FBC_OPTION_MEM_SAVING), 559 + DRM_FORMAT_MOD_AMLOGIC_FBC(AMLOGIC_FBC_LAYOUT_BASIC, 560 + AMLOGIC_FBC_OPTION_MEM_SAVING), 561 + DRM_FORMAT_MOD_AMLOGIC_FBC(AMLOGIC_FBC_LAYOUT_SCATTER, 0), 562 + DRM_FORMAT_MOD_AMLOGIC_FBC(AMLOGIC_FBC_LAYOUT_BASIC, 0), 563 + DRM_FORMAT_MOD_LINEAR, 564 + DRM_FORMAT_MOD_INVALID, 814 565 }; 815 566 816 567 int meson_overlay_create(struct meson_drm *priv) ··· 845 570 &meson_overlay_funcs, 846 571 supported_drm_formats, 847 572 ARRAY_SIZE(supported_drm_formats), 848 - NULL, 573 + format_modifiers, 849 574 DRM_PLANE_TYPE_OVERLAY, "meson_overlay_plane"); 850 575 851 576 drm_plane_helper_add(plane, &meson_overlay_helper_funcs);
+22
drivers/gpu/drm/meson/meson_registers.h
··· 144 144 #define VIU_SW_RESET_OSD1 BIT(0) 145 145 #define VIU_MISC_CTRL0 0x1a06 146 146 #define VIU_CTRL0_VD1_AFBC_MASK 0x170000 147 + #define VIU_CTRL0_AFBC_TO_VD1 BIT(20) 147 148 #define VIU_MISC_CTRL1 0x1a07 148 149 #define MALI_AFBC_MISC GENMASK(15, 8) 149 150 #define D2D3_INTF_LENGTH 0x1a08 150 151 #define D2D3_INTF_CTRL0 0x1a09 152 + #define VD1_AFBCD0_MISC_CTRL 0x1a0a 153 + #define VD1_AXI_SEL_AFBC (1 << 12) 154 + #define AFBC_VD1_SEL (1 << 10) 155 + #define VD2_AFBCD1_MISC_CTRL 0x1a0b 151 156 #define VIU_OSD1_CTRL_STAT 0x1a10 152 157 #define VIU_OSD1_OSD_BLK_ENABLE BIT(0) 153 158 #define VIU_OSD1_OSD_MEM_MODE_LINEAR BIT(2) ··· 370 365 #define VIU_OSD1_OETF_LUT_ADDR_PORT 0x1add 371 366 #define VIU_OSD1_OETF_LUT_DATA_PORT 0x1ade 372 367 #define AFBC_ENABLE 0x1ae0 368 + #define AFBC_MODE 0x1ae1 369 + #define AFBC_SIZE_IN 0x1ae2 370 + #define AFBC_DEC_DEF_COLOR 0x1ae3 371 + #define AFBC_CONV_CTRL 0x1ae4 372 + #define AFBC_LBUF_DEPTH 0x1ae5 373 + #define AFBC_HEAD_BADDR 0x1ae6 374 + #define AFBC_BODY_BADDR 0x1ae7 375 + #define AFBC_SIZE_OUT 0x1ae8 376 + #define AFBC_OUT_YSCOPE 0x1ae9 377 + #define AFBC_STAT 0x1aea 378 + #define AFBC_VD_CFMT_CTRL 0x1aeb 379 + #define AFBC_VD_CFMT_W 0x1aec 380 + #define AFBC_MIF_HOR_SCOPE 0x1aed 381 + #define AFBC_MIF_VER_SCOPE 0x1aee 382 + #define AFBC_PIXEL_HOR_SCOPE 0x1aef 383 + #define AFBC_PIXEL_VER_SCOPE 0x1af0 384 + #define AFBC_VD_CFMT_H 0x1af1 373 385 374 386 /* vpp */ 375 387 #define VPP_DUMMY_DATA 0x1d00
+6
drivers/gpu/drm/mgag200/mgag200_drv.h
··· 60 60 WREG8(MGAREG_SEQ_DATA, v); \ 61 61 } while (0) \ 62 62 63 + #define RREG_CRT(reg, v) \ 64 + do { \ 65 + WREG8(MGAREG_CRTC_INDEX, reg); \ 66 + v = RREG8(MGAREG_CRTC_DATA); \ 67 + } while (0) \ 68 + 63 69 #define WREG_CRT(reg, v) \ 64 70 do { \ 65 71 WREG8(MGAREG_CRTC_INDEX, reg); \
+59 -109
drivers/gpu/drm/mgag200/mgag200_mode.c
··· 712 712 return 0; 713 713 } 714 714 715 - static int mga_crtc_set_plls(struct mga_device *mdev, long clock) 715 + static int mgag200_crtc_set_plls(struct mga_device *mdev, long clock) 716 716 { 717 717 u8 misc; 718 718 ··· 745 745 return 0; 746 746 } 747 747 748 - static void mga_g200wb_prepare(struct drm_crtc *crtc) 748 + static void mgag200_g200wb_hold_bmc(struct mga_device *mdev) 749 749 { 750 - struct mga_device *mdev = to_mga_device(crtc->dev); 751 750 u8 tmp; 752 751 int iter_max; 753 752 ··· 798 799 } 799 800 } 800 801 801 - static void mga_g200wb_commit(struct drm_crtc *crtc) 802 + static void mgag200_g200wb_release_bmc(struct mga_device *mdev) 802 803 { 803 804 u8 tmp; 804 - struct mga_device *mdev = to_mga_device(crtc->dev); 805 805 806 806 /* 1- The first step is to ensure that the vrsten and hrsten are set */ 807 807 WREG8(MGAREG_CRTCEXT_INDEX, 1); ··· 986 988 987 989 static void mgag200_init_regs(struct mga_device *mdev) 988 990 { 989 - u8 crtcext3, crtcext4, misc; 991 + u8 crtc11, crtcext3, crtcext4, misc; 990 992 991 993 mgag200_set_pci_regs(mdev); 992 994 mgag200_set_dac_regs(mdev); ··· 1009 1011 1010 1012 WREG_ECRT(0x03, crtcext3); 1011 1013 WREG_ECRT(0x04, crtcext4); 1014 + 1015 + RREG_CRT(0x11, crtc11); 1016 + crtc11 &= ~(MGAREG_CRTC11_CRTCPROTECT | 1017 + MGAREG_CRTC11_VINTEN | 1018 + MGAREG_CRTC11_VINTCLR); 1019 + WREG_CRT(0x11, crtc11); 1012 1020 1013 1021 if (mdev->type == G200_ER) 1014 1022 WREG_ECRT(0x24, 0x5); ··· 1108 1104 WREG_ECRT(0x05, crtcext5); 1109 1105 1110 1106 WREG8(MGA_MISC_OUT, misc); 1111 - 1112 - mga_crtc_set_plls(mdev, mode->clock); 1113 1107 } 1114 1108 1115 1109 static u8 mgag200_get_bpp_shift(struct mga_device *mdev, ··· 1217 1215 static void mgag200_g200er_reset_tagfifo(struct mga_device *mdev) 1218 1216 { 1219 1217 static uint32_t RESET_FLAG = 0x00200000; /* undocumented magic value */ 1220 - u8 seq1; 1221 1218 u32 memctl; 1222 - 1223 - /* screen off */ 1224 - RREG_SEQ(0x01, seq1); 1225 - seq1 |= MGAREG_SEQ1_SCROFF; 1226 - WREG_SEQ(0x01, seq1); 1227 1219 1228 1220 memctl = RREG32(MGAREG_MEMCTL); 1229 1221 ··· 1228 1232 1229 1233 memctl &= ~RESET_FLAG; 1230 1234 WREG32(MGAREG_MEMCTL, memctl); 1231 - 1232 - /* screen on */ 1233 - RREG_SEQ(0x01, seq1); 1234 - seq1 &= ~MGAREG_SEQ1_SCROFF; 1235 - WREG_SEQ(0x01, seq1); 1236 1235 } 1237 1236 1238 1237 static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev, ··· 1280 1289 WREG_ECRT(0x06, 0x00); 1281 1290 } 1282 1291 1283 - static void mga_crtc_dpms(struct drm_crtc *crtc, int mode) 1292 + static void mgag200_enable_display(struct mga_device *mdev) 1284 1293 { 1285 - struct drm_device *dev = crtc->dev; 1286 - struct mga_device *mdev = to_mga_device(dev); 1287 - u8 seq1 = 0, crtcext1 = 0; 1294 + u8 seq0, seq1, crtcext1; 1288 1295 1289 - switch (mode) { 1290 - case DRM_MODE_DPMS_ON: 1291 - seq1 = 0; 1292 - crtcext1 = 0; 1293 - mga_crtc_load_lut(crtc); 1294 - break; 1295 - case DRM_MODE_DPMS_STANDBY: 1296 - seq1 = 0x20; 1297 - crtcext1 = 0x10; 1298 - break; 1299 - case DRM_MODE_DPMS_SUSPEND: 1300 - seq1 = 0x20; 1301 - crtcext1 = 0x20; 1302 - break; 1303 - case DRM_MODE_DPMS_OFF: 1304 - seq1 = 0x20; 1305 - crtcext1 = 0x30; 1306 - break; 1307 - } 1296 + RREG_SEQ(0x00, seq0); 1297 + seq0 |= MGAREG_SEQ0_SYNCRST | 1298 + MGAREG_SEQ0_ASYNCRST; 1299 + WREG_SEQ(0x00, seq0); 1308 1300 1309 - WREG8(MGAREG_SEQ_INDEX, 0x01); 1310 - seq1 |= RREG8(MGAREG_SEQ_DATA) & ~0x20; 1301 + /* 1302 + * TODO: replace busy waiting with vblank IRQ; put 1303 + * msleep(50) before changing SCROFF 1304 + */ 1311 1305 mga_wait_vsync(mdev); 1312 1306 mga_wait_busy(mdev); 1313 - WREG8(MGAREG_SEQ_DATA, seq1); 1307 + 1308 + RREG_SEQ(0x01, seq1); 1309 + seq1 &= ~MGAREG_SEQ1_SCROFF; 1310 + WREG_SEQ(0x01, seq1); 1311 + 1314 1312 msleep(20); 1315 - WREG8(MGAREG_CRTCEXT_INDEX, 0x01); 1316 - crtcext1 |= RREG8(MGAREG_CRTCEXT_DATA) & ~0x30; 1317 - WREG8(MGAREG_CRTCEXT_DATA, crtcext1); 1313 + 1314 + RREG_ECRT(0x01, crtcext1); 1315 + crtcext1 &= ~MGAREG_CRTCEXT1_VSYNCOFF; 1316 + crtcext1 &= ~MGAREG_CRTCEXT1_HSYNCOFF; 1317 + WREG_ECRT(0x01, crtcext1); 1318 1318 } 1319 1319 1320 - /* 1321 - * This is called before a mode is programmed. A typical use might be to 1322 - * enable DPMS during the programming to avoid seeing intermediate stages, 1323 - * but that's not relevant to us 1324 - */ 1325 - static void mga_crtc_prepare(struct drm_crtc *crtc) 1320 + static void mgag200_disable_display(struct mga_device *mdev) 1326 1321 { 1327 - struct drm_device *dev = crtc->dev; 1328 - struct mga_device *mdev = to_mga_device(dev); 1329 - u8 tmp; 1322 + u8 seq0, seq1, crtcext1; 1330 1323 1331 - /* mga_resume(crtc);*/ 1324 + RREG_SEQ(0x00, seq0); 1325 + seq0 &= ~MGAREG_SEQ0_SYNCRST; 1326 + WREG_SEQ(0x00, seq0); 1332 1327 1333 - WREG8(MGAREG_CRTC_INDEX, 0x11); 1334 - tmp = RREG8(MGAREG_CRTC_DATA); 1335 - WREG_CRT(0x11, tmp | 0x80); 1328 + /* 1329 + * TODO: replace busy waiting with vblank IRQ; put 1330 + * msleep(50) before changing SCROFF 1331 + */ 1332 + mga_wait_vsync(mdev); 1333 + mga_wait_busy(mdev); 1336 1334 1337 - if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) { 1338 - WREG_SEQ(0, 1); 1339 - msleep(50); 1340 - WREG_SEQ(1, 0x20); 1341 - msleep(20); 1342 - } else { 1343 - WREG8(MGAREG_SEQ_INDEX, 0x1); 1344 - tmp = RREG8(MGAREG_SEQ_DATA); 1335 + RREG_SEQ(0x01, seq1); 1336 + seq1 |= MGAREG_SEQ1_SCROFF; 1337 + WREG_SEQ(0x01, seq1); 1345 1338 1346 - /* start sync reset */ 1347 - WREG_SEQ(0, 1); 1348 - WREG_SEQ(1, tmp | 0x20); 1349 - } 1339 + msleep(20); 1350 1340 1351 - if (mdev->type == G200_WB || mdev->type == G200_EW3) 1352 - mga_g200wb_prepare(crtc); 1353 - 1354 - WREG_CRT(17, 0); 1355 - } 1356 - 1357 - /* 1358 - * This is called after a mode is programmed. It should reverse anything done 1359 - * by the prepare function 1360 - */ 1361 - static void mga_crtc_commit(struct drm_crtc *crtc) 1362 - { 1363 - struct drm_device *dev = crtc->dev; 1364 - struct mga_device *mdev = to_mga_device(dev); 1365 - u8 tmp; 1366 - 1367 - if (mdev->type == G200_WB || mdev->type == G200_EW3) 1368 - mga_g200wb_commit(crtc); 1369 - 1370 - if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) { 1371 - msleep(50); 1372 - WREG_SEQ(1, 0x0); 1373 - msleep(20); 1374 - WREG_SEQ(0, 0x3); 1375 - } else { 1376 - WREG8(MGAREG_SEQ_INDEX, 0x1); 1377 - tmp = RREG8(MGAREG_SEQ_DATA); 1378 - 1379 - tmp &= ~0x20; 1380 - WREG_SEQ(0x1, tmp); 1381 - WREG_SEQ(0, 3); 1382 - } 1383 - mga_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 1341 + RREG_ECRT(0x01, crtcext1); 1342 + crtcext1 |= MGAREG_CRTCEXT1_VSYNCOFF | 1343 + MGAREG_CRTCEXT1_HSYNCOFF; 1344 + WREG_ECRT(0x01, crtcext1); 1384 1345 } 1385 1346 1386 1347 /* ··· 1555 1612 .y2 = fb->height, 1556 1613 }; 1557 1614 1558 - mga_crtc_prepare(crtc); 1615 + if (mdev->type == G200_WB || mdev->type == G200_EW3) 1616 + mgag200_g200wb_hold_bmc(mdev); 1559 1617 1560 1618 mgag200_set_format_regs(mdev, fb); 1561 1619 mgag200_set_mode_regs(mdev, adjusted_mode); 1620 + mgag200_crtc_set_plls(mdev, adjusted_mode->clock); 1562 1621 1563 1622 if (mdev->type == G200_ER) 1564 1623 mgag200_g200er_reset_tagfifo(mdev); ··· 1570 1625 else if (mdev->type == G200_EV) 1571 1626 mgag200_g200ev_set_hiprilvl(mdev); 1572 1627 1573 - mga_crtc_commit(crtc); 1628 + if (mdev->type == G200_WB || mdev->type == G200_EW3) 1629 + mgag200_g200wb_release_bmc(mdev); 1630 + 1631 + mga_crtc_load_lut(crtc); 1632 + mgag200_enable_display(mdev); 1574 1633 1575 1634 mgag200_handle_damage(mdev, fb, &fullscreen); 1576 1635 } ··· 1583 1634 mgag200_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe) 1584 1635 { 1585 1636 struct drm_crtc *crtc = &pipe->crtc; 1637 + struct mga_device *mdev = to_mga_device(crtc->dev); 1586 1638 1587 - mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 1639 + mgag200_disable_display(mdev); 1588 1640 } 1589 1641 1590 1642 static int
+11
drivers/gpu/drm/mgag200/mgag200_reg.h
··· 236 236 #define MGAREG_SEQ_INDEX 0x1fc4 237 237 #define MGAREG_SEQ_DATA 0x1fc5 238 238 239 + #define MGAREG_SEQ0_ASYNCRST BIT(0) 240 + #define MGAREG_SEQ0_SYNCRST BIT(1) 241 + 239 242 #define MGAREG_SEQ1_SCROFF BIT(5) 240 243 241 244 #define MGAREG_CRTC_INDEX 0x1fd4 242 245 #define MGAREG_CRTC_DATA 0x1fd5 246 + 247 + #define MGAREG_CRTC11_VINTCLR BIT(4) 248 + #define MGAREG_CRTC11_VINTEN BIT(5) 249 + #define MGAREG_CRTC11_CRTCPROTECT BIT(7) 250 + 243 251 #define MGAREG_CRTCEXT_INDEX 0x1fde 244 252 #define MGAREG_CRTCEXT_DATA 0x1fdf 245 253 246 254 #define MGAREG_CRTCEXT0_OFFSET_MASK GENMASK(5, 4) 255 + 256 + #define MGAREG_CRTCEXT1_VSYNCOFF BIT(5) 257 + #define MGAREG_CRTCEXT1_HSYNCOFF BIT(4) 247 258 248 259 /* Cursor X and Y position */ 249 260 #define MGA_CURPOSXL 0x3c0c
-2
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
··· 1117 1117 mdp5_crtc_destroy_state(crtc, crtc->state); 1118 1118 1119 1119 __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base); 1120 - 1121 - drm_crtc_vblank_reset(crtc); 1122 1120 } 1123 1121 1124 1122 static const struct drm_crtc_funcs mdp5_crtc_funcs = {
+3 -3
drivers/gpu/drm/nouveau/dispnv04/crtc.c
··· 845 845 } 846 846 847 847 nvbo = nouveau_gem_object(drm_fb->obj[0]); 848 - nv_crtc->fb.offset = nvbo->bo.offset; 848 + nv_crtc->fb.offset = nvbo->offset; 849 849 850 850 if (nv_crtc->lut.depth != drm_fb->format->depth) { 851 851 nv_crtc->lut.depth = drm_fb->format->depth; ··· 1013 1013 nv04_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo); 1014 1014 1015 1015 nouveau_bo_unmap(cursor); 1016 - nv_crtc->cursor.offset = nv_crtc->cursor.nvbo->bo.offset; 1016 + nv_crtc->cursor.offset = nv_crtc->cursor.nvbo->offset; 1017 1017 nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); 1018 1018 nv_crtc->cursor.show(nv_crtc, true); 1019 1019 out: ··· 1192 1192 /* Initialize a page flip struct */ 1193 1193 *s = (struct nv04_page_flip_state) 1194 1194 { { }, event, crtc, fb->format->cpp[0] * 8, fb->pitches[0], 1195 - new_bo->bo.offset }; 1195 + new_bo->offset }; 1196 1196 1197 1197 /* Keep vblanks on during flip, for the target crtc of this flip */ 1198 1198 drm_crtc_vblank_get(crtc);
+2 -1
drivers/gpu/drm/nouveau/dispnv04/disp.c
··· 152 152 continue; 153 153 154 154 if (nv_crtc->cursor.set_offset) 155 - nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset); 155 + nv_crtc->cursor.set_offset(nv_crtc, 156 + nv_crtc->cursor.nvbo->offset); 156 157 nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, 157 158 nv_crtc->cursor_saved_y); 158 159 }
+3 -3
drivers/gpu/drm/nouveau/dispnv04/overlay.c
··· 152 152 nvif_mask(dev, NV_PCRTC_ENGINE_CTRL + soff2, NV_CRTC_FSEL_OVERLAY, 0); 153 153 154 154 nvif_wr32(dev, NV_PVIDEO_BASE(flip), 0); 155 - nvif_wr32(dev, NV_PVIDEO_OFFSET_BUFF(flip), nvbo->bo.offset); 155 + nvif_wr32(dev, NV_PVIDEO_OFFSET_BUFF(flip), nvbo->offset); 156 156 nvif_wr32(dev, NV_PVIDEO_SIZE_IN(flip), src_h << 16 | src_w); 157 157 nvif_wr32(dev, NV_PVIDEO_POINT_IN(flip), src_y << 16 | src_x); 158 158 nvif_wr32(dev, NV_PVIDEO_DS_DX(flip), (src_w << 20) / crtc_w); ··· 174 174 if (format & NV_PVIDEO_FORMAT_PLANAR) { 175 175 nvif_wr32(dev, NV_PVIDEO_UVPLANE_BASE(flip), 0); 176 176 nvif_wr32(dev, NV_PVIDEO_UVPLANE_OFFSET_BUFF(flip), 177 - nvbo->bo.offset + fb->offsets[1]); 177 + nvbo->offset + fb->offsets[1]); 178 178 } 179 179 nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format | fb->pitches[0]); 180 180 nvif_wr32(dev, NV_PVIDEO_STOP, 0); ··· 399 399 400 400 for (i = 0; i < 2; i++) { 401 401 nvif_wr32(dev, NV_PVIDEO_BUFF0_START_ADDRESS + 4 * i, 402 - nvbo->bo.offset); 402 + nvbo->offset); 403 403 nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i, 404 404 fb->pitches[0]); 405 405 nvif_wr32(dev, NV_PVIDEO_BUFF0_OFFSET + 4 * i, 0);
+1 -1
drivers/gpu/drm/nouveau/dispnv50/base507c.c
··· 276 276 277 277 ret = nv50_dmac_create(&drm->client.device, &disp->disp.object, 278 278 &oclass, head, &args, sizeof(args), 279 - disp50->sync->bo.offset, &wndw->wndw); 279 + disp50->sync->offset, &wndw->wndw); 280 280 if (ret) { 281 281 NV_ERROR(drm, "base%04x allocation failed: %d\n", oclass, ret); 282 282 return ret;
+1 -1
drivers/gpu/drm/nouveau/dispnv50/core507d.c
··· 115 115 116 116 ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, 117 117 &oclass, 0, &args, sizeof(args), 118 - disp->sync->bo.offset, &core->chan); 118 + disp->sync->offset, &core->chan); 119 119 if (ret) { 120 120 NV_ERROR(drm, "core%04x allocation failed: %d\n", oclass, ret); 121 121 return ret;
+1 -1
drivers/gpu/drm/nouveau/dispnv50/ovly507e.c
··· 186 186 187 187 ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, 188 188 &oclass, 0, &args, sizeof(args), 189 - disp->sync->bo.offset, &wndw->wndw); 189 + disp->sync->offset, &wndw->wndw); 190 190 if (ret) { 191 191 NV_ERROR(drm, "ovly%04x allocation failed: %d\n", oclass, ret); 192 192 return ret;
+1 -1
drivers/gpu/drm/nouveau/dispnv50/wndw.c
··· 526 526 } 527 527 528 528 asyw->state.fence = dma_resv_get_excl_rcu(nvbo->bo.base.resv); 529 - asyw->image.offset[0] = nvbo->bo.offset; 529 + asyw->image.offset[0] = nvbo->offset; 530 530 531 531 if (wndw->func->prepare) { 532 532 asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc);
+1 -1
drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c
··· 298 298 299 299 ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, 300 300 &oclass, 0, &args, sizeof(args), 301 - disp->sync->bo.offset, &wndw->wndw); 301 + disp->sync->offset, &wndw->wndw); 302 302 if (ret) { 303 303 NV_ERROR(drm, "qndw%04x allocation failed: %d\n", oclass, ret); 304 304 return ret;
+4 -4
drivers/gpu/drm/nouveau/nouveau_abi16.c
··· 558 558 if (drm->agp.bridge) { 559 559 args.target = NV_DMA_V0_TARGET_AGP; 560 560 args.access = NV_DMA_V0_ACCESS_RDWR; 561 - args.start += drm->agp.base + chan->ntfy->bo.offset; 562 - args.limit += drm->agp.base + chan->ntfy->bo.offset; 561 + args.start += drm->agp.base + chan->ntfy->offset; 562 + args.limit += drm->agp.base + chan->ntfy->offset; 563 563 } else { 564 564 args.target = NV_DMA_V0_TARGET_VM; 565 565 args.access = NV_DMA_V0_ACCESS_RDWR; 566 - args.start += chan->ntfy->bo.offset; 567 - args.limit += chan->ntfy->bo.offset; 566 + args.start += chan->ntfy->offset; 567 + args.limit += chan->ntfy->offset; 568 568 } 569 569 570 570 client->route = NVDRM_OBJECT_ABI16;
+8
drivers/gpu/drm/nouveau/nouveau_bo.c
··· 1317 1317 nouveau_vma_unmap(vma); 1318 1318 } 1319 1319 } 1320 + 1321 + if (new_reg) { 1322 + if (new_reg->mm_node) 1323 + nvbo->offset = (new_reg->start << PAGE_SHIFT); 1324 + else 1325 + nvbo->offset = 0; 1326 + } 1327 + 1320 1328 } 1321 1329 1322 1330 static int
+3
drivers/gpu/drm/nouveau/nouveau_bo.h
··· 24 24 int pbbo_index; 25 25 bool validate_mapped; 26 26 27 + /* GPU address space is independent of CPU word size */ 28 + uint64_t offset; 29 + 27 30 struct list_head vma_list; 28 31 29 32 unsigned contig:1;
+1 -1
drivers/gpu/drm/nouveau/nouveau_chan.c
··· 162 162 * pushbuf lives in, this is because the GEM code requires that 163 163 * we be able to call out to other (indirect) push buffers 164 164 */ 165 - chan->push.addr = chan->push.buffer->bo.offset; 165 + chan->push.addr = chan->push.buffer->offset; 166 166 167 167 if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { 168 168 ret = nouveau_vma_new(chan->push.buffer, chan->vmm,
+1 -1
drivers/gpu/drm/nouveau/nouveau_dmem.c
··· 100 100 unsigned long off = (page_to_pfn(page) << PAGE_SHIFT) - 101 101 chunk->pagemap.res.start; 102 102 103 - return chunk->bo->bo.offset + off; 103 + return chunk->bo->offset + off; 104 104 } 105 105 106 106 static void nouveau_dmem_page_free(struct page *page)
+1 -1
drivers/gpu/drm/nouveau/nouveau_fbcon.c
··· 393 393 394 394 /* To allow resizeing without swapping buffers */ 395 395 NV_INFO(drm, "allocated %dx%d fb: 0x%llx, bo %p\n", 396 - fb->width, fb->height, nvbo->bo.offset, nvbo); 396 + fb->width, fb->height, nvbo->offset, nvbo); 397 397 398 398 vga_switcheroo_client_fb_set(dev->pdev, info); 399 399 return 0;
+5 -5
drivers/gpu/drm/nouveau/nouveau_gem.c
··· 234 234 rep->domain = NOUVEAU_GEM_DOMAIN_GART; 235 235 else 236 236 rep->domain = NOUVEAU_GEM_DOMAIN_VRAM; 237 - rep->offset = nvbo->bo.offset; 237 + rep->offset = nvbo->offset; 238 238 if (vmm->vmm.object.oclass >= NVIF_CLASS_VMM_NV50) { 239 239 vma = nouveau_vma_find(nvbo, vmm); 240 240 if (!vma) ··· 518 518 } 519 519 520 520 if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA) { 521 - if (nvbo->bo.offset == b->presumed.offset && 521 + if (nvbo->offset == b->presumed.offset && 522 522 ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && 523 523 b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || 524 524 (nvbo->bo.mem.mem_type == TTM_PL_TT && ··· 529 529 b->presumed.domain = NOUVEAU_GEM_DOMAIN_GART; 530 530 else 531 531 b->presumed.domain = NOUVEAU_GEM_DOMAIN_VRAM; 532 - b->presumed.offset = nvbo->bo.offset; 532 + b->presumed.offset = nvbo->offset; 533 533 b->presumed.valid = 0; 534 534 relocs++; 535 535 } ··· 807 807 struct nouveau_bo *nvbo = (void *)(unsigned long) 808 808 bo[push[i].bo_index].user_priv; 809 809 810 - OUT_RING(chan, (nvbo->bo.offset + push[i].offset) | 2); 810 + OUT_RING(chan, (nvbo->offset + push[i].offset) | 2); 811 811 OUT_RING(chan, 0); 812 812 } 813 813 } else { ··· 842 842 } 843 843 844 844 OUT_RING(chan, 0x20000000 | 845 - (nvbo->bo.offset + push[i].offset)); 845 + (nvbo->offset + push[i].offset)); 846 846 OUT_RING(chan, 0); 847 847 for (j = 0; j < NOUVEAU_DMA_SKIPS; j++) 848 848 OUT_RING(chan, 0);
-8
drivers/gpu/drm/nouveau/nouveau_ttm.c
··· 75 75 ret = nouveau_mem_vram(reg, nvbo->contig, nvbo->page); 76 76 if (ret) { 77 77 nouveau_mem_del(reg); 78 - if (ret == -ENOSPC) { 79 - reg->mm_node = NULL; 80 - return 0; 81 - } 82 78 return ret; 83 79 } 84 80 ··· 135 139 reg->num_pages << PAGE_SHIFT, &mem->vma[0]); 136 140 if (ret) { 137 141 nouveau_mem_del(reg); 138 - if (ret == -ENOSPC) { 139 - reg->mm_node = NULL; 140 - return 0; 141 - } 142 142 return ret; 143 143 } 144 144
+5 -3
drivers/gpu/drm/omapdrm/omap_crtc.c
··· 697 697 698 698 static void omap_crtc_reset(struct drm_crtc *crtc) 699 699 { 700 + struct omap_crtc_state *state; 701 + 700 702 if (crtc->state) 701 703 __drm_atomic_helper_crtc_destroy_state(crtc->state); 702 704 703 705 kfree(crtc->state); 704 - crtc->state = kzalloc(sizeof(struct omap_crtc_state), GFP_KERNEL); 705 706 706 - if (crtc->state) 707 - crtc->state->crtc = crtc; 707 + state = kzalloc(sizeof(*state), GFP_KERNEL); 708 + if (state) 709 + __drm_atomic_helper_crtc_reset(crtc, &state->base); 708 710 } 709 711 710 712 static struct drm_crtc_state *
-4
drivers/gpu/drm/omapdrm/omap_drv.c
··· 595 595 { 596 596 const struct soc_device_attribute *soc; 597 597 struct drm_device *ddev; 598 - unsigned int i; 599 598 int ret; 600 599 601 600 DBG("%s", dev_name(dev)); ··· 640 641 dev_err(priv->dev, "could not init vblank\n"); 641 642 goto err_cleanup_modeset; 642 643 } 643 - 644 - for (i = 0; i < priv->num_pipes; i++) 645 - drm_crtc_vblank_off(priv->pipes[i].crtc); 646 644 647 645 omap_fbdev_init(ddev); 648 646
+13 -13
drivers/gpu/drm/panel/Kconfig
··· 283 283 Say Y here if you want to enable support for Raydium RM68200 284 284 720x1280 DSI video mode panel. 285 285 286 - config DRM_PANEL_ROCKTECH_JH057N00900 287 - tristate "Rocktech JH057N00900 MIPI touchscreen panel" 288 - depends on OF 289 - depends on DRM_MIPI_DSI 290 - depends on BACKLIGHT_CLASS_DEVICE 291 - help 292 - Say Y here if you want to enable support for Rocktech JH057N00900 293 - MIPI DSI panel as e.g. used in the Librem 5 devkit. It has a 294 - resolution of 720x1440 pixels, a built in backlight and touch 295 - controller. 296 - Touch input support is provided by the goodix driver and needs to be 297 - selected separately. 298 - 299 286 config DRM_PANEL_RONBO_RB070D30 300 287 tristate "Ronbo Electronics RB070D30 panel" 301 288 depends on OF ··· 381 394 Say Y here if you want to enable support for the Sitronix 382 395 ST7701 controller for 480X864 LCD panels with MIPI/RGB/SPI 383 396 system interfaces. 397 + 398 + config DRM_PANEL_SITRONIX_ST7703 399 + tristate "Sitronix ST7703 based MIPI touchscreen panels" 400 + depends on OF 401 + depends on DRM_MIPI_DSI 402 + depends on BACKLIGHT_CLASS_DEVICE 403 + help 404 + Say Y here if you want to enable support for Sitronix ST7703 based 405 + panels, souch as Rocktech JH057N00900 MIPI DSI panel as e.g. used in 406 + the Librem 5 devkit. It has a resolution of 720x1440 pixels, a built 407 + in backlight and touch controller. 408 + Touch input support is provided by the goodix driver and needs to be 409 + selected separately. 384 410 385 411 config DRM_PANEL_SITRONIX_ST7789V 386 412 tristate "Sitronix ST7789V panel"
+1 -1
drivers/gpu/drm/panel/Makefile
··· 27 27 obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o 28 28 obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o 29 29 obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o 30 - obj-$(CONFIG_DRM_PANEL_ROCKTECH_JH057N00900) += panel-rocktech-jh057n00900.o 31 30 obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o 32 31 obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o 33 32 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o ··· 40 41 obj-$(CONFIG_DRM_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 41 42 obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o 42 43 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o 44 + obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7703) += panel-sitronix-st7703.o 43 45 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o 44 46 obj-$(CONFIG_DRM_PANEL_SONY_ACX424AKP) += panel-sony-acx424akp.o 45 47 obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
+2 -2
drivers/gpu/drm/panel/panel-elida-kd35t133.c
··· 52 52 } 53 53 54 54 #define dsi_dcs_write_seq(dsi, cmd, seq...) do { \ 55 - static const u8 d[] = { seq }; \ 55 + static const u8 b[] = { cmd, seq }; \ 56 56 int ret; \ 57 - ret = mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d)); \ 57 + ret = mipi_dsi_dcs_write_buffer(dsi, b, ARRAY_SIZE(b)); \ 58 58 if (ret < 0) \ 59 59 return ret; \ 60 60 } while (0)
+2 -2
drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
··· 246 246 } 247 247 248 248 #define dsi_dcs_write_seq(dsi, cmd, seq...) do { \ 249 - static const u8 d[] = { seq }; \ 249 + static const u8 b[] = { cmd, seq }; \ 250 250 int ret; \ 251 - ret = mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d)); \ 251 + ret = mipi_dsi_dcs_write_buffer(dsi, b, ARRAY_SIZE(b)); \ 252 252 if (ret < 0) \ 253 253 return ret; \ 254 254 } while (0)
+1 -1
drivers/gpu/drm/panel/panel-novatek-nt39016.c
··· 357 357 .width_mm = 71, 358 358 .height_mm = 53, 359 359 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 360 - .bus_flags = DRM_BUS_FLAG_PIXDATA_NEGEDGE, 360 + .bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, 361 361 }; 362 362 363 363 static const struct of_device_id nt39016_of_match[] = {
+1 -1
drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com 3 + * Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com 4 4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> 5 5 */ 6 6
+1 -1
drivers/gpu/drm/panel/panel-raydium-rm67191.c
··· 192 192 }; 193 193 194 194 static const u32 rad_bus_flags = DRM_BUS_FLAG_DE_LOW | 195 - DRM_BUS_FLAG_PIXDATA_NEGEDGE; 195 + DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE; 196 196 197 197 struct rad_panel { 198 198 struct drm_panel panel;
-423
drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Rockteck jh057n00900 5.5" MIPI-DSI panel driver 4 - * 5 - * Copyright (C) Purism SPC 2019 6 - */ 7 - 8 - #include <linux/debugfs.h> 9 - #include <linux/delay.h> 10 - #include <linux/gpio/consumer.h> 11 - #include <linux/media-bus-format.h> 12 - #include <linux/mod_devicetable.h> 13 - #include <linux/module.h> 14 - #include <linux/regulator/consumer.h> 15 - 16 - #include <video/display_timing.h> 17 - #include <video/mipi_display.h> 18 - 19 - #include <drm/drm_mipi_dsi.h> 20 - #include <drm/drm_modes.h> 21 - #include <drm/drm_panel.h> 22 - #include <drm/drm_print.h> 23 - 24 - #define DRV_NAME "panel-rocktech-jh057n00900" 25 - 26 - /* Manufacturer specific Commands send via DSI */ 27 - #define ST7703_CMD_ALL_PIXEL_OFF 0x22 28 - #define ST7703_CMD_ALL_PIXEL_ON 0x23 29 - #define ST7703_CMD_SETDISP 0xB2 30 - #define ST7703_CMD_SETRGBIF 0xB3 31 - #define ST7703_CMD_SETCYC 0xB4 32 - #define ST7703_CMD_SETBGP 0xB5 33 - #define ST7703_CMD_SETVCOM 0xB6 34 - #define ST7703_CMD_SETOTP 0xB7 35 - #define ST7703_CMD_SETPOWER_EXT 0xB8 36 - #define ST7703_CMD_SETEXTC 0xB9 37 - #define ST7703_CMD_SETMIPI 0xBA 38 - #define ST7703_CMD_SETVDC 0xBC 39 - #define ST7703_CMD_UNKNOWN0 0xBF 40 - #define ST7703_CMD_SETSCR 0xC0 41 - #define ST7703_CMD_SETPOWER 0xC1 42 - #define ST7703_CMD_SETPANEL 0xCC 43 - #define ST7703_CMD_SETGAMMA 0xE0 44 - #define ST7703_CMD_SETEQ 0xE3 45 - #define ST7703_CMD_SETGIP1 0xE9 46 - #define ST7703_CMD_SETGIP2 0xEA 47 - 48 - struct jh057n { 49 - struct device *dev; 50 - struct drm_panel panel; 51 - struct gpio_desc *reset_gpio; 52 - struct regulator *vcc; 53 - struct regulator *iovcc; 54 - bool prepared; 55 - 56 - struct dentry *debugfs; 57 - }; 58 - 59 - static inline struct jh057n *panel_to_jh057n(struct drm_panel *panel) 60 - { 61 - return container_of(panel, struct jh057n, panel); 62 - } 63 - 64 - #define dsi_generic_write_seq(dsi, seq...) do { \ 65 - static const u8 d[] = { seq }; \ 66 - int ret; \ 67 - ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \ 68 - if (ret < 0) \ 69 - return ret; \ 70 - } while (0) 71 - 72 - static int jh057n_init_sequence(struct jh057n *ctx) 73 - { 74 - struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 75 - struct device *dev = ctx->dev; 76 - int ret; 77 - 78 - /* 79 - * Init sequence was supplied by the panel vendor. Most of the commands 80 - * resemble the ST7703 but the number of parameters often don't match 81 - * so it's likely a clone. 82 - */ 83 - dsi_generic_write_seq(dsi, ST7703_CMD_SETEXTC, 84 - 0xF1, 0x12, 0x83); 85 - dsi_generic_write_seq(dsi, ST7703_CMD_SETRGBIF, 86 - 0x10, 0x10, 0x05, 0x05, 0x03, 0xFF, 0x00, 0x00, 87 - 0x00, 0x00); 88 - dsi_generic_write_seq(dsi, ST7703_CMD_SETSCR, 89 - 0x73, 0x73, 0x50, 0x50, 0x00, 0x00, 0x08, 0x70, 90 - 0x00); 91 - dsi_generic_write_seq(dsi, ST7703_CMD_SETVDC, 0x4E); 92 - dsi_generic_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0B); 93 - dsi_generic_write_seq(dsi, ST7703_CMD_SETCYC, 0x80); 94 - dsi_generic_write_seq(dsi, ST7703_CMD_SETDISP, 0xF0, 0x12, 0x30); 95 - dsi_generic_write_seq(dsi, ST7703_CMD_SETEQ, 96 - 0x07, 0x07, 0x0B, 0x0B, 0x03, 0x0B, 0x00, 0x00, 97 - 0x00, 0x00, 0xFF, 0x00, 0xC0, 0x10); 98 - dsi_generic_write_seq(dsi, ST7703_CMD_SETBGP, 0x08, 0x08); 99 - msleep(20); 100 - 101 - dsi_generic_write_seq(dsi, ST7703_CMD_SETVCOM, 0x3F, 0x3F); 102 - dsi_generic_write_seq(dsi, ST7703_CMD_UNKNOWN0, 0x02, 0x11, 0x00); 103 - dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP1, 104 - 0x82, 0x10, 0x06, 0x05, 0x9E, 0x0A, 0xA5, 0x12, 105 - 0x31, 0x23, 0x37, 0x83, 0x04, 0xBC, 0x27, 0x38, 106 - 0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 107 - 0x03, 0x00, 0x00, 0x00, 0x75, 0x75, 0x31, 0x88, 108 - 0x88, 0x88, 0x88, 0x88, 0x88, 0x13, 0x88, 0x64, 109 - 0x64, 0x20, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 110 - 0x02, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 111 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 112 - dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP2, 113 - 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 114 - 0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x02, 0x88, 115 - 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x88, 0x13, 116 - 0x57, 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 117 - 0x75, 0x88, 0x23, 0x14, 0x00, 0x00, 0x02, 0x00, 118 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0A, 120 - 0xA5, 0x00, 0x00, 0x00, 0x00); 121 - dsi_generic_write_seq(dsi, ST7703_CMD_SETGAMMA, 122 - 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, 0x37, 123 - 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, 0x11, 124 - 0x18, 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, 125 - 0x37, 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, 126 - 0x11, 0x18); 127 - msleep(20); 128 - 129 - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 130 - if (ret < 0) { 131 - DRM_DEV_ERROR(dev, "Failed to exit sleep mode: %d\n", ret); 132 - return ret; 133 - } 134 - /* Panel is operational 120 msec after reset */ 135 - msleep(60); 136 - ret = mipi_dsi_dcs_set_display_on(dsi); 137 - if (ret) 138 - return ret; 139 - 140 - DRM_DEV_DEBUG_DRIVER(dev, "Panel init sequence done\n"); 141 - return 0; 142 - } 143 - 144 - static int jh057n_enable(struct drm_panel *panel) 145 - { 146 - struct jh057n *ctx = panel_to_jh057n(panel); 147 - int ret; 148 - 149 - ret = jh057n_init_sequence(ctx); 150 - if (ret < 0) { 151 - DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n", 152 - ret); 153 - return ret; 154 - } 155 - 156 - return 0; 157 - } 158 - 159 - static int jh057n_disable(struct drm_panel *panel) 160 - { 161 - struct jh057n *ctx = panel_to_jh057n(panel); 162 - struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 163 - 164 - return mipi_dsi_dcs_set_display_off(dsi); 165 - } 166 - 167 - static int jh057n_unprepare(struct drm_panel *panel) 168 - { 169 - struct jh057n *ctx = panel_to_jh057n(panel); 170 - 171 - if (!ctx->prepared) 172 - return 0; 173 - 174 - regulator_disable(ctx->iovcc); 175 - regulator_disable(ctx->vcc); 176 - ctx->prepared = false; 177 - 178 - return 0; 179 - } 180 - 181 - static int jh057n_prepare(struct drm_panel *panel) 182 - { 183 - struct jh057n *ctx = panel_to_jh057n(panel); 184 - int ret; 185 - 186 - if (ctx->prepared) 187 - return 0; 188 - 189 - DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n"); 190 - ret = regulator_enable(ctx->vcc); 191 - if (ret < 0) { 192 - DRM_DEV_ERROR(ctx->dev, 193 - "Failed to enable vcc supply: %d\n", ret); 194 - return ret; 195 - } 196 - ret = regulator_enable(ctx->iovcc); 197 - if (ret < 0) { 198 - DRM_DEV_ERROR(ctx->dev, 199 - "Failed to enable iovcc supply: %d\n", ret); 200 - goto disable_vcc; 201 - } 202 - 203 - gpiod_set_value_cansleep(ctx->reset_gpio, 1); 204 - usleep_range(20, 40); 205 - gpiod_set_value_cansleep(ctx->reset_gpio, 0); 206 - msleep(20); 207 - 208 - ctx->prepared = true; 209 - 210 - return 0; 211 - 212 - disable_vcc: 213 - regulator_disable(ctx->vcc); 214 - return ret; 215 - } 216 - 217 - static const struct drm_display_mode default_mode = { 218 - .hdisplay = 720, 219 - .hsync_start = 720 + 90, 220 - .hsync_end = 720 + 90 + 20, 221 - .htotal = 720 + 90 + 20 + 20, 222 - .vdisplay = 1440, 223 - .vsync_start = 1440 + 20, 224 - .vsync_end = 1440 + 20 + 4, 225 - .vtotal = 1440 + 20 + 4 + 12, 226 - .clock = 75276, 227 - .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 228 - .width_mm = 65, 229 - .height_mm = 130, 230 - }; 231 - 232 - static int jh057n_get_modes(struct drm_panel *panel, 233 - struct drm_connector *connector) 234 - { 235 - struct jh057n *ctx = panel_to_jh057n(panel); 236 - struct drm_display_mode *mode; 237 - 238 - mode = drm_mode_duplicate(connector->dev, &default_mode); 239 - if (!mode) { 240 - DRM_DEV_ERROR(ctx->dev, "Failed to add mode %ux%u@%u\n", 241 - default_mode.hdisplay, default_mode.vdisplay, 242 - drm_mode_vrefresh(&default_mode)); 243 - return -ENOMEM; 244 - } 245 - 246 - drm_mode_set_name(mode); 247 - 248 - mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 249 - connector->display_info.width_mm = mode->width_mm; 250 - connector->display_info.height_mm = mode->height_mm; 251 - drm_mode_probed_add(connector, mode); 252 - 253 - return 1; 254 - } 255 - 256 - static const struct drm_panel_funcs jh057n_drm_funcs = { 257 - .disable = jh057n_disable, 258 - .unprepare = jh057n_unprepare, 259 - .prepare = jh057n_prepare, 260 - .enable = jh057n_enable, 261 - .get_modes = jh057n_get_modes, 262 - }; 263 - 264 - static int allpixelson_set(void *data, u64 val) 265 - { 266 - struct jh057n *ctx = data; 267 - struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 268 - 269 - DRM_DEV_DEBUG_DRIVER(ctx->dev, "Setting all pixels on\n"); 270 - dsi_generic_write_seq(dsi, ST7703_CMD_ALL_PIXEL_ON); 271 - msleep(val * 1000); 272 - /* Reset the panel to get video back */ 273 - drm_panel_disable(&ctx->panel); 274 - drm_panel_unprepare(&ctx->panel); 275 - drm_panel_prepare(&ctx->panel); 276 - drm_panel_enable(&ctx->panel); 277 - 278 - return 0; 279 - } 280 - 281 - DEFINE_SIMPLE_ATTRIBUTE(allpixelson_fops, NULL, 282 - allpixelson_set, "%llu\n"); 283 - 284 - static void jh057n_debugfs_init(struct jh057n *ctx) 285 - { 286 - ctx->debugfs = debugfs_create_dir(DRV_NAME, NULL); 287 - 288 - debugfs_create_file("allpixelson", 0600, ctx->debugfs, ctx, 289 - &allpixelson_fops); 290 - } 291 - 292 - static void jh057n_debugfs_remove(struct jh057n *ctx) 293 - { 294 - debugfs_remove_recursive(ctx->debugfs); 295 - ctx->debugfs = NULL; 296 - } 297 - 298 - static int jh057n_probe(struct mipi_dsi_device *dsi) 299 - { 300 - struct device *dev = &dsi->dev; 301 - struct jh057n *ctx; 302 - int ret; 303 - 304 - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 305 - if (!ctx) 306 - return -ENOMEM; 307 - 308 - ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 309 - if (IS_ERR(ctx->reset_gpio)) { 310 - DRM_DEV_ERROR(dev, "cannot get reset gpio\n"); 311 - return PTR_ERR(ctx->reset_gpio); 312 - } 313 - 314 - mipi_dsi_set_drvdata(dsi, ctx); 315 - 316 - ctx->dev = dev; 317 - 318 - dsi->lanes = 4; 319 - dsi->format = MIPI_DSI_FMT_RGB888; 320 - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | 321 - MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_SYNC_PULSE; 322 - 323 - ctx->vcc = devm_regulator_get(dev, "vcc"); 324 - if (IS_ERR(ctx->vcc)) { 325 - ret = PTR_ERR(ctx->vcc); 326 - if (ret != -EPROBE_DEFER) 327 - DRM_DEV_ERROR(dev, 328 - "Failed to request vcc regulator: %d\n", 329 - ret); 330 - return ret; 331 - } 332 - ctx->iovcc = devm_regulator_get(dev, "iovcc"); 333 - if (IS_ERR(ctx->iovcc)) { 334 - ret = PTR_ERR(ctx->iovcc); 335 - if (ret != -EPROBE_DEFER) 336 - DRM_DEV_ERROR(dev, 337 - "Failed to request iovcc regulator: %d\n", 338 - ret); 339 - return ret; 340 - } 341 - 342 - drm_panel_init(&ctx->panel, dev, &jh057n_drm_funcs, 343 - DRM_MODE_CONNECTOR_DSI); 344 - 345 - ret = drm_panel_of_backlight(&ctx->panel); 346 - if (ret) 347 - return ret; 348 - 349 - drm_panel_add(&ctx->panel); 350 - 351 - ret = mipi_dsi_attach(dsi); 352 - if (ret < 0) { 353 - DRM_DEV_ERROR(dev, 354 - "mipi_dsi_attach failed (%d). Is host ready?\n", 355 - ret); 356 - drm_panel_remove(&ctx->panel); 357 - return ret; 358 - } 359 - 360 - DRM_DEV_INFO(dev, "%ux%u@%u %ubpp dsi %udl - ready\n", 361 - default_mode.hdisplay, default_mode.vdisplay, 362 - drm_mode_vrefresh(&default_mode), 363 - mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes); 364 - 365 - jh057n_debugfs_init(ctx); 366 - return 0; 367 - } 368 - 369 - static void jh057n_shutdown(struct mipi_dsi_device *dsi) 370 - { 371 - struct jh057n *ctx = mipi_dsi_get_drvdata(dsi); 372 - int ret; 373 - 374 - ret = drm_panel_unprepare(&ctx->panel); 375 - if (ret < 0) 376 - DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n", 377 - ret); 378 - 379 - ret = drm_panel_disable(&ctx->panel); 380 - if (ret < 0) 381 - DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n", 382 - ret); 383 - } 384 - 385 - static int jh057n_remove(struct mipi_dsi_device *dsi) 386 - { 387 - struct jh057n *ctx = mipi_dsi_get_drvdata(dsi); 388 - int ret; 389 - 390 - jh057n_shutdown(dsi); 391 - 392 - ret = mipi_dsi_detach(dsi); 393 - if (ret < 0) 394 - DRM_DEV_ERROR(&dsi->dev, "Failed to detach from DSI host: %d\n", 395 - ret); 396 - 397 - drm_panel_remove(&ctx->panel); 398 - 399 - jh057n_debugfs_remove(ctx); 400 - 401 - return 0; 402 - } 403 - 404 - static const struct of_device_id jh057n_of_match[] = { 405 - { .compatible = "rocktech,jh057n00900" }, 406 - { /* sentinel */ } 407 - }; 408 - MODULE_DEVICE_TABLE(of, jh057n_of_match); 409 - 410 - static struct mipi_dsi_driver jh057n_driver = { 411 - .probe = jh057n_probe, 412 - .remove = jh057n_remove, 413 - .shutdown = jh057n_shutdown, 414 - .driver = { 415 - .name = DRV_NAME, 416 - .of_match_table = jh057n_of_match, 417 - }, 418 - }; 419 - module_mipi_dsi_driver(jh057n_driver); 420 - 421 - MODULE_AUTHOR("Guido Günther <agx@sigxcpu.org>"); 422 - MODULE_DESCRIPTION("DRM driver for Rocktech JH057N00900 MIPI DSI panel"); 423 - MODULE_LICENSE("GPL v2");
+57 -23
drivers/gpu/drm/panel/panel-simple.c
··· 549 549 panel_simple_parse_panel_timing_node(dev, panel, &dt); 550 550 } 551 551 552 + if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) { 553 + /* Catch common mistakes for LVDS panels. */ 554 + WARN_ON(desc->bus_flags & 555 + ~(DRM_BUS_FLAG_DE_LOW | 556 + DRM_BUS_FLAG_DE_HIGH | 557 + DRM_BUS_FLAG_DATA_MSB_TO_LSB | 558 + DRM_BUS_FLAG_DATA_LSB_TO_MSB)); 559 + WARN_ON(desc->bus_format != MEDIA_BUS_FMT_RGB666_1X7X3_SPWG && 560 + desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_SPWG && 561 + desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA); 562 + WARN_ON(desc->bus_format == MEDIA_BUS_FMT_RGB666_1X7X3_SPWG && 563 + desc->bpc != 6); 564 + WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG || 565 + desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) && 566 + desc->bpc != 8); 567 + } 568 + 552 569 drm_panel_init(&panel->base, dev, &panel_simple_funcs, 553 570 desc->connector_type); 554 571 ··· 681 664 .height = 86, 682 665 }, 683 666 .bus_format = MEDIA_BUS_FMT_RGB666_1X18, 684 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE, 667 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, 685 668 }; 686 669 687 670 static const struct drm_display_mode auo_b101aw03_mode = { ··· 704 687 .width = 223, 705 688 .height = 125, 706 689 }, 690 + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 691 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 707 692 .connector_type = DRM_MODE_CONNECTOR_LVDS, 708 693 }; 709 694 ··· 792 773 .vsync_start = 768 + 10, 793 774 .vsync_end = 768 + 10 + 12, 794 775 .vtotal = 768 + 10 + 12 + 6, 776 + .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, 795 777 }; 796 778 797 779 static const struct panel_desc auo_b116xw03 = { ··· 803 783 .width = 256, 804 784 .height = 144, 805 785 }, 786 + .delay = { 787 + .enable = 400, 788 + }, 789 + .bus_flags = DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE, 790 + .bus_format = MEDIA_BUS_FMT_RGB666_1X18, 791 + .connector_type = DRM_MODE_CONNECTOR_eDP, 806 792 }; 807 793 808 794 static const struct drm_display_mode auo_b133xtn01_mode = { ··· 1346 1320 .height = 86, 1347 1321 }, 1348 1322 .bus_format = MEDIA_BUS_FMT_RGB666_1X18, 1349 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE, 1323 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, 1350 1324 .connector_type = DRM_MODE_CONNECTOR_DPI, 1351 1325 }; 1352 1326 ··· 1373 1347 .height = 86, 1374 1348 }, 1375 1349 .bus_format = MEDIA_BUS_FMT_RGB666_1X18, 1376 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE, 1350 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, 1377 1351 .connector_type = DRM_MODE_CONNECTOR_DPI, 1378 1352 }; 1379 1353 ··· 1421 1395 .width = 94, 1422 1396 .height = 150, 1423 1397 }, 1398 + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 1399 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 1424 1400 .connector_type = DRM_MODE_CONNECTOR_LVDS, 1425 1401 }; 1426 1402 ··· 1446 1418 .width = 220, 1447 1419 .height = 120, 1448 1420 }, 1421 + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 1422 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 1449 1423 .connector_type = DRM_MODE_CONNECTOR_LVDS, 1450 1424 }; 1451 1425 ··· 1471 1441 .width = 223, 1472 1442 .height = 125, 1473 1443 }, 1444 + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 1445 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 1474 1446 .connector_type = DRM_MODE_CONNECTOR_LVDS, 1475 1447 }; 1476 1448 ··· 1584 1552 .height = 52, 1585 1553 }, 1586 1554 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 1587 - .bus_flags = DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_PIXDATA_NEGEDGE, 1555 + .bus_flags = DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, 1588 1556 }; 1589 1557 1590 1558 static const struct drm_display_mode edt_etm043080dh6gp_mode = { ··· 1663 1631 }, 1664 1632 .bus_format = MEDIA_BUS_FMT_RGB666_1X18, 1665 1633 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, 1666 - .connector_type = DRM_MODE_CONNECTOR_LVDS, 1634 + .connector_type = DRM_MODE_CONNECTOR_DPI, 1667 1635 }; 1668 1636 1669 1637 static const struct drm_display_mode edt_etm0700g0dh6_mode = { ··· 1727 1695 .height = 64, 1728 1696 }, 1729 1697 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 1730 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE, 1698 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, 1731 1699 }; 1732 1700 1733 1701 static const struct drm_display_mode foxlink_fl500wvr00_a0t_mode = { ··· 1775 1743 .height = 64, 1776 1744 }, 1777 1745 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 1778 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE, 1746 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, 1779 1747 .connector_type = DRM_MODE_CONNECTOR_DPI, 1780 1748 }; 1781 1749 ··· 1846 1814 .height = 45, 1847 1815 }, 1848 1816 .bus_format = MEDIA_BUS_FMT_RGB888_3X8, 1849 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE, 1817 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, 1850 1818 }; 1851 1819 1852 1820 static const struct display_timing hannstar_hsd070pww1_timing = { ··· 2146 2114 .width = 344, 2147 2115 .height = 193, 2148 2116 }, 2117 + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 2118 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 2149 2119 .connector_type = DRM_MODE_CONNECTOR_LVDS, 2150 2120 }; 2151 2121 ··· 2280 2246 .disable = 1000, 2281 2247 }, 2282 2248 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 2283 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, 2249 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 2284 2250 .connector_type = DRM_MODE_CONNECTOR_LVDS, 2285 2251 }; 2286 2252 ··· 2372 2338 static const struct panel_desc lg_lb070wv8 = { 2373 2339 .modes = &lg_lb070wv8_mode, 2374 2340 .num_modes = 1, 2375 - .bpc = 16, 2341 + .bpc = 8, 2376 2342 .size = { 2377 2343 .width = 151, 2378 2344 .height = 91, ··· 2521 2487 .height = 136, 2522 2488 }, 2523 2489 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 2524 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | 2525 - DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE | 2526 - DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE, 2490 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 2527 2491 .connector_type = DRM_MODE_CONNECTOR_LVDS, 2528 2492 }; 2529 2493 ··· 2892 2860 .height = 75, /* 74.88mm */ 2893 2861 }, 2894 2862 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 2895 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE | 2863 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE | 2896 2864 DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE, 2897 2865 }; 2898 2866 ··· 3093 3061 .width = 223, 3094 3062 .height = 125, 3095 3063 }, 3064 + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 3065 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 3096 3066 .connector_type = DRM_MODE_CONNECTOR_LVDS, 3097 3067 }; 3098 3068 ··· 3140 3106 .width = 108, 3141 3107 .height = 65, 3142 3108 }, 3143 - .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 3109 + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 3144 3110 .connector_type = DRM_MODE_CONNECTOR_LVDS, 3145 3111 }; 3146 3112 ··· 3191 3157 .height = 91, /* 91.4mm */ 3192 3158 }, 3193 3159 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 3194 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE | 3160 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE | 3195 3161 DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE, 3196 3162 }; 3197 3163 ··· 3294 3260 }, 3295 3261 .bus_format = MEDIA_BUS_FMT_RGB565_1X16, 3296 3262 .bus_flags = DRM_BUS_FLAG_DE_HIGH 3297 - | DRM_BUS_FLAG_PIXDATA_NEGEDGE 3263 + | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE 3298 3264 | DRM_BUS_FLAG_SHARP_SIGNALS, 3299 3265 }; 3300 3266 ··· 3342 3308 }, 3343 3309 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 3344 3310 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, 3345 - .connector_type = DRM_MODE_CONNECTOR_LVDS, 3311 + .connector_type = DRM_MODE_CONNECTOR_DPI, 3346 3312 }; 3347 3313 3348 3314 static const struct drm_display_mode starry_kr122ea0sra_mode = { ··· 3393 3359 .height = 90, 3394 3360 }, 3395 3361 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 3396 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE, 3362 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, 3397 3363 }; 3398 3364 3399 3365 static const struct display_timing tianma_tm070jdhg30_timing = { ··· 3482 3448 .height = 49, 3483 3449 }, 3484 3450 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 3485 - .bus_flags = DRM_BUS_FLAG_PIXDATA_NEGEDGE, 3451 + .bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, 3486 3452 }; 3487 3453 3488 3454 static const struct drm_display_mode ti_nspire_classic_lcd_mode[] = { ··· 3511 3477 }, 3512 3478 /* This is the grayscale bus format */ 3513 3479 .bus_format = MEDIA_BUS_FMT_Y8_1X8, 3514 - .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE, 3480 + .bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, 3515 3481 }; 3516 3482 3517 3483 static const struct drm_display_mode toshiba_lt089ac29000_mode = { ··· 3534 3500 .height = 116, 3535 3501 }, 3536 3502 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 3537 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, 3503 + .bus_flags = DRM_BUS_FLAG_DE_HIGH, 3538 3504 .connector_type = DRM_MODE_CONNECTOR_LVDS, 3539 3505 }; 3540 3506 ··· 3640 3606 .height = 76, 3641 3607 }, 3642 3608 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 3643 - .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE, 3609 + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, 3644 3610 }; 3645 3611 3646 3612 static const struct drm_display_mode winstar_wf35ltiacd_mode = {
+654
drivers/gpu/drm/panel/panel-sitronix-st7703.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Driver for panels based on Sitronix ST7703 controller, souch as: 4 + * 5 + * - Rocktech jh057n00900 5.5" MIPI-DSI panel 6 + * 7 + * Copyright (C) Purism SPC 2019 8 + */ 9 + 10 + #include <linux/debugfs.h> 11 + #include <linux/delay.h> 12 + #include <linux/gpio/consumer.h> 13 + #include <linux/media-bus-format.h> 14 + #include <linux/mod_devicetable.h> 15 + #include <linux/module.h> 16 + #include <linux/of_device.h> 17 + #include <linux/regulator/consumer.h> 18 + 19 + #include <video/display_timing.h> 20 + #include <video/mipi_display.h> 21 + 22 + #include <drm/drm_mipi_dsi.h> 23 + #include <drm/drm_modes.h> 24 + #include <drm/drm_panel.h> 25 + #include <drm/drm_print.h> 26 + 27 + #define DRV_NAME "panel-sitronix-st7703" 28 + 29 + /* Manufacturer specific Commands send via DSI */ 30 + #define ST7703_CMD_ALL_PIXEL_OFF 0x22 31 + #define ST7703_CMD_ALL_PIXEL_ON 0x23 32 + #define ST7703_CMD_SETDISP 0xB2 33 + #define ST7703_CMD_SETRGBIF 0xB3 34 + #define ST7703_CMD_SETCYC 0xB4 35 + #define ST7703_CMD_SETBGP 0xB5 36 + #define ST7703_CMD_SETVCOM 0xB6 37 + #define ST7703_CMD_SETOTP 0xB7 38 + #define ST7703_CMD_SETPOWER_EXT 0xB8 39 + #define ST7703_CMD_SETEXTC 0xB9 40 + #define ST7703_CMD_SETMIPI 0xBA 41 + #define ST7703_CMD_SETVDC 0xBC 42 + #define ST7703_CMD_UNKNOWN_BF 0xBF 43 + #define ST7703_CMD_SETSCR 0xC0 44 + #define ST7703_CMD_SETPOWER 0xC1 45 + #define ST7703_CMD_SETPANEL 0xCC 46 + #define ST7703_CMD_UNKNOWN_C6 0xC6 47 + #define ST7703_CMD_SETGAMMA 0xE0 48 + #define ST7703_CMD_SETEQ 0xE3 49 + #define ST7703_CMD_SETGIP1 0xE9 50 + #define ST7703_CMD_SETGIP2 0xEA 51 + 52 + struct st7703 { 53 + struct device *dev; 54 + struct drm_panel panel; 55 + struct gpio_desc *reset_gpio; 56 + struct regulator *vcc; 57 + struct regulator *iovcc; 58 + bool prepared; 59 + 60 + struct dentry *debugfs; 61 + const struct st7703_panel_desc *desc; 62 + }; 63 + 64 + struct st7703_panel_desc { 65 + const struct drm_display_mode *mode; 66 + unsigned int lanes; 67 + unsigned long mode_flags; 68 + enum mipi_dsi_pixel_format format; 69 + int (*init_sequence)(struct st7703 *ctx); 70 + }; 71 + 72 + static inline struct st7703 *panel_to_st7703(struct drm_panel *panel) 73 + { 74 + return container_of(panel, struct st7703, panel); 75 + } 76 + 77 + #define dsi_generic_write_seq(dsi, seq...) do { \ 78 + static const u8 d[] = { seq }; \ 79 + int ret; \ 80 + ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \ 81 + if (ret < 0) \ 82 + return ret; \ 83 + } while (0) 84 + 85 + static int jh057n_init_sequence(struct st7703 *ctx) 86 + { 87 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 88 + 89 + /* 90 + * Init sequence was supplied by the panel vendor. Most of the commands 91 + * resemble the ST7703 but the number of parameters often don't match 92 + * so it's likely a clone. 93 + */ 94 + dsi_generic_write_seq(dsi, ST7703_CMD_SETEXTC, 95 + 0xF1, 0x12, 0x83); 96 + dsi_generic_write_seq(dsi, ST7703_CMD_SETRGBIF, 97 + 0x10, 0x10, 0x05, 0x05, 0x03, 0xFF, 0x00, 0x00, 98 + 0x00, 0x00); 99 + dsi_generic_write_seq(dsi, ST7703_CMD_SETSCR, 100 + 0x73, 0x73, 0x50, 0x50, 0x00, 0x00, 0x08, 0x70, 101 + 0x00); 102 + dsi_generic_write_seq(dsi, ST7703_CMD_SETVDC, 0x4E); 103 + dsi_generic_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0B); 104 + dsi_generic_write_seq(dsi, ST7703_CMD_SETCYC, 0x80); 105 + dsi_generic_write_seq(dsi, ST7703_CMD_SETDISP, 0xF0, 0x12, 0x30); 106 + dsi_generic_write_seq(dsi, ST7703_CMD_SETEQ, 107 + 0x07, 0x07, 0x0B, 0x0B, 0x03, 0x0B, 0x00, 0x00, 108 + 0x00, 0x00, 0xFF, 0x00, 0xC0, 0x10); 109 + dsi_generic_write_seq(dsi, ST7703_CMD_SETBGP, 0x08, 0x08); 110 + msleep(20); 111 + 112 + dsi_generic_write_seq(dsi, ST7703_CMD_SETVCOM, 0x3F, 0x3F); 113 + dsi_generic_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00); 114 + dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP1, 115 + 0x82, 0x10, 0x06, 0x05, 0x9E, 0x0A, 0xA5, 0x12, 116 + 0x31, 0x23, 0x37, 0x83, 0x04, 0xBC, 0x27, 0x38, 117 + 0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 118 + 0x03, 0x00, 0x00, 0x00, 0x75, 0x75, 0x31, 0x88, 119 + 0x88, 0x88, 0x88, 0x88, 0x88, 0x13, 0x88, 0x64, 120 + 0x64, 0x20, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 121 + 0x02, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 122 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 123 + dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP2, 124 + 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 + 0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x02, 0x88, 126 + 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x88, 0x13, 127 + 0x57, 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 128 + 0x75, 0x88, 0x23, 0x14, 0x00, 0x00, 0x02, 0x00, 129 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 130 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0A, 131 + 0xA5, 0x00, 0x00, 0x00, 0x00); 132 + dsi_generic_write_seq(dsi, ST7703_CMD_SETGAMMA, 133 + 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, 0x37, 134 + 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, 0x11, 135 + 0x18, 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, 136 + 0x37, 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, 137 + 0x11, 0x18); 138 + 139 + return 0; 140 + } 141 + 142 + static const struct drm_display_mode jh057n00900_mode = { 143 + .hdisplay = 720, 144 + .hsync_start = 720 + 90, 145 + .hsync_end = 720 + 90 + 20, 146 + .htotal = 720 + 90 + 20 + 20, 147 + .vdisplay = 1440, 148 + .vsync_start = 1440 + 20, 149 + .vsync_end = 1440 + 20 + 4, 150 + .vtotal = 1440 + 20 + 4 + 12, 151 + .clock = 75276, 152 + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 153 + .width_mm = 65, 154 + .height_mm = 130, 155 + }; 156 + 157 + struct st7703_panel_desc jh057n00900_panel_desc = { 158 + .mode = &jh057n00900_mode, 159 + .lanes = 4, 160 + .mode_flags = MIPI_DSI_MODE_VIDEO | 161 + MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_SYNC_PULSE, 162 + .format = MIPI_DSI_FMT_RGB888, 163 + .init_sequence = jh057n_init_sequence, 164 + }; 165 + 166 + #define dsi_dcs_write_seq(dsi, cmd, seq...) do { \ 167 + static const u8 d[] = { seq }; \ 168 + int ret; \ 169 + ret = mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d)); \ 170 + if (ret < 0) \ 171 + return ret; \ 172 + } while (0) 173 + 174 + 175 + static int xbd599_init_sequence(struct st7703 *ctx) 176 + { 177 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 178 + 179 + /* 180 + * Init sequence was supplied by the panel vendor. 181 + */ 182 + 183 + /* Magic sequence to unlock user commands below. */ 184 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xF1, 0x12, 0x83); 185 + 186 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 187 + 0x33, /* VC_main = 0, Lane_Number = 3 (4 lanes) */ 188 + 0x81, /* DSI_LDO_SEL = 1.7V, RTERM = 90 Ohm */ 189 + 0x05, /* IHSRX = x6 (Low High Speed driving ability) */ 190 + 0xF9, /* TX_CLK_SEL = fDSICLK/16 */ 191 + 0x0E, /* HFP_OSC (min. HFP number in DSI mode) */ 192 + 0x0E, /* HBP_OSC (min. HBP number in DSI mode) */ 193 + /* The rest is undocumented in ST7703 datasheet */ 194 + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 195 + 0x44, 0x25, 0x00, 0x91, 0x0a, 0x00, 0x00, 0x02, 196 + 0x4F, 0x11, 0x00, 0x00, 0x37); 197 + 198 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 199 + 0x25, /* PCCS = 2, ECP_DC_DIV = 1/4 HSYNC */ 200 + 0x22, /* DT = 15ms XDK_ECP = x2 */ 201 + 0x20, /* PFM_DC_DIV = /1 */ 202 + 0x03 /* ECP_SYNC_EN = 1, VGX_SYNC_EN = 1 */); 203 + 204 + /* RGB I/F porch timing */ 205 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 206 + 0x10, /* VBP_RGB_GEN */ 207 + 0x10, /* VFP_RGB_GEN */ 208 + 0x05, /* DE_BP_RGB_GEN */ 209 + 0x05, /* DE_FP_RGB_GEN */ 210 + /* The rest is undocumented in ST7703 datasheet */ 211 + 0x03, 0xFF, 212 + 0x00, 0x00, 213 + 0x00, 0x00); 214 + 215 + /* Source driving settings. */ 216 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 217 + 0x73, /* N_POPON */ 218 + 0x73, /* N_NOPON */ 219 + 0x50, /* I_POPON */ 220 + 0x50, /* I_NOPON */ 221 + 0x00, /* SCR[31,24] */ 222 + 0xC0, /* SCR[23,16] */ 223 + 0x08, /* SCR[15,8] */ 224 + 0x70, /* SCR[7,0] */ 225 + 0x00 /* Undocumented */); 226 + 227 + /* NVDDD_SEL = -1.8V, VDDD_SEL = out of range (possibly 1.9V?) */ 228 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x4E); 229 + 230 + /* 231 + * SS_PANEL = 1 (reverse scan), GS_PANEL = 0 (normal scan) 232 + * REV_PANEL = 1 (normally black panel), BGR_PANEL = 1 (BGR) 233 + */ 234 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0B); 235 + 236 + /* Zig-Zag Type C column inversion. */ 237 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80); 238 + 239 + /* Set display resolution. */ 240 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 241 + 0xF0, /* NL = 240 */ 242 + 0x12, /* RES_V_LSB = 0, BLK_CON = VSSD, 243 + * RESO_SEL = 720RGB 244 + */ 245 + 0xF0 /* WHITE_GND_EN = 1 (GND), 246 + * WHITE_FRAME_SEL = 7 frames, 247 + * ISC = 0 frames 248 + */); 249 + 250 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 251 + 0x00, /* PNOEQ */ 252 + 0x00, /* NNOEQ */ 253 + 0x0B, /* PEQGND */ 254 + 0x0B, /* NEQGND */ 255 + 0x10, /* PEQVCI */ 256 + 0x10, /* NEQVCI */ 257 + 0x00, /* PEQVCI1 */ 258 + 0x00, /* NEQVCI1 */ 259 + 0x00, /* reserved */ 260 + 0x00, /* reserved */ 261 + 0xFF, /* reserved */ 262 + 0x00, /* reserved */ 263 + 0xC0, /* ESD_DET_DATA_WHITE = 1, ESD_WHITE_EN = 1 */ 264 + 0x10 /* SLPIN_OPTION = 1 (no need vsync after sleep-in) 265 + * VEDIO_NO_CHECK_EN = 0 266 + * ESD_WHITE_GND_EN = 0 267 + * ESD_DET_TIME_SEL = 0 frames 268 + */); 269 + 270 + /* Undocumented command. */ 271 + dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_C6, 0x01, 0x00, 0xFF, 0xFF, 0x00); 272 + 273 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 274 + 0x74, /* VBTHS, VBTLS: VGH = 17V, VBL = -11V */ 275 + 0x00, /* FBOFF_VGH = 0, FBOFF_VGL = 0 */ 276 + 0x32, /* VRP */ 277 + 0x32, /* VRN */ 278 + 0x77, /* reserved */ 279 + 0xF1, /* APS = 1 (small), 280 + * VGL_DET_EN = 1, VGH_DET_EN = 1, 281 + * VGL_TURBO = 1, VGH_TURBO = 1 282 + */ 283 + 0xFF, /* VGH1_L_DIV, VGL1_L_DIV (1.5MHz) */ 284 + 0xFF, /* VGH1_R_DIV, VGL1_R_DIV (1.5MHz) */ 285 + 0xCC, /* VGH2_L_DIV, VGL2_L_DIV (2.6MHz) */ 286 + 0xCC, /* VGH2_R_DIV, VGL2_R_DIV (2.6MHz) */ 287 + 0x77, /* VGH3_L_DIV, VGL3_L_DIV (4.5MHz) */ 288 + 0x77 /* VGH3_R_DIV, VGL3_R_DIV (4.5MHz) */); 289 + 290 + /* Reference voltage. */ 291 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 292 + 0x07, /* VREF_SEL = 4.2V */ 293 + 0x07 /* NVREF_SEL = 4.2V */); 294 + msleep(20); 295 + 296 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 297 + 0x2C, /* VCOMDC_F = -0.67V */ 298 + 0x2C /* VCOMDC_B = -0.67V */); 299 + 300 + /* Undocumented command. */ 301 + dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00); 302 + 303 + /* This command is to set forward GIP timing. */ 304 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 305 + 0x82, 0x10, 0x06, 0x05, 0xA2, 0x0A, 0xA5, 0x12, 306 + 0x31, 0x23, 0x37, 0x83, 0x04, 0xBC, 0x27, 0x38, 307 + 0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 308 + 0x03, 0x00, 0x00, 0x00, 0x75, 0x75, 0x31, 0x88, 309 + 0x88, 0x88, 0x88, 0x88, 0x88, 0x13, 0x88, 0x64, 310 + 0x64, 0x20, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 311 + 0x02, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 312 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 313 + 314 + /* This command is to set backward GIP timing. */ 315 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 316 + 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 317 + 0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x02, 0x88, 318 + 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x88, 0x13, 319 + 0x57, 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 320 + 0x75, 0x88, 0x23, 0x14, 0x00, 0x00, 0x02, 0x00, 321 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 322 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0A, 323 + 0xA5, 0x00, 0x00, 0x00, 0x00); 324 + 325 + /* Adjust the gamma characteristics of the panel. */ 326 + dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 327 + 0x00, 0x09, 0x0D, 0x23, 0x27, 0x3C, 0x41, 0x35, 328 + 0x07, 0x0D, 0x0E, 0x12, 0x13, 0x10, 0x12, 0x12, 329 + 0x18, 0x00, 0x09, 0x0D, 0x23, 0x27, 0x3C, 0x41, 330 + 0x35, 0x07, 0x0D, 0x0E, 0x12, 0x13, 0x10, 0x12, 331 + 0x12, 0x18); 332 + 333 + return 0; 334 + } 335 + 336 + static const struct drm_display_mode xbd599_mode = { 337 + .hdisplay = 720, 338 + .hsync_start = 720 + 40, 339 + .hsync_end = 720 + 40 + 40, 340 + .htotal = 720 + 40 + 40 + 40, 341 + .vdisplay = 1440, 342 + .vsync_start = 1440 + 18, 343 + .vsync_end = 1440 + 18 + 10, 344 + .vtotal = 1440 + 18 + 10 + 17, 345 + .clock = 69000, 346 + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 347 + .width_mm = 68, 348 + .height_mm = 136, 349 + }; 350 + 351 + static const struct st7703_panel_desc xbd599_desc = { 352 + .mode = &xbd599_mode, 353 + .lanes = 4, 354 + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE, 355 + .format = MIPI_DSI_FMT_RGB888, 356 + .init_sequence = xbd599_init_sequence, 357 + }; 358 + 359 + static int st7703_enable(struct drm_panel *panel) 360 + { 361 + struct st7703 *ctx = panel_to_st7703(panel); 362 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 363 + int ret; 364 + 365 + ret = ctx->desc->init_sequence(ctx); 366 + if (ret < 0) { 367 + DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n", 368 + ret); 369 + return ret; 370 + } 371 + 372 + msleep(20); 373 + 374 + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 375 + if (ret < 0) { 376 + DRM_DEV_ERROR(ctx->dev, "Failed to exit sleep mode: %d\n", ret); 377 + return ret; 378 + } 379 + 380 + /* Panel is operational 120 msec after reset */ 381 + msleep(60); 382 + 383 + ret = mipi_dsi_dcs_set_display_on(dsi); 384 + if (ret) 385 + return ret; 386 + 387 + DRM_DEV_DEBUG_DRIVER(ctx->dev, "Panel init sequence done\n"); 388 + 389 + return 0; 390 + } 391 + 392 + static int st7703_disable(struct drm_panel *panel) 393 + { 394 + struct st7703 *ctx = panel_to_st7703(panel); 395 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 396 + int ret; 397 + 398 + ret = mipi_dsi_dcs_set_display_off(dsi); 399 + if (ret < 0) 400 + DRM_DEV_ERROR(ctx->dev, 401 + "Failed to turn off the display: %d\n", ret); 402 + 403 + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); 404 + if (ret < 0) 405 + DRM_DEV_ERROR(ctx->dev, 406 + "Failed to enter sleep mode: %d\n", ret); 407 + 408 + return 0; 409 + } 410 + 411 + static int st7703_unprepare(struct drm_panel *panel) 412 + { 413 + struct st7703 *ctx = panel_to_st7703(panel); 414 + 415 + if (!ctx->prepared) 416 + return 0; 417 + 418 + gpiod_set_value_cansleep(ctx->reset_gpio, 1); 419 + regulator_disable(ctx->iovcc); 420 + regulator_disable(ctx->vcc); 421 + ctx->prepared = false; 422 + 423 + return 0; 424 + } 425 + 426 + static int st7703_prepare(struct drm_panel *panel) 427 + { 428 + struct st7703 *ctx = panel_to_st7703(panel); 429 + int ret; 430 + 431 + if (ctx->prepared) 432 + return 0; 433 + 434 + DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n"); 435 + ret = regulator_enable(ctx->vcc); 436 + if (ret < 0) { 437 + DRM_DEV_ERROR(ctx->dev, 438 + "Failed to enable vcc supply: %d\n", ret); 439 + return ret; 440 + } 441 + ret = regulator_enable(ctx->iovcc); 442 + if (ret < 0) { 443 + DRM_DEV_ERROR(ctx->dev, 444 + "Failed to enable iovcc supply: %d\n", ret); 445 + goto disable_vcc; 446 + } 447 + 448 + gpiod_set_value_cansleep(ctx->reset_gpio, 1); 449 + usleep_range(20, 40); 450 + gpiod_set_value_cansleep(ctx->reset_gpio, 0); 451 + msleep(20); 452 + 453 + ctx->prepared = true; 454 + 455 + return 0; 456 + 457 + disable_vcc: 458 + regulator_disable(ctx->vcc); 459 + return ret; 460 + } 461 + 462 + static int st7703_get_modes(struct drm_panel *panel, 463 + struct drm_connector *connector) 464 + { 465 + struct st7703 *ctx = panel_to_st7703(panel); 466 + struct drm_display_mode *mode; 467 + 468 + mode = drm_mode_duplicate(connector->dev, ctx->desc->mode); 469 + if (!mode) { 470 + DRM_DEV_ERROR(ctx->dev, "Failed to add mode %ux%u@%u\n", 471 + ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay, 472 + drm_mode_vrefresh(ctx->desc->mode)); 473 + return -ENOMEM; 474 + } 475 + 476 + drm_mode_set_name(mode); 477 + 478 + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 479 + connector->display_info.width_mm = mode->width_mm; 480 + connector->display_info.height_mm = mode->height_mm; 481 + drm_mode_probed_add(connector, mode); 482 + 483 + return 1; 484 + } 485 + 486 + static const struct drm_panel_funcs st7703_drm_funcs = { 487 + .disable = st7703_disable, 488 + .unprepare = st7703_unprepare, 489 + .prepare = st7703_prepare, 490 + .enable = st7703_enable, 491 + .get_modes = st7703_get_modes, 492 + }; 493 + 494 + static int allpixelson_set(void *data, u64 val) 495 + { 496 + struct st7703 *ctx = data; 497 + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 498 + 499 + DRM_DEV_DEBUG_DRIVER(ctx->dev, "Setting all pixels on\n"); 500 + dsi_generic_write_seq(dsi, ST7703_CMD_ALL_PIXEL_ON); 501 + msleep(val * 1000); 502 + /* Reset the panel to get video back */ 503 + drm_panel_disable(&ctx->panel); 504 + drm_panel_unprepare(&ctx->panel); 505 + drm_panel_prepare(&ctx->panel); 506 + drm_panel_enable(&ctx->panel); 507 + 508 + return 0; 509 + } 510 + 511 + DEFINE_SIMPLE_ATTRIBUTE(allpixelson_fops, NULL, 512 + allpixelson_set, "%llu\n"); 513 + 514 + static void st7703_debugfs_init(struct st7703 *ctx) 515 + { 516 + ctx->debugfs = debugfs_create_dir(DRV_NAME, NULL); 517 + 518 + debugfs_create_file("allpixelson", 0600, ctx->debugfs, ctx, 519 + &allpixelson_fops); 520 + } 521 + 522 + static void st7703_debugfs_remove(struct st7703 *ctx) 523 + { 524 + debugfs_remove_recursive(ctx->debugfs); 525 + ctx->debugfs = NULL; 526 + } 527 + 528 + static int st7703_probe(struct mipi_dsi_device *dsi) 529 + { 530 + struct device *dev = &dsi->dev; 531 + struct st7703 *ctx; 532 + int ret; 533 + 534 + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 535 + if (!ctx) 536 + return -ENOMEM; 537 + 538 + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 539 + if (IS_ERR(ctx->reset_gpio)) { 540 + DRM_DEV_ERROR(dev, "cannot get reset gpio\n"); 541 + return PTR_ERR(ctx->reset_gpio); 542 + } 543 + 544 + mipi_dsi_set_drvdata(dsi, ctx); 545 + 546 + ctx->dev = dev; 547 + ctx->desc = of_device_get_match_data(dev); 548 + 549 + dsi->mode_flags = ctx->desc->mode_flags; 550 + dsi->format = ctx->desc->format; 551 + dsi->lanes = ctx->desc->lanes; 552 + 553 + ctx->vcc = devm_regulator_get(dev, "vcc"); 554 + if (IS_ERR(ctx->vcc)) { 555 + ret = PTR_ERR(ctx->vcc); 556 + if (ret != -EPROBE_DEFER) 557 + DRM_DEV_ERROR(dev, 558 + "Failed to request vcc regulator: %d\n", 559 + ret); 560 + return ret; 561 + } 562 + ctx->iovcc = devm_regulator_get(dev, "iovcc"); 563 + if (IS_ERR(ctx->iovcc)) { 564 + ret = PTR_ERR(ctx->iovcc); 565 + if (ret != -EPROBE_DEFER) 566 + DRM_DEV_ERROR(dev, 567 + "Failed to request iovcc regulator: %d\n", 568 + ret); 569 + return ret; 570 + } 571 + 572 + drm_panel_init(&ctx->panel, dev, &st7703_drm_funcs, 573 + DRM_MODE_CONNECTOR_DSI); 574 + 575 + ret = drm_panel_of_backlight(&ctx->panel); 576 + if (ret) 577 + return ret; 578 + 579 + drm_panel_add(&ctx->panel); 580 + 581 + ret = mipi_dsi_attach(dsi); 582 + if (ret < 0) { 583 + DRM_DEV_ERROR(dev, 584 + "mipi_dsi_attach failed (%d). Is host ready?\n", 585 + ret); 586 + drm_panel_remove(&ctx->panel); 587 + return ret; 588 + } 589 + 590 + DRM_DEV_INFO(dev, "%ux%u@%u %ubpp dsi %udl - ready\n", 591 + ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay, 592 + drm_mode_vrefresh(ctx->desc->mode), 593 + mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes); 594 + 595 + st7703_debugfs_init(ctx); 596 + return 0; 597 + } 598 + 599 + static void st7703_shutdown(struct mipi_dsi_device *dsi) 600 + { 601 + struct st7703 *ctx = mipi_dsi_get_drvdata(dsi); 602 + int ret; 603 + 604 + ret = drm_panel_unprepare(&ctx->panel); 605 + if (ret < 0) 606 + DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n", 607 + ret); 608 + 609 + ret = drm_panel_disable(&ctx->panel); 610 + if (ret < 0) 611 + DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n", 612 + ret); 613 + } 614 + 615 + static int st7703_remove(struct mipi_dsi_device *dsi) 616 + { 617 + struct st7703 *ctx = mipi_dsi_get_drvdata(dsi); 618 + int ret; 619 + 620 + st7703_shutdown(dsi); 621 + 622 + ret = mipi_dsi_detach(dsi); 623 + if (ret < 0) 624 + DRM_DEV_ERROR(&dsi->dev, "Failed to detach from DSI host: %d\n", 625 + ret); 626 + 627 + drm_panel_remove(&ctx->panel); 628 + 629 + st7703_debugfs_remove(ctx); 630 + 631 + return 0; 632 + } 633 + 634 + static const struct of_device_id st7703_of_match[] = { 635 + { .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc }, 636 + { .compatible = "xingbangda,xbd599", .data = &xbd599_desc }, 637 + { /* sentinel */ } 638 + }; 639 + MODULE_DEVICE_TABLE(of, st7703_of_match); 640 + 641 + static struct mipi_dsi_driver st7703_driver = { 642 + .probe = st7703_probe, 643 + .remove = st7703_remove, 644 + .shutdown = st7703_shutdown, 645 + .driver = { 646 + .name = DRV_NAME, 647 + .of_match_table = st7703_of_match, 648 + }, 649 + }; 650 + module_mipi_dsi_driver(st7703_driver); 651 + 652 + MODULE_AUTHOR("Guido Günther <agx@sigxcpu.org>"); 653 + MODULE_DESCRIPTION("DRM driver for Sitronix ST7703 based MIPI DSI panels"); 654 + MODULE_LICENSE("GPL v2");
+2 -2
drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
··· 62 62 } 63 63 64 64 #define dsi_generic_write_seq(dsi, cmd, seq...) do { \ 65 - static const u8 d[] = { seq }; \ 65 + static const u8 b[] = { cmd, seq }; \ 66 66 int ret; \ 67 - ret = mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d)); \ 67 + ret = mipi_dsi_dcs_write_buffer(dsi, b, ARRAY_SIZE(b)); \ 68 68 if (ret < 0) \ 69 69 return ret; \ 70 70 } while (0)
-1
drivers/gpu/drm/pl111/pl111_debugfs.c
··· 3 3 * Copyright © 2017 Broadcom 4 4 */ 5 5 6 - #include <linux/amba/clcd-regs.h> 7 6 #include <linux/seq_file.h> 8 7 9 8 #include <drm/drm_debugfs.h>
-1
drivers/gpu/drm/pl111/pl111_display.c
··· 9 9 * Copyright (C) 2011 Texas Instruments 10 10 */ 11 11 12 - #include <linux/amba/clcd-regs.h> 13 12 #include <linux/clk.h> 14 13 #include <linux/delay.h> 15 14 #include <linux/version.h>
+73
drivers/gpu/drm/pl111/pl111_drm.h
··· 23 23 #include <drm/drm_panel.h> 24 24 #include <drm/drm_simple_kms_helper.h> 25 25 26 + /* 27 + * CLCD Controller Internal Register addresses 28 + */ 29 + #define CLCD_TIM0 0x00000000 30 + #define CLCD_TIM1 0x00000004 31 + #define CLCD_TIM2 0x00000008 32 + #define CLCD_TIM3 0x0000000c 33 + #define CLCD_UBAS 0x00000010 34 + #define CLCD_LBAS 0x00000014 35 + 36 + #define CLCD_PL110_IENB 0x00000018 37 + #define CLCD_PL110_CNTL 0x0000001c 38 + #define CLCD_PL110_STAT 0x00000020 39 + #define CLCD_PL110_INTR 0x00000024 40 + #define CLCD_PL110_UCUR 0x00000028 41 + #define CLCD_PL110_LCUR 0x0000002C 42 + 43 + #define CLCD_PL111_CNTL 0x00000018 44 + #define CLCD_PL111_IENB 0x0000001c 45 + #define CLCD_PL111_RIS 0x00000020 46 + #define CLCD_PL111_MIS 0x00000024 47 + #define CLCD_PL111_ICR 0x00000028 48 + #define CLCD_PL111_UCUR 0x0000002c 49 + #define CLCD_PL111_LCUR 0x00000030 50 + 51 + #define CLCD_PALL 0x00000200 52 + #define CLCD_PALETTE 0x00000200 53 + 54 + #define TIM2_PCD_LO_MASK GENMASK(4, 0) 55 + #define TIM2_PCD_LO_BITS 5 56 + #define TIM2_CLKSEL (1 << 5) 57 + #define TIM2_ACB_MASK GENMASK(10, 6) 58 + #define TIM2_IVS (1 << 11) 59 + #define TIM2_IHS (1 << 12) 60 + #define TIM2_IPC (1 << 13) 61 + #define TIM2_IOE (1 << 14) 62 + #define TIM2_BCD (1 << 26) 63 + #define TIM2_PCD_HI_MASK GENMASK(31, 27) 64 + #define TIM2_PCD_HI_BITS 5 65 + #define TIM2_PCD_HI_SHIFT 27 66 + 67 + #define CNTL_LCDEN (1 << 0) 68 + #define CNTL_LCDBPP1 (0 << 1) 69 + #define CNTL_LCDBPP2 (1 << 1) 70 + #define CNTL_LCDBPP4 (2 << 1) 71 + #define CNTL_LCDBPP8 (3 << 1) 72 + #define CNTL_LCDBPP16 (4 << 1) 73 + #define CNTL_LCDBPP16_565 (6 << 1) 74 + #define CNTL_LCDBPP16_444 (7 << 1) 75 + #define CNTL_LCDBPP24 (5 << 1) 76 + #define CNTL_LCDBW (1 << 4) 77 + #define CNTL_LCDTFT (1 << 5) 78 + #define CNTL_LCDMONO8 (1 << 6) 79 + #define CNTL_LCDDUAL (1 << 7) 80 + #define CNTL_BGR (1 << 8) 81 + #define CNTL_BEBO (1 << 9) 82 + #define CNTL_BEPO (1 << 10) 83 + #define CNTL_LCDPWR (1 << 11) 84 + #define CNTL_LCDVCOMP(x) ((x) << 12) 85 + #define CNTL_LDMAFIFOTIME (1 << 15) 86 + #define CNTL_WATERMARK (1 << 16) 87 + 88 + /* ST Microelectronics variant bits */ 89 + #define CNTL_ST_1XBPP_444 0x0 90 + #define CNTL_ST_1XBPP_5551 (1 << 17) 91 + #define CNTL_ST_1XBPP_565 (1 << 18) 92 + #define CNTL_ST_CDWID_12 0x0 93 + #define CNTL_ST_CDWID_16 (1 << 19) 94 + #define CNTL_ST_CDWID_18 (1 << 20) 95 + #define CNTL_ST_CDWID_24 ((1 << 19) | (1 << 20)) 96 + #define CNTL_ST_CEAEN (1 << 21) 97 + #define CNTL_ST_LCDBPP24_PACKED (6 << 1) 98 + 26 99 #define CLCD_IRQ_NEXTBASE_UPDATE BIT(2) 27 100 28 101 struct drm_minor;
-1
drivers/gpu/drm/pl111/pl111_drv.c
··· 47 47 */ 48 48 49 49 #include <linux/amba/bus.h> 50 - #include <linux/amba/clcd-regs.h> 51 50 #include <linux/dma-buf.h> 52 51 #include <linux/module.h> 53 52 #include <linux/of.h>
+9 -1
drivers/gpu/drm/pl111/pl111_versatile.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 3 - #include <linux/amba/clcd-regs.h> 3 + /* 4 + * Versatile family (ARM reference designs) handling for the PL11x. 5 + * This is based on code and know-how in the previous frame buffer 6 + * driver in drivers/video/fbdev/amba-clcd.c: 7 + * Copyright (C) 2001 ARM Limited, by David A Rusling 8 + * Updated to 2.5 by Deep Blue Solutions Ltd. 9 + * Major contributions and discoveries by Russell King. 10 + */ 11 + 4 12 #include <linux/bitops.h> 5 13 #include <linux/device.h> 6 14 #include <linux/mfd/syscon.h>
+5 -6
drivers/gpu/drm/radeon/radeon_ttm.c
··· 479 479 { 480 480 struct radeon_device *rdev = radeon_get_rdev(ttm->bdev); 481 481 struct radeon_ttm_tt *gtt = (void *)ttm; 482 - unsigned pinned = 0, nents; 482 + unsigned pinned = 0; 483 483 int r; 484 484 485 485 int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY); ··· 519 519 if (r) 520 520 goto release_sg; 521 521 522 - r = -ENOMEM; 523 - nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction); 524 - if (nents == 0) 522 + r = dma_map_sgtable(rdev->dev, ttm->sg, direction, 0); 523 + if (r) 525 524 goto release_sg; 526 525 527 526 drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, ··· 551 552 return; 552 553 553 554 /* free the sg table and pages again */ 554 - dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction); 555 + dma_unmap_sgtable(rdev->dev, ttm->sg, direction, 0); 555 556 556 - for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) { 557 + for_each_sgtable_page(ttm->sg, &sg_iter, 0) { 557 558 struct page *page = sg_page_iter_page(&sg_iter); 558 559 if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY)) 559 560 set_page_dirty(page);
+1 -5
drivers/gpu/drm/rcar-du/rcar_du_crtc.c
··· 975 975 state->crc.source = VSP1_DU_CRC_NONE; 976 976 state->crc.index = 0; 977 977 978 - crtc->state = &state->state; 979 - crtc->state->crtc = crtc; 978 + __drm_atomic_helper_crtc_reset(crtc, &state->state); 980 979 } 981 980 982 981 static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc) ··· 1269 1270 } 1270 1271 1271 1272 drm_crtc_helper_add(crtc, &crtc_helper_funcs); 1272 - 1273 - /* Start with vertical blanking interrupt reporting disabled. */ 1274 - drm_crtc_vblank_off(crtc); 1275 1273 1276 1274 /* Register the interrupt handler. */ 1277 1275 if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
+1 -1
drivers/gpu/drm/scheduler/sched_entity.c
··· 486 486 bool first; 487 487 488 488 trace_drm_sched_job(sched_job, entity); 489 - atomic_inc(&entity->rq->sched->num_jobs); 489 + atomic_inc(&entity->rq->sched->score); 490 490 WRITE_ONCE(entity->last_user, current->group_leader); 491 491 first = spsc_queue_push(&entity->job_queue, &sched_job->queue_node); 492 492
+8 -6
drivers/gpu/drm/scheduler/sched_main.c
··· 92 92 if (!list_empty(&entity->list)) 93 93 return; 94 94 spin_lock(&rq->lock); 95 + atomic_inc(&rq->sched->score); 95 96 list_add_tail(&entity->list, &rq->entities); 96 97 spin_unlock(&rq->lock); 97 98 } ··· 111 110 if (list_empty(&entity->list)) 112 111 return; 113 112 spin_lock(&rq->lock); 113 + atomic_dec(&rq->sched->score); 114 114 list_del_init(&entity->list); 115 115 if (rq->current_entity == entity) 116 116 rq->current_entity = NULL; ··· 649 647 struct drm_gpu_scheduler *sched = s_fence->sched; 650 648 651 649 atomic_dec(&sched->hw_rq_count); 652 - atomic_dec(&sched->num_jobs); 650 + atomic_dec(&sched->score); 653 651 654 652 trace_drm_sched_process_job(s_fence); 655 653 ··· 714 712 { 715 713 struct drm_gpu_scheduler *sched, *picked_sched = NULL; 716 714 int i; 717 - unsigned int min_jobs = UINT_MAX, num_jobs; 715 + unsigned int min_score = UINT_MAX, num_score; 718 716 719 717 for (i = 0; i < num_sched_list; ++i) { 720 718 sched = sched_list[i]; ··· 725 723 continue; 726 724 } 727 725 728 - num_jobs = atomic_read(&sched->num_jobs); 729 - if (num_jobs < min_jobs) { 730 - min_jobs = num_jobs; 726 + num_score = atomic_read(&sched->score); 727 + if (num_score < min_score) { 728 + min_score = num_score; 731 729 picked_sched = sched; 732 730 } 733 731 } ··· 862 860 spin_lock_init(&sched->job_list_lock); 863 861 atomic_set(&sched->hw_rq_count, 0); 864 862 INIT_DELAYED_WORK(&sched->work_tdr, drm_sched_job_timedout); 865 - atomic_set(&sched->num_jobs, 0); 863 + atomic_set(&sched->score, 0); 866 864 atomic64_set(&sched->job_id_count, 0); 867 865 868 866 /* Each scheduler will run on a seperate kernel thread */
+3 -16
drivers/gpu/drm/stm/ltdc.c
··· 423 423 struct drm_crtc_state *old_state) 424 424 { 425 425 struct ltdc_device *ldev = crtc_to_ltdc(crtc); 426 + struct drm_device *ddev = crtc->dev; 426 427 427 428 DRM_DEBUG_DRIVER("\n"); 429 + 430 + pm_runtime_get_sync(ddev->dev); 428 431 429 432 /* Sets the background color value */ 430 433 reg_write(ldev->regs, LTDC_BCCR, BCCR_BCBLACK); ··· 506 503 struct drm_display_mode *adjusted_mode) 507 504 { 508 505 struct ltdc_device *ldev = crtc_to_ltdc(crtc); 509 - struct drm_device *ddev = crtc->dev; 510 506 int rate = mode->clock * 1000; 511 - bool runtime_active; 512 - int ret; 513 - 514 - runtime_active = pm_runtime_active(ddev->dev); 515 - 516 - if (runtime_active) 517 - pm_runtime_put_sync(ddev->dev); 518 507 519 508 if (clk_set_rate(ldev->pixel_clk, rate) < 0) { 520 509 DRM_ERROR("Cannot set rate (%dHz) for pixel clk\n", rate); ··· 514 519 } 515 520 516 521 adjusted_mode->clock = clk_get_rate(ldev->pixel_clk) / 1000; 517 - 518 - if (runtime_active) { 519 - ret = pm_runtime_get_sync(ddev->dev); 520 - if (ret) { 521 - DRM_ERROR("Failed to fixup mode, cannot get sync\n"); 522 - return false; 523 - } 524 - } 525 522 526 523 DRM_DEBUG_DRIVER("requested clock %dkHz, adjusted clock %dkHz\n", 527 524 mode->clock, adjusted_mode->clock);
-1
drivers/gpu/drm/tegra/dc.c
··· 1168 1168 tegra_crtc_atomic_destroy_state(crtc, crtc->state); 1169 1169 1170 1170 __drm_atomic_helper_crtc_reset(crtc, &state->base); 1171 - drm_crtc_vblank_reset(crtc); 1172 1171 } 1173 1172 1174 1173 static struct drm_crtc_state *
+1 -2
drivers/gpu/drm/tidss/tidss_crtc.c
··· 352 352 return; 353 353 } 354 354 355 - crtc->state = &tcrtc->base; 356 - crtc->state->crtc = crtc; 355 + __drm_atomic_helper_crtc_reset(crtc, &tcrtc->base); 357 356 } 358 357 359 358 static struct drm_crtc_state *tidss_crtc_duplicate_state(struct drm_crtc *crtc)
+2 -2
drivers/gpu/drm/tidss/tidss_dispc.c
··· 997 997 998 998 ieo = !!(tstate->bus_flags & DRM_BUS_FLAG_DE_LOW); 999 999 1000 - ipc = !!(tstate->bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE); 1000 + ipc = !!(tstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE); 1001 1001 1002 1002 /* always use the 'rf' setting */ 1003 1003 onoff = true; 1004 1004 1005 - rf = !!(tstate->bus_flags & DRM_BUS_FLAG_SYNC_POSEDGE); 1005 + rf = !!(tstate->bus_flags & DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE); 1006 1006 1007 1007 /* always use aligned syncs */ 1008 1008 align = true;
-5
drivers/gpu/drm/tidss/tidss_kms.c
··· 253 253 int tidss_modeset_init(struct tidss_device *tidss) 254 254 { 255 255 struct drm_device *ddev = &tidss->ddev; 256 - unsigned int i; 257 256 int ret; 258 257 259 258 dev_dbg(tidss->dev, "%s\n", __func__); ··· 276 277 ret = drm_vblank_init(ddev, tidss->num_crtcs); 277 278 if (ret) 278 279 return ret; 279 - 280 - /* Start with vertical blanking interrupt reporting disabled. */ 281 - for (i = 0; i < tidss->num_crtcs; ++i) 282 - drm_crtc_vblank_reset(tidss->crtcs[i]); 283 280 284 281 drm_mode_config_reset(ddev); 285 282
+13
drivers/gpu/drm/tilcdc/tilcdc_crtc.c
··· 537 537 tilcdc_crtc_disable(crtc); 538 538 } 539 539 540 + static void tilcdc_crtc_atomic_flush(struct drm_crtc *crtc, 541 + struct drm_crtc_state *old_state) 542 + { 543 + if (!crtc->state->event) 544 + return; 545 + 546 + spin_lock_irq(&crtc->dev->event_lock); 547 + drm_crtc_send_vblank_event(crtc, crtc->state->event); 548 + crtc->state->event = NULL; 549 + spin_unlock_irq(&crtc->dev->event_lock); 550 + } 551 + 540 552 void tilcdc_crtc_shutdown(struct drm_crtc *crtc) 541 553 { 542 554 tilcdc_crtc_off(crtc, true); ··· 834 822 .atomic_check = tilcdc_crtc_atomic_check, 835 823 .atomic_enable = tilcdc_crtc_atomic_enable, 836 824 .atomic_disable = tilcdc_crtc_atomic_disable, 825 + .atomic_flush = tilcdc_crtc_atomic_flush, 837 826 }; 838 827 839 828 void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
+1 -46
drivers/gpu/drm/tilcdc/tilcdc_drv.c
··· 87 87 return ret; 88 88 } 89 89 90 - static int tilcdc_commit(struct drm_device *dev, 91 - struct drm_atomic_state *state, 92 - bool async) 93 - { 94 - int ret; 95 - 96 - ret = drm_atomic_helper_prepare_planes(dev, state); 97 - if (ret) 98 - return ret; 99 - 100 - ret = drm_atomic_helper_swap_state(state, true); 101 - if (ret) { 102 - drm_atomic_helper_cleanup_planes(dev, state); 103 - return ret; 104 - } 105 - 106 - /* 107 - * Everything below can be run asynchronously without the need to grab 108 - * any modeset locks at all under one condition: It must be guaranteed 109 - * that the asynchronous work has either been cancelled (if the driver 110 - * supports it, which at least requires that the framebuffers get 111 - * cleaned up with drm_atomic_helper_cleanup_planes()) or completed 112 - * before the new state gets committed on the software side with 113 - * drm_atomic_helper_swap_state(). 114 - * 115 - * This scheme allows new atomic state updates to be prepared and 116 - * checked in parallel to the asynchronous completion of the previous 117 - * update. Which is important since compositors need to figure out the 118 - * composition of the next frame right after having submitted the 119 - * current layout. 120 - */ 121 - 122 - drm_atomic_helper_commit_modeset_disables(dev, state); 123 - 124 - drm_atomic_helper_commit_planes(dev, state, 0); 125 - 126 - drm_atomic_helper_commit_modeset_enables(dev, state); 127 - 128 - drm_atomic_helper_wait_for_vblanks(dev, state); 129 - 130 - drm_atomic_helper_cleanup_planes(dev, state); 131 - 132 - return 0; 133 - } 134 - 135 90 static const struct drm_mode_config_funcs mode_config_funcs = { 136 91 .fb_create = drm_gem_fb_create, 137 92 .atomic_check = tilcdc_atomic_check, 138 - .atomic_commit = tilcdc_commit, 93 + .atomic_commit = drm_atomic_helper_commit, 139 94 }; 140 95 141 96 static void modeset_init(struct drm_device *dev)
+5 -3
drivers/gpu/drm/tilcdc/tilcdc_plane.c
··· 83 83 if (WARN_ON(!state->fb || !state->crtc->state)) 84 84 return; 85 85 86 - tilcdc_crtc_update_fb(state->crtc, 87 - state->fb, 88 - state->crtc->state->event); 86 + if (tilcdc_crtc_update_fb(state->crtc, 87 + state->fb, 88 + state->crtc->state->event) == 0) { 89 + state->crtc->state->event = NULL; 90 + } 89 91 } 90 92 91 93 static const struct drm_plane_helper_funcs plane_helper_funcs = {
+42 -61
drivers/gpu/drm/ttm/ttm_bo.c
··· 85 85 drm_printf(p, " has_type: %d\n", man->has_type); 86 86 drm_printf(p, " use_type: %d\n", man->use_type); 87 87 drm_printf(p, " flags: 0x%08X\n", man->flags); 88 - drm_printf(p, " gpu_offset: 0x%08llX\n", man->gpu_offset); 89 88 drm_printf(p, " size: %llu\n", man->size); 90 89 drm_printf(p, " available_caching: 0x%08X\n", man->available_caching); 91 90 drm_printf(p, " default_caching: 0x%08X\n", man->default_caching); ··· 292 293 */ 293 294 294 295 if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) { 295 - if (bo->ttm == NULL) { 296 - bool zero = !(old_man->flags & TTM_MEMTYPE_FLAG_FIXED); 297 - ret = ttm_tt_create(bo, zero); 298 - if (ret) 299 - goto out_err; 300 - } 296 + bool zero = !(old_man->flags & TTM_MEMTYPE_FLAG_FIXED); 297 + 298 + ret = ttm_tt_create(bo, zero); 299 + if (ret) 300 + goto out_err; 301 301 302 302 ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement); 303 303 if (ret) ··· 312 314 if (bdev->driver->move_notify) 313 315 bdev->driver->move_notify(bo, evict, mem); 314 316 bo->mem = *mem; 315 - mem->mm_node = NULL; 316 317 goto moved; 317 318 } 318 319 } ··· 339 342 340 343 moved: 341 344 bo->evicted = false; 342 - 343 - if (bo->mem.mm_node) 344 - bo->offset = (bo->mem.start << PAGE_SHIFT) + 345 - bdev->man[bo->mem.mem_type].gpu_offset; 346 - else 347 - bo->offset = 0; 348 345 349 346 ctx->bytes_moved += bo->num_pages << PAGE_SHIFT; 350 347 return 0; ··· 615 624 ttm_bo_cleanup_memtype_use(bo); 616 625 dma_resv_unlock(bo->base.resv); 617 626 618 - BUG_ON(bo->mem.mm_node != NULL); 619 627 atomic_dec(&ttm_bo_glob.bo_count); 620 628 dma_fence_put(bo->moving); 621 629 if (!ttm_bo_uses_embedded_gem_object(bo)) ··· 657 667 placement.num_busy_placement = 0; 658 668 bdev->driver->evict_flags(bo, &placement); 659 669 660 - if (!placement.num_placement && !placement.num_busy_placement) { 661 - ret = ttm_bo_pipeline_gutting(bo); 662 - if (ret) 663 - return ret; 664 - 665 - return ttm_tt_create(bo, false); 666 - } 670 + if (!placement.num_placement && !placement.num_busy_placement) 671 + return ttm_bo_pipeline_gutting(bo); 667 672 668 673 evict_mem = bo->mem; 669 674 evict_mem.mm_node = NULL; ··· 841 856 return ret; 842 857 } 843 858 859 + static int ttm_bo_mem_get(struct ttm_buffer_object *bo, 860 + const struct ttm_place *place, 861 + struct ttm_mem_reg *mem) 862 + { 863 + struct ttm_mem_type_manager *man = &bo->bdev->man[mem->mem_type]; 864 + 865 + mem->mm_node = NULL; 866 + if (!man->func || !man->func->get_node) 867 + return 0; 868 + 869 + return man->func->get_node(man, bo, place, mem); 870 + } 871 + 844 872 void ttm_bo_mem_put(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem) 845 873 { 846 874 struct ttm_mem_type_manager *man = &bo->bdev->man[mem->mem_type]; 847 875 848 - if (mem->mm_node) 849 - (*man->func->put_node)(man, mem); 876 + if (!man->func || !man->func->put_node) 877 + return; 878 + 879 + man->func->put_node(man, mem); 880 + mem->mm_node = NULL; 881 + mem->mem_type = TTM_PL_SYSTEM; 850 882 } 851 883 EXPORT_SYMBOL(ttm_bo_mem_put); 852 884 ··· 917 915 918 916 ticket = dma_resv_locking_ctx(bo->base.resv); 919 917 do { 920 - ret = (*man->func->get_node)(man, bo, place, mem); 921 - if (unlikely(ret != 0)) 922 - return ret; 923 - if (mem->mm_node) 918 + ret = ttm_bo_mem_get(bo, place, mem); 919 + if (likely(!ret)) 924 920 break; 921 + if (unlikely(ret != -ENOSPC)) 922 + return ret; 925 923 ret = ttm_mem_evict_first(bdev, mem->mem_type, place, ctx, 926 924 ticket); 927 925 if (unlikely(ret != 0)) ··· 1047 1045 if (unlikely(ret)) 1048 1046 return ret; 1049 1047 1050 - mem->mm_node = NULL; 1051 1048 for (i = 0; i < placement->num_placement; ++i) { 1052 1049 const struct ttm_place *place = &placement->placement[i]; 1053 1050 struct ttm_mem_type_manager *man; ··· 1058 1057 goto error; 1059 1058 1060 1059 type_found = true; 1061 - mem->mm_node = NULL; 1062 - if (mem->mem_type == TTM_PL_SYSTEM) 1063 - return 0; 1064 - 1065 - man = &bdev->man[mem->mem_type]; 1066 - ret = (*man->func->get_node)(man, bo, place, mem); 1060 + ret = ttm_bo_mem_get(bo, place, mem); 1061 + if (ret == -ENOSPC) 1062 + continue; 1067 1063 if (unlikely(ret)) 1068 1064 goto error; 1069 1065 1070 - if (!mem->mm_node) 1071 - continue; 1072 - 1066 + man = &bdev->man[mem->mem_type]; 1073 1067 ret = ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu); 1074 1068 if (unlikely(ret)) { 1075 - (*man->func->put_node)(man, mem); 1069 + ttm_bo_mem_put(bo, mem); 1076 1070 if (ret == -EBUSY) 1077 1071 continue; 1078 1072 ··· 1086 1090 goto error; 1087 1091 1088 1092 type_found = true; 1089 - mem->mm_node = NULL; 1090 - if (mem->mem_type == TTM_PL_SYSTEM) 1091 - return 0; 1092 - 1093 1093 ret = ttm_bo_mem_force_space(bo, place, mem, ctx); 1094 - if (ret == 0 && mem->mm_node) 1094 + if (likely(!ret)) 1095 1095 return 0; 1096 1096 1097 1097 if (ret && ret != -EBUSY) ··· 1125 1133 mem.page_alignment = bo->mem.page_alignment; 1126 1134 mem.bus.io_reserved_vm = false; 1127 1135 mem.bus.io_reserved_count = 0; 1136 + mem.mm_node = NULL; 1137 + 1128 1138 /* 1129 1139 * Determine where to move the buffer. 1130 1140 */ ··· 1135 1141 goto out_unlock; 1136 1142 ret = ttm_bo_handle_move_mem(bo, &mem, false, ctx); 1137 1143 out_unlock: 1138 - if (ret && mem.mm_node) 1144 + if (ret) 1139 1145 ttm_bo_mem_put(bo, &mem); 1140 1146 return ret; 1141 1147 } ··· 1150 1156 for (i = 0; i < num_placement; i++) { 1151 1157 const struct ttm_place *heap = &places[i]; 1152 1158 1153 - if (mem->mm_node && (mem->start < heap->fpfn || 1159 + if ((mem->start < heap->fpfn || 1154 1160 (heap->lpfn != 0 && (mem->start + mem->num_pages) > heap->lpfn))) 1155 1161 continue; 1156 1162 ··· 1195 1201 /* 1196 1202 * Remove the backing store if no placement is given. 1197 1203 */ 1198 - if (!placement->num_placement && !placement->num_busy_placement) { 1199 - ret = ttm_bo_pipeline_gutting(bo); 1200 - if (ret) 1201 - return ret; 1202 - 1203 - return ttm_tt_create(bo, false); 1204 - } 1204 + if (!placement->num_placement && !placement->num_busy_placement) 1205 + return ttm_bo_pipeline_gutting(bo); 1205 1206 1206 1207 /* 1207 1208 * Check whether we need to move buffer. ··· 1212 1223 */ 1213 1224 ttm_flag_masked(&bo->mem.placement, new_flags, 1214 1225 ~TTM_PL_MASK_MEMTYPE); 1215 - } 1216 - /* 1217 - * We might need to add a TTM. 1218 - */ 1219 - if (bo->mem.mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { 1220 - ret = ttm_tt_create(bo, true); 1221 - if (ret) 1222 - return ret; 1223 1226 } 1224 1227 return 0; 1225 1228 }
+1 -1
drivers/gpu/drm/ttm/ttm_bo_manager.c
··· 86 86 mem->start = node->start; 87 87 } 88 88 89 - return 0; 89 + return ret; 90 90 } 91 91 92 92 static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man,
+5 -2
drivers/gpu/drm/ttm/ttm_bo_util.c
··· 532 532 .interruptible = false, 533 533 .no_wait_gpu = false 534 534 }; 535 - struct ttm_tt *ttm = bo->ttm; 535 + struct ttm_tt *ttm; 536 536 pgprot_t prot; 537 537 int ret; 538 538 539 - BUG_ON(!ttm); 539 + ret = ttm_tt_create(bo, true); 540 + if (ret) 541 + return ret; 540 542 543 + ttm = bo->ttm; 541 544 ret = ttm_tt_populate(ttm, &ctx); 542 545 if (ret) 543 546 return ret;
+5
drivers/gpu/drm/ttm/ttm_bo_vm.c
··· 349 349 350 350 }; 351 351 352 + if (ttm_tt_create(bo, true)) { 353 + ret = VM_FAULT_OOM; 354 + goto out_io_unlock; 355 + } 356 + 352 357 ttm = bo->ttm; 353 358 if (ttm_tt_populate(bo->ttm, &ctx)) { 354 359 ret = VM_FAULT_OOM;
+3 -1
drivers/gpu/drm/ttm/ttm_tt.c
··· 50 50 51 51 dma_resv_assert_held(bo->base.resv); 52 52 53 + if (bo->ttm) 54 + return 0; 55 + 53 56 if (bdev->need_dma32) 54 57 page_flags |= TTM_PAGE_FLAG_DMA32; 55 58 ··· 70 67 page_flags |= TTM_PAGE_FLAG_SG; 71 68 break; 72 69 default: 73 - bo->ttm = NULL; 74 70 pr_err("Illegal buffer object type\n"); 75 71 return -EINVAL; 76 72 }
+87 -344
drivers/gpu/drm/vc4/vc4_crtc.c
··· 184 184 return ret; 185 185 } 186 186 187 - static void vc4_crtc_destroy(struct drm_crtc *crtc) 187 + void vc4_crtc_destroy(struct drm_crtc *crtc) 188 188 { 189 189 drm_crtc_cleanup(crtc); 190 - } 191 - 192 - static void 193 - vc4_crtc_lut_load(struct drm_crtc *crtc) 194 - { 195 - struct drm_device *dev = crtc->dev; 196 - struct vc4_dev *vc4 = to_vc4_dev(dev); 197 - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 198 - u32 i; 199 - 200 - /* The LUT memory is laid out with each HVS channel in order, 201 - * each of which takes 256 writes for R, 256 for G, then 256 202 - * for B. 203 - */ 204 - HVS_WRITE(SCALER_GAMADDR, 205 - SCALER_GAMADDR_AUTOINC | 206 - (vc4_crtc->channel * 3 * crtc->gamma_size)); 207 - 208 - for (i = 0; i < crtc->gamma_size; i++) 209 - HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_r[i]); 210 - for (i = 0; i < crtc->gamma_size; i++) 211 - HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_g[i]); 212 - for (i = 0; i < crtc->gamma_size; i++) 213 - HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]); 214 - } 215 - 216 - static void 217 - vc4_crtc_update_gamma_lut(struct drm_crtc *crtc) 218 - { 219 - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 220 - struct drm_color_lut *lut = crtc->state->gamma_lut->data; 221 - u32 length = drm_color_lut_size(crtc->state->gamma_lut); 222 - u32 i; 223 - 224 - for (i = 0; i < length; i++) { 225 - vc4_crtc->lut_r[i] = drm_color_lut_extract(lut[i].red, 8); 226 - vc4_crtc->lut_g[i] = drm_color_lut_extract(lut[i].green, 8); 227 - vc4_crtc->lut_b[i] = drm_color_lut_extract(lut[i].blue, 8); 228 - } 229 - 230 - vc4_crtc_lut_load(crtc); 231 190 } 232 191 233 192 static u32 vc4_get_fifo_full_level(u32 format) ··· 322 363 323 364 static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) 324 365 { 325 - struct drm_device *dev = crtc->dev; 326 - struct vc4_dev *vc4 = to_vc4_dev(dev); 327 366 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 328 - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 329 - struct drm_display_mode *mode = &crtc->state->adjusted_mode; 330 - bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE; 331 367 bool debug_dump_regs = false; 332 368 333 369 if (debug_dump_regs) { ··· 332 378 drm_print_regset32(&p, &vc4_crtc->regset); 333 379 } 334 380 335 - if (vc4_crtc->channel == 2) { 336 - u32 dispctrl; 337 - u32 dsp3_mux; 381 + vc4_crtc_config_pv(crtc); 338 382 339 - /* 340 - * SCALER_DISPCTRL_DSP3 = X, where X < 2 means 'connect DSP3 to 341 - * FIFO X'. 342 - * SCALER_DISPCTRL_DSP3 = 3 means 'disable DSP 3'. 343 - * 344 - * DSP3 is connected to FIFO2 unless the transposer is 345 - * enabled. In this case, FIFO 2 is directly accessed by the 346 - * TXP IP, and we need to disable the FIFO2 -> pixelvalve1 347 - * route. 348 - */ 349 - if (vc4_state->feed_txp) 350 - dsp3_mux = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX); 351 - else 352 - dsp3_mux = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX); 353 - 354 - dispctrl = HVS_READ(SCALER_DISPCTRL) & 355 - ~SCALER_DISPCTRL_DSP3_MUX_MASK; 356 - HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux); 357 - } 358 - 359 - if (!vc4_state->feed_txp) 360 - vc4_crtc_config_pv(crtc); 361 - 362 - HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel), 363 - SCALER_DISPBKGND_AUTOHS | 364 - SCALER_DISPBKGND_GAMMA | 365 - (interlace ? SCALER_DISPBKGND_INTERLACE : 0)); 366 - 367 - /* Reload the LUT, since the SRAMs would have been disabled if 368 - * all CRTCs had SCALER_DISPBKGND_GAMMA unset at once. 369 - */ 370 - vc4_crtc_lut_load(crtc); 383 + vc4_hvs_mode_set_nofb(crtc); 371 384 372 385 if (debug_dump_regs) { 373 386 struct drm_printer p = drm_info_printer(&vc4_crtc->pdev->dev); ··· 356 435 struct drm_crtc_state *old_state) 357 436 { 358 437 struct drm_device *dev = crtc->dev; 359 - struct vc4_dev *vc4 = to_vc4_dev(dev); 360 438 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 361 - u32 chan = vc4_crtc->channel; 362 439 int ret; 440 + 363 441 require_hvs_enabled(dev); 364 442 365 443 /* Disable vblank irq handling before crtc is disabled. */ ··· 369 449 ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1); 370 450 WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n"); 371 451 372 - if (HVS_READ(SCALER_DISPCTRLX(chan)) & 373 - SCALER_DISPCTRLX_ENABLE) { 374 - HVS_WRITE(SCALER_DISPCTRLX(chan), 375 - SCALER_DISPCTRLX_RESET); 376 - 377 - /* While the docs say that reset is self-clearing, it 378 - * seems it doesn't actually. 379 - */ 380 - HVS_WRITE(SCALER_DISPCTRLX(chan), 0); 381 - } 382 - 383 - /* Once we leave, the scaler should be disabled and its fifo empty. */ 384 - 385 - WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_RESET); 386 - 387 - WARN_ON_ONCE(VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(chan)), 388 - SCALER_DISPSTATX_MODE) != 389 - SCALER_DISPSTATX_MODE_DISABLED); 390 - 391 - WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(chan)) & 392 - (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) != 393 - SCALER_DISPSTATX_EMPTY); 452 + vc4_hvs_atomic_disable(crtc, old_state); 394 453 395 454 /* 396 455 * Make sure we issue a vblank event after disabling the CRTC if ··· 385 486 } 386 487 } 387 488 388 - void vc4_crtc_txp_armed(struct drm_crtc_state *state) 389 - { 390 - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); 391 - 392 - vc4_state->txp_armed = true; 393 - } 394 - 395 - static void vc4_crtc_update_dlist(struct drm_crtc *crtc) 396 - { 397 - struct drm_device *dev = crtc->dev; 398 - struct vc4_dev *vc4 = to_vc4_dev(dev); 399 - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 400 - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 401 - 402 - if (crtc->state->event) { 403 - unsigned long flags; 404 - 405 - crtc->state->event->pipe = drm_crtc_index(crtc); 406 - 407 - WARN_ON(drm_crtc_vblank_get(crtc) != 0); 408 - 409 - spin_lock_irqsave(&dev->event_lock, flags); 410 - 411 - if (!vc4_state->feed_txp || vc4_state->txp_armed) { 412 - vc4_crtc->event = crtc->state->event; 413 - crtc->state->event = NULL; 414 - } 415 - 416 - HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 417 - vc4_state->mm.start); 418 - 419 - spin_unlock_irqrestore(&dev->event_lock, flags); 420 - } else { 421 - HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 422 - vc4_state->mm.start); 423 - } 424 - } 425 - 426 489 static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, 427 490 struct drm_crtc_state *old_state) 428 491 { 429 492 struct drm_device *dev = crtc->dev; 430 - struct vc4_dev *vc4 = to_vc4_dev(dev); 431 493 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 432 - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 433 - struct drm_display_mode *mode = &crtc->state->adjusted_mode; 434 494 435 495 require_hvs_enabled(dev); 436 496 ··· 397 539 * drm_crtc_get_vblank() fails in vc4_crtc_update_dlist(). 398 540 */ 399 541 drm_crtc_vblank_on(crtc); 400 - vc4_crtc_update_dlist(crtc); 401 542 402 - /* Turn on the scaler, which will wait for vstart to start 403 - * compositing. 404 - * When feeding the transposer, we should operate in oneshot 405 - * mode. 406 - */ 407 - HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel), 408 - VC4_SET_FIELD(mode->hdisplay, SCALER_DISPCTRLX_WIDTH) | 409 - VC4_SET_FIELD(mode->vdisplay, SCALER_DISPCTRLX_HEIGHT) | 410 - SCALER_DISPCTRLX_ENABLE | 411 - (vc4_state->feed_txp ? SCALER_DISPCTRLX_ONESHOT : 0)); 543 + vc4_hvs_atomic_enable(crtc, old_state); 412 544 413 545 /* When feeding the transposer block the pixelvalve is unneeded and 414 546 * should not be enabled. 415 547 */ 416 - if (!vc4_state->feed_txp) 417 - CRTC_WRITE(PV_V_CONTROL, 418 - CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN); 548 + CRTC_WRITE(PV_V_CONTROL, 549 + CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN); 419 550 } 420 551 421 552 static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc, ··· 455 608 struct drm_crtc_state *state) 456 609 { 457 610 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); 458 - struct drm_device *dev = crtc->dev; 459 - struct vc4_dev *vc4 = to_vc4_dev(dev); 460 - struct drm_plane *plane; 461 - unsigned long flags; 462 - const struct drm_plane_state *plane_state; 463 611 struct drm_connector *conn; 464 612 struct drm_connector_state *conn_state; 465 - u32 dlist_count = 0; 466 613 int ret, i; 467 614 468 - /* The pixelvalve can only feed one encoder (and encoders are 469 - * 1:1 with connectors.) 470 - */ 471 - if (hweight32(state->connector_mask) > 1) 472 - return -EINVAL; 473 - 474 - drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state) 475 - dlist_count += vc4_plane_dlist_size(plane_state); 476 - 477 - dlist_count++; /* Account for SCALER_CTL0_END. */ 478 - 479 - spin_lock_irqsave(&vc4->hvs->mm_lock, flags); 480 - ret = drm_mm_insert_node(&vc4->hvs->dlist_mm, &vc4_state->mm, 481 - dlist_count); 482 - spin_unlock_irqrestore(&vc4->hvs->mm_lock, flags); 615 + ret = vc4_hvs_atomic_check(crtc, state); 483 616 if (ret) 484 617 return ret; 485 618 486 619 for_each_new_connector_in_state(state->state, conn, conn_state, i) { 487 620 if (conn_state->crtc != crtc) 488 621 continue; 489 - 490 - /* The writeback connector is implemented using the transposer 491 - * block which is directly taking its data from the HVS FIFO. 492 - */ 493 - if (conn->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) { 494 - state->no_vblank = true; 495 - vc4_state->feed_txp = true; 496 - } else { 497 - state->no_vblank = false; 498 - vc4_state->feed_txp = false; 499 - } 500 622 501 623 vc4_state->margins.left = conn_state->tv.margins.left; 502 624 vc4_state->margins.right = conn_state->tv.margins.right; ··· 475 659 } 476 660 477 661 return 0; 478 - } 479 - 480 - static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, 481 - struct drm_crtc_state *old_state) 482 - { 483 - struct drm_device *dev = crtc->dev; 484 - struct vc4_dev *vc4 = to_vc4_dev(dev); 485 - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 486 - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 487 - struct drm_plane *plane; 488 - struct vc4_plane_state *vc4_plane_state; 489 - bool debug_dump_regs = false; 490 - bool enable_bg_fill = false; 491 - u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start; 492 - u32 __iomem *dlist_next = dlist_start; 493 - 494 - if (debug_dump_regs) { 495 - DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc)); 496 - vc4_hvs_dump_state(dev); 497 - } 498 - 499 - /* Copy all the active planes' dlist contents to the hardware dlist. */ 500 - drm_atomic_crtc_for_each_plane(plane, crtc) { 501 - /* Is this the first active plane? */ 502 - if (dlist_next == dlist_start) { 503 - /* We need to enable background fill when a plane 504 - * could be alpha blending from the background, i.e. 505 - * where no other plane is underneath. It suffices to 506 - * consider the first active plane here since we set 507 - * needs_bg_fill such that either the first plane 508 - * already needs it or all planes on top blend from 509 - * the first or a lower plane. 510 - */ 511 - vc4_plane_state = to_vc4_plane_state(plane->state); 512 - enable_bg_fill = vc4_plane_state->needs_bg_fill; 513 - } 514 - 515 - dlist_next += vc4_plane_write_dlist(plane, dlist_next); 516 - } 517 - 518 - writel(SCALER_CTL0_END, dlist_next); 519 - dlist_next++; 520 - 521 - WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); 522 - 523 - if (enable_bg_fill) 524 - /* This sets a black background color fill, as is the case 525 - * with other DRM drivers. 526 - */ 527 - HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel), 528 - HVS_READ(SCALER_DISPBKGNDX(vc4_crtc->channel)) | 529 - SCALER_DISPBKGND_FILL); 530 - 531 - /* Only update DISPLIST if the CRTC was already running and is not 532 - * being disabled. 533 - * vc4_crtc_enable() takes care of updating the dlist just after 534 - * re-enabling VBLANK interrupts and before enabling the engine. 535 - * If the CRTC is being disabled, there's no point in updating this 536 - * information. 537 - */ 538 - if (crtc->state->active && old_state->active) 539 - vc4_crtc_update_dlist(crtc); 540 - 541 - if (crtc->state->color_mgmt_changed) { 542 - u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(vc4_crtc->channel)); 543 - 544 - if (crtc->state->gamma_lut) { 545 - vc4_crtc_update_gamma_lut(crtc); 546 - dispbkgndx |= SCALER_DISPBKGND_GAMMA; 547 - } else { 548 - /* Unsetting DISPBKGND_GAMMA skips the gamma lut step 549 - * in hardware, which is the same as a linear lut that 550 - * DRM expects us to use in absence of a user lut. 551 - */ 552 - dispbkgndx &= ~SCALER_DISPBKGND_GAMMA; 553 - } 554 - HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel), dispbkgndx); 555 - } 556 - 557 - if (debug_dump_regs) { 558 - DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); 559 - vc4_hvs_dump_state(dev); 560 - } 561 662 } 562 663 563 664 static int vc4_enable_vblank(struct drm_crtc *crtc) ··· 675 942 return 0; 676 943 } 677 944 678 - static int vc4_page_flip(struct drm_crtc *crtc, 679 - struct drm_framebuffer *fb, 680 - struct drm_pending_vblank_event *event, 681 - uint32_t flags, 682 - struct drm_modeset_acquire_ctx *ctx) 945 + int vc4_page_flip(struct drm_crtc *crtc, 946 + struct drm_framebuffer *fb, 947 + struct drm_pending_vblank_event *event, 948 + uint32_t flags, 949 + struct drm_modeset_acquire_ctx *ctx) 683 950 { 684 951 if (flags & DRM_MODE_PAGE_FLIP_ASYNC) 685 952 return vc4_async_page_flip(crtc, fb, event, flags); ··· 687 954 return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx); 688 955 } 689 956 690 - static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc) 957 + struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc) 691 958 { 692 959 struct vc4_crtc_state *vc4_state, *old_vc4_state; 693 960 ··· 703 970 return &vc4_state->base; 704 971 } 705 972 706 - static void vc4_crtc_destroy_state(struct drm_crtc *crtc, 707 - struct drm_crtc_state *state) 973 + void vc4_crtc_destroy_state(struct drm_crtc *crtc, 974 + struct drm_crtc_state *state) 708 975 { 709 976 struct vc4_dev *vc4 = to_vc4_dev(crtc->dev); 710 977 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); ··· 721 988 drm_atomic_helper_crtc_destroy_state(crtc, state); 722 989 } 723 990 724 - static void 725 - vc4_crtc_reset(struct drm_crtc *crtc) 991 + void vc4_crtc_reset(struct drm_crtc *crtc) 726 992 { 727 993 if (crtc->state) 728 994 vc4_crtc_destroy_state(crtc, crtc->state); 729 - 730 995 crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL); 731 996 if (crtc->state) 732 - crtc->state->crtc = crtc; 997 + __drm_atomic_helper_crtc_reset(crtc, crtc->state); 733 998 } 734 999 735 1000 static const struct drm_crtc_funcs vc4_crtc_funcs = { ··· 750 1019 .mode_set_nofb = vc4_crtc_mode_set_nofb, 751 1020 .mode_valid = vc4_crtc_mode_valid, 752 1021 .atomic_check = vc4_crtc_atomic_check, 753 - .atomic_flush = vc4_crtc_atomic_flush, 1022 + .atomic_flush = vc4_hvs_atomic_flush, 754 1023 .atomic_enable = vc4_crtc_atomic_enable, 755 1024 .atomic_disable = vc4_crtc_atomic_disable, 756 1025 .get_scanout_position = vc4_crtc_get_scanout_position, 757 1026 }; 758 1027 759 - static const struct vc4_crtc_data bcm2835_pv0_data = { 760 - .hvs_channel = 0, 1028 + static const struct vc4_pv_data bcm2835_pv0_data = { 1029 + .base = { 1030 + .hvs_channel = 0, 1031 + }, 761 1032 .debugfs_name = "crtc0_regs", 762 1033 .encoder_types = { 763 1034 [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0, ··· 767 1034 }, 768 1035 }; 769 1036 770 - static const struct vc4_crtc_data bcm2835_pv1_data = { 771 - .hvs_channel = 2, 1037 + static const struct vc4_pv_data bcm2835_pv1_data = { 1038 + .base = { 1039 + .hvs_channel = 2, 1040 + }, 772 1041 .debugfs_name = "crtc1_regs", 773 1042 .encoder_types = { 774 1043 [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1, ··· 778 1043 }, 779 1044 }; 780 1045 781 - static const struct vc4_crtc_data bcm2835_pv2_data = { 782 - .hvs_channel = 1, 1046 + static const struct vc4_pv_data bcm2835_pv2_data = { 1047 + .base = { 1048 + .hvs_channel = 1, 1049 + }, 783 1050 .debugfs_name = "crtc2_regs", 784 1051 .encoder_types = { 785 1052 [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI, ··· 800 1063 struct drm_crtc *crtc) 801 1064 { 802 1065 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 803 - const struct vc4_crtc_data *crtc_data = vc4_crtc->data; 804 - const enum vc4_encoder_type *encoder_types = crtc_data->encoder_types; 1066 + const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc); 1067 + const enum vc4_encoder_type *encoder_types = pv_data->encoder_types; 805 1068 struct drm_encoder *encoder; 806 1069 807 1070 drm_for_each_encoder(encoder, drm) { 808 1071 struct vc4_encoder *vc4_encoder; 809 1072 int i; 810 1073 811 - /* HVS FIFO2 can feed the TXP IP. */ 812 - if (crtc_data->hvs_channel == 2 && 813 - encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL) { 814 - encoder->possible_crtcs |= drm_crtc_mask(crtc); 815 - continue; 816 - } 817 - 818 1074 vc4_encoder = to_vc4_encoder(encoder); 819 - for (i = 0; i < ARRAY_SIZE(crtc_data->encoder_types); i++) { 1075 + for (i = 0; i < ARRAY_SIZE(pv_data->encoder_types); i++) { 820 1076 if (vc4_encoder->type == encoder_types[i]) { 821 1077 vc4_encoder->clock_select = i; 822 1078 encoder->possible_crtcs |= drm_crtc_mask(crtc); ··· 835 1105 vc4_crtc->cob_size = top - base + 4; 836 1106 } 837 1107 1108 + int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc, 1109 + const struct drm_crtc_funcs *crtc_funcs, 1110 + const struct drm_crtc_helper_funcs *crtc_helper_funcs) 1111 + { 1112 + struct drm_crtc *crtc = &vc4_crtc->base; 1113 + struct drm_plane *primary_plane; 1114 + unsigned int i; 1115 + 1116 + /* For now, we create just the primary and the legacy cursor 1117 + * planes. We should be able to stack more planes on easily, 1118 + * but to do that we would need to compute the bandwidth 1119 + * requirement of the plane configuration, and reject ones 1120 + * that will take too much. 1121 + */ 1122 + primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY); 1123 + if (IS_ERR(primary_plane)) { 1124 + dev_err(drm->dev, "failed to construct primary plane\n"); 1125 + return PTR_ERR(primary_plane); 1126 + } 1127 + 1128 + drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL, 1129 + crtc_funcs, NULL); 1130 + drm_crtc_helper_add(crtc, crtc_helper_funcs); 1131 + vc4_crtc->channel = vc4_crtc->data->hvs_channel; 1132 + drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r)); 1133 + drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size); 1134 + 1135 + /* We support CTM, but only for one CRTC at a time. It's therefore 1136 + * implemented as private driver state in vc4_kms, not here. 1137 + */ 1138 + drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size); 1139 + vc4_crtc_get_cob_allocation(vc4_crtc); 1140 + 1141 + for (i = 0; i < crtc->gamma_size; i++) { 1142 + vc4_crtc->lut_r[i] = i; 1143 + vc4_crtc->lut_g[i] = i; 1144 + vc4_crtc->lut_b[i] = i; 1145 + } 1146 + 1147 + return 0; 1148 + } 1149 + 838 1150 static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) 839 1151 { 840 1152 struct platform_device *pdev = to_platform_device(dev); 841 1153 struct drm_device *drm = dev_get_drvdata(master); 842 - const struct vc4_crtc_data *pv_data; 1154 + const struct vc4_pv_data *pv_data; 843 1155 struct vc4_crtc *vc4_crtc; 844 1156 struct drm_crtc *crtc; 845 - struct drm_plane *primary_plane, *destroy_plane, *temp; 846 - int ret, i; 1157 + struct drm_plane *destroy_plane, *temp; 1158 + int ret; 847 1159 848 1160 vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL); 849 1161 if (!vc4_crtc) ··· 895 1123 pv_data = of_device_get_match_data(dev); 896 1124 if (!pv_data) 897 1125 return -ENODEV; 898 - vc4_crtc->data = pv_data; 1126 + vc4_crtc->data = &pv_data->base; 899 1127 vc4_crtc->pdev = pdev; 900 1128 901 1129 vc4_crtc->regs = vc4_ioremap_regs(pdev, 0); ··· 906 1134 vc4_crtc->regset.regs = crtc_regs; 907 1135 vc4_crtc->regset.nregs = ARRAY_SIZE(crtc_regs); 908 1136 909 - /* For now, we create just the primary and the legacy cursor 910 - * planes. We should be able to stack more planes on easily, 911 - * but to do that we would need to compute the bandwidth 912 - * requirement of the plane configuration, and reject ones 913 - * that will take too much. 914 - */ 915 - primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY); 916 - if (IS_ERR(primary_plane)) { 917 - dev_err(dev, "failed to construct primary plane\n"); 918 - ret = PTR_ERR(primary_plane); 919 - goto err; 920 - } 921 - 922 - drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL, 923 - &vc4_crtc_funcs, NULL); 924 - drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs); 925 - vc4_crtc->channel = vc4_crtc->data->hvs_channel; 926 - drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r)); 927 - drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size); 928 - 929 - /* We support CTM, but only for one CRTC at a time. It's therefore 930 - * implemented as private driver state in vc4_kms, not here. 931 - */ 932 - drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size); 933 - 934 - vc4_crtc_get_cob_allocation(vc4_crtc); 1137 + ret = vc4_crtc_init(drm, vc4_crtc, 1138 + &vc4_crtc_funcs, &vc4_crtc_helper_funcs); 1139 + if (ret) 1140 + return ret; 1141 + vc4_set_crtc_possible_masks(drm, crtc); 935 1142 936 1143 CRTC_WRITE(PV_INTEN, 0); 937 1144 CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START); ··· 918 1167 vc4_crtc_irq_handler, 0, "vc4 crtc", vc4_crtc); 919 1168 if (ret) 920 1169 goto err_destroy_planes; 921 - 922 - vc4_set_crtc_possible_masks(drm, crtc); 923 - 924 - for (i = 0; i < crtc->gamma_size; i++) { 925 - vc4_crtc->lut_r[i] = i; 926 - vc4_crtc->lut_g[i] = i; 927 - vc4_crtc->lut_b[i] = i; 928 - } 929 1170 930 1171 platform_set_drvdata(pdev, vc4_crtc); 931 1172 ··· 932 1189 if (destroy_plane->possible_crtcs == drm_crtc_mask(crtc)) 933 1190 destroy_plane->funcs->destroy(destroy_plane); 934 1191 } 935 - err: 1192 + 936 1193 return ret; 937 1194 } 938 1195
+1 -1
drivers/gpu/drm/vc4/vc4_drv.c
··· 343 343 &vc4_vec_driver, 344 344 &vc4_dpi_driver, 345 345 &vc4_dsi_driver, 346 - &vc4_txp_driver, 347 346 &vc4_hvs_driver, 347 + &vc4_txp_driver, 348 348 &vc4_crtc_driver, 349 349 &vc4_v3d_driver, 350 350 };
+37 -1
drivers/gpu/drm/vc4/vc4_drv.h
··· 443 443 struct vc4_crtc_data { 444 444 /* Which channel of the HVS this pixelvalve sources from. */ 445 445 int hvs_channel; 446 + }; 447 + 448 + struct vc4_pv_data { 449 + struct vc4_crtc_data base; 446 450 447 451 enum vc4_encoder_type encoder_types[4]; 448 452 const char *debugfs_name; 453 + 449 454 }; 450 455 451 456 struct vc4_crtc { ··· 480 475 to_vc4_crtc(struct drm_crtc *crtc) 481 476 { 482 477 return (struct vc4_crtc *)crtc; 478 + } 479 + 480 + static inline const struct vc4_crtc_data * 481 + vc4_crtc_to_vc4_crtc_data(const struct vc4_crtc *crtc) 482 + { 483 + return crtc->data; 484 + } 485 + 486 + static inline const struct vc4_pv_data * 487 + vc4_crtc_to_vc4_pv_data(const struct vc4_crtc *crtc) 488 + { 489 + const struct vc4_crtc_data *data = vc4_crtc_to_vc4_crtc_data(crtc); 490 + 491 + return container_of(data, struct vc4_pv_data, base); 483 492 } 484 493 485 494 struct vc4_crtc_state { ··· 794 775 795 776 /* vc4_crtc.c */ 796 777 extern struct platform_driver vc4_crtc_driver; 778 + int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc, 779 + const struct drm_crtc_funcs *crtc_funcs, 780 + const struct drm_crtc_helper_funcs *crtc_helper_funcs); 781 + void vc4_crtc_destroy(struct drm_crtc *crtc); 782 + int vc4_page_flip(struct drm_crtc *crtc, 783 + struct drm_framebuffer *fb, 784 + struct drm_pending_vblank_event *event, 785 + uint32_t flags, 786 + struct drm_modeset_acquire_ctx *ctx); 787 + struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc); 788 + void vc4_crtc_destroy_state(struct drm_crtc *crtc, 789 + struct drm_crtc_state *state); 790 + void vc4_crtc_reset(struct drm_crtc *crtc); 797 791 void vc4_crtc_handle_vblank(struct vc4_crtc *crtc); 798 - void vc4_crtc_txp_armed(struct drm_crtc_state *state); 799 792 void vc4_crtc_get_margins(struct drm_crtc_state *state, 800 793 unsigned int *right, unsigned int *left, 801 794 unsigned int *top, unsigned int *bottom); ··· 888 857 889 858 /* vc4_hvs.c */ 890 859 extern struct platform_driver vc4_hvs_driver; 860 + int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state); 861 + void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state); 862 + void vc4_hvs_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state); 863 + void vc4_hvs_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *state); 864 + void vc4_hvs_mode_set_nofb(struct drm_crtc *crtc); 891 865 void vc4_hvs_dump_state(struct drm_device *dev); 892 866 void vc4_hvs_unmask_underrun(struct drm_device *dev, int channel); 893 867 void vc4_hvs_mask_underrun(struct drm_device *dev, int channel);
+291
drivers/gpu/drm/vc4/vc4_hvs.c
··· 23 23 #include <linux/platform_device.h> 24 24 25 25 #include <drm/drm_atomic_helper.h> 26 + #include <drm/drm_vblank.h> 26 27 27 28 #include "vc4_drv.h" 28 29 #include "vc4_regs.h" ··· 153 152 } 154 153 155 154 return 0; 155 + } 156 + 157 + static void vc4_hvs_lut_load(struct drm_crtc *crtc) 158 + { 159 + struct drm_device *dev = crtc->dev; 160 + struct vc4_dev *vc4 = to_vc4_dev(dev); 161 + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 162 + u32 i; 163 + 164 + /* The LUT memory is laid out with each HVS channel in order, 165 + * each of which takes 256 writes for R, 256 for G, then 256 166 + * for B. 167 + */ 168 + HVS_WRITE(SCALER_GAMADDR, 169 + SCALER_GAMADDR_AUTOINC | 170 + (vc4_crtc->channel * 3 * crtc->gamma_size)); 171 + 172 + for (i = 0; i < crtc->gamma_size; i++) 173 + HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_r[i]); 174 + for (i = 0; i < crtc->gamma_size; i++) 175 + HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_g[i]); 176 + for (i = 0; i < crtc->gamma_size; i++) 177 + HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]); 178 + } 179 + 180 + static void vc4_hvs_update_gamma_lut(struct drm_crtc *crtc) 181 + { 182 + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 183 + struct drm_color_lut *lut = crtc->state->gamma_lut->data; 184 + u32 length = drm_color_lut_size(crtc->state->gamma_lut); 185 + u32 i; 186 + 187 + for (i = 0; i < length; i++) { 188 + vc4_crtc->lut_r[i] = drm_color_lut_extract(lut[i].red, 8); 189 + vc4_crtc->lut_g[i] = drm_color_lut_extract(lut[i].green, 8); 190 + vc4_crtc->lut_b[i] = drm_color_lut_extract(lut[i].blue, 8); 191 + } 192 + 193 + vc4_hvs_lut_load(crtc); 194 + } 195 + 196 + int vc4_hvs_atomic_check(struct drm_crtc *crtc, 197 + struct drm_crtc_state *state) 198 + { 199 + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); 200 + struct drm_device *dev = crtc->dev; 201 + struct vc4_dev *vc4 = to_vc4_dev(dev); 202 + struct drm_plane *plane; 203 + unsigned long flags; 204 + const struct drm_plane_state *plane_state; 205 + u32 dlist_count = 0; 206 + int ret; 207 + 208 + /* The pixelvalve can only feed one encoder (and encoders are 209 + * 1:1 with connectors.) 210 + */ 211 + if (hweight32(state->connector_mask) > 1) 212 + return -EINVAL; 213 + 214 + drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state) 215 + dlist_count += vc4_plane_dlist_size(plane_state); 216 + 217 + dlist_count++; /* Account for SCALER_CTL0_END. */ 218 + 219 + spin_lock_irqsave(&vc4->hvs->mm_lock, flags); 220 + ret = drm_mm_insert_node(&vc4->hvs->dlist_mm, &vc4_state->mm, 221 + dlist_count); 222 + spin_unlock_irqrestore(&vc4->hvs->mm_lock, flags); 223 + if (ret) 224 + return ret; 225 + 226 + return 0; 227 + } 228 + 229 + static void vc4_hvs_update_dlist(struct drm_crtc *crtc) 230 + { 231 + struct drm_device *dev = crtc->dev; 232 + struct vc4_dev *vc4 = to_vc4_dev(dev); 233 + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 234 + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 235 + 236 + if (crtc->state->event) { 237 + unsigned long flags; 238 + 239 + crtc->state->event->pipe = drm_crtc_index(crtc); 240 + 241 + WARN_ON(drm_crtc_vblank_get(crtc) != 0); 242 + 243 + spin_lock_irqsave(&dev->event_lock, flags); 244 + 245 + if (!vc4_state->feed_txp || vc4_state->txp_armed) { 246 + vc4_crtc->event = crtc->state->event; 247 + crtc->state->event = NULL; 248 + } 249 + 250 + HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 251 + vc4_state->mm.start); 252 + 253 + spin_unlock_irqrestore(&dev->event_lock, flags); 254 + } else { 255 + HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 256 + vc4_state->mm.start); 257 + } 258 + } 259 + 260 + void vc4_hvs_atomic_enable(struct drm_crtc *crtc, 261 + struct drm_crtc_state *old_state) 262 + { 263 + struct drm_device *dev = crtc->dev; 264 + struct vc4_dev *vc4 = to_vc4_dev(dev); 265 + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 266 + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 267 + struct drm_display_mode *mode = &crtc->state->adjusted_mode; 268 + bool oneshot = vc4_state->feed_txp; 269 + u32 dispctrl; 270 + 271 + vc4_hvs_update_dlist(crtc); 272 + 273 + /* Turn on the scaler, which will wait for vstart to start 274 + * compositing. 275 + * When feeding the transposer, we should operate in oneshot 276 + * mode. 277 + */ 278 + dispctrl = SCALER_DISPCTRLX_ENABLE; 279 + dispctrl |= VC4_SET_FIELD(mode->hdisplay, 280 + SCALER_DISPCTRLX_WIDTH) | 281 + VC4_SET_FIELD(mode->vdisplay, 282 + SCALER_DISPCTRLX_HEIGHT) | 283 + (oneshot ? SCALER_DISPCTRLX_ONESHOT : 0); 284 + 285 + HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel), dispctrl); 286 + } 287 + 288 + void vc4_hvs_atomic_disable(struct drm_crtc *crtc, 289 + struct drm_crtc_state *old_state) 290 + { 291 + struct drm_device *dev = crtc->dev; 292 + struct vc4_dev *vc4 = to_vc4_dev(dev); 293 + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 294 + u32 chan = vc4_crtc->channel; 295 + 296 + if (HVS_READ(SCALER_DISPCTRLX(chan)) & 297 + SCALER_DISPCTRLX_ENABLE) { 298 + HVS_WRITE(SCALER_DISPCTRLX(chan), 299 + SCALER_DISPCTRLX_RESET); 300 + 301 + /* While the docs say that reset is self-clearing, it 302 + * seems it doesn't actually. 303 + */ 304 + HVS_WRITE(SCALER_DISPCTRLX(chan), 0); 305 + } 306 + 307 + /* Once we leave, the scaler should be disabled and its fifo empty. */ 308 + 309 + WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_RESET); 310 + 311 + WARN_ON_ONCE(VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(chan)), 312 + SCALER_DISPSTATX_MODE) != 313 + SCALER_DISPSTATX_MODE_DISABLED); 314 + 315 + WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(chan)) & 316 + (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) != 317 + SCALER_DISPSTATX_EMPTY); 318 + } 319 + 320 + void vc4_hvs_atomic_flush(struct drm_crtc *crtc, 321 + struct drm_crtc_state *old_state) 322 + { 323 + struct drm_device *dev = crtc->dev; 324 + struct vc4_dev *vc4 = to_vc4_dev(dev); 325 + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 326 + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 327 + struct drm_plane *plane; 328 + struct vc4_plane_state *vc4_plane_state; 329 + bool debug_dump_regs = false; 330 + bool enable_bg_fill = false; 331 + u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start; 332 + u32 __iomem *dlist_next = dlist_start; 333 + 334 + if (debug_dump_regs) { 335 + DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc)); 336 + vc4_hvs_dump_state(dev); 337 + } 338 + 339 + /* Copy all the active planes' dlist contents to the hardware dlist. */ 340 + drm_atomic_crtc_for_each_plane(plane, crtc) { 341 + /* Is this the first active plane? */ 342 + if (dlist_next == dlist_start) { 343 + /* We need to enable background fill when a plane 344 + * could be alpha blending from the background, i.e. 345 + * where no other plane is underneath. It suffices to 346 + * consider the first active plane here since we set 347 + * needs_bg_fill such that either the first plane 348 + * already needs it or all planes on top blend from 349 + * the first or a lower plane. 350 + */ 351 + vc4_plane_state = to_vc4_plane_state(plane->state); 352 + enable_bg_fill = vc4_plane_state->needs_bg_fill; 353 + } 354 + 355 + dlist_next += vc4_plane_write_dlist(plane, dlist_next); 356 + } 357 + 358 + writel(SCALER_CTL0_END, dlist_next); 359 + dlist_next++; 360 + 361 + WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); 362 + 363 + if (enable_bg_fill) 364 + /* This sets a black background color fill, as is the case 365 + * with other DRM drivers. 366 + */ 367 + HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel), 368 + HVS_READ(SCALER_DISPBKGNDX(vc4_crtc->channel)) | 369 + SCALER_DISPBKGND_FILL); 370 + 371 + /* Only update DISPLIST if the CRTC was already running and is not 372 + * being disabled. 373 + * vc4_crtc_enable() takes care of updating the dlist just after 374 + * re-enabling VBLANK interrupts and before enabling the engine. 375 + * If the CRTC is being disabled, there's no point in updating this 376 + * information. 377 + */ 378 + if (crtc->state->active && old_state->active) 379 + vc4_hvs_update_dlist(crtc); 380 + 381 + if (crtc->state->color_mgmt_changed) { 382 + u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(vc4_crtc->channel)); 383 + 384 + if (crtc->state->gamma_lut) { 385 + vc4_hvs_update_gamma_lut(crtc); 386 + dispbkgndx |= SCALER_DISPBKGND_GAMMA; 387 + } else { 388 + /* Unsetting DISPBKGND_GAMMA skips the gamma lut step 389 + * in hardware, which is the same as a linear lut that 390 + * DRM expects us to use in absence of a user lut. 391 + */ 392 + dispbkgndx &= ~SCALER_DISPBKGND_GAMMA; 393 + } 394 + HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel), dispbkgndx); 395 + } 396 + 397 + if (debug_dump_regs) { 398 + DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); 399 + vc4_hvs_dump_state(dev); 400 + } 401 + } 402 + 403 + void vc4_hvs_mode_set_nofb(struct drm_crtc *crtc) 404 + { 405 + struct drm_device *dev = crtc->dev; 406 + struct vc4_dev *vc4 = to_vc4_dev(dev); 407 + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 408 + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 409 + struct drm_display_mode *mode = &crtc->state->adjusted_mode; 410 + bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE; 411 + 412 + if (vc4_crtc->data->hvs_channel == 2) { 413 + u32 dispctrl; 414 + u32 dsp3_mux; 415 + 416 + /* 417 + * SCALER_DISPCTRL_DSP3 = X, where X < 2 means 'connect DSP3 to 418 + * FIFO X'. 419 + * SCALER_DISPCTRL_DSP3 = 3 means 'disable DSP 3'. 420 + * 421 + * DSP3 is connected to FIFO2 unless the transposer is 422 + * enabled. In this case, FIFO 2 is directly accessed by the 423 + * TXP IP, and we need to disable the FIFO2 -> pixelvalve1 424 + * route. 425 + */ 426 + if (vc4_state->feed_txp) 427 + dsp3_mux = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX); 428 + else 429 + dsp3_mux = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX); 430 + 431 + dispctrl = HVS_READ(SCALER_DISPCTRL) & 432 + ~SCALER_DISPCTRL_DSP3_MUX_MASK; 433 + HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux); 434 + } 435 + 436 + HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel), 437 + SCALER_DISPBKGND_AUTOHS | 438 + SCALER_DISPBKGND_GAMMA | 439 + (interlace ? SCALER_DISPBKGND_INTERLACE : 0)); 440 + 441 + /* Reload the LUT, since the SRAMs would have been disabled if 442 + * all CRTCs had SCALER_DISPBKGND_GAMMA unset at once. 443 + */ 444 + vc4_hvs_lut_load(crtc); 156 445 } 157 446 158 447 void vc4_hvs_mask_underrun(struct drm_device *dev, int channel)
+4 -5
drivers/gpu/drm/vc4/vc4_regs.h
··· 6 6 #ifndef VC4_REGS_H 7 7 #define VC4_REGS_H 8 8 9 + #include <linux/bitfield.h> 9 10 #include <linux/bitops.h> 10 11 11 12 #define VC4_MASK(high, low) ((u32)GENMASK(high, low)) 12 13 /* Using the GNU statement expression extension */ 13 14 #define VC4_SET_FIELD(value, field) \ 14 15 ({ \ 15 - uint32_t fieldval = (value) << field##_SHIFT; \ 16 - WARN_ON((fieldval & ~field##_MASK) != 0); \ 17 - fieldval & field##_MASK; \ 16 + WARN_ON(!FIELD_FIT(field##_MASK, value)); \ 17 + FIELD_PREP(field##_MASK, value); \ 18 18 }) 19 19 20 - #define VC4_GET_FIELD(word, field) (((word) & field##_MASK) >> \ 21 - field##_SHIFT) 20 + #define VC4_GET_FIELD(word, field) FIELD_GET(field##_MASK, word) 22 21 23 22 #define V3D_IDENT0 0x00000 24 23 # define V3D_EXPECTED_IDENT0 \
+107 -2
drivers/gpu/drm/vc4/vc4_txp.c
··· 19 19 #include <drm/drm_fourcc.h> 20 20 #include <drm/drm_panel.h> 21 21 #include <drm/drm_probe_helper.h> 22 + #include <drm/drm_vblank.h> 22 23 #include <drm/drm_writeback.h> 23 24 24 25 #include "vc4_drv.h" ··· 146 145 #define TXP_WRITE(offset, val) writel(val, txp->regs + (offset)) 147 146 148 147 struct vc4_txp { 148 + struct vc4_crtc base; 149 + 149 150 struct platform_device *pdev; 150 151 151 152 struct drm_writeback_connector connector; ··· 225 222 TXP_FORMAT_BGRA8888, 226 223 }; 227 224 225 + static void vc4_txp_armed(struct drm_crtc_state *state) 226 + { 227 + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); 228 + 229 + vc4_state->txp_armed = true; 230 + } 231 + 228 232 static int vc4_txp_connector_atomic_check(struct drm_connector *conn, 229 233 struct drm_atomic_state *state) 230 234 { ··· 266 256 if (fb->pitches[0] & GENMASK(3, 0)) 267 257 return -EINVAL; 268 258 269 - vc4_crtc_txp_armed(crtc_state); 259 + vc4_txp_armed(crtc_state); 270 260 271 261 return 0; 272 262 } ··· 365 355 .disable = vc4_txp_encoder_disable, 366 356 }; 367 357 358 + static int vc4_txp_enable_vblank(struct drm_crtc *crtc) 359 + { 360 + return 0; 361 + } 362 + 363 + static void vc4_txp_disable_vblank(struct drm_crtc *crtc) {} 364 + 365 + static const struct drm_crtc_funcs vc4_txp_crtc_funcs = { 366 + .set_config = drm_atomic_helper_set_config, 367 + .destroy = vc4_crtc_destroy, 368 + .page_flip = vc4_page_flip, 369 + .reset = vc4_crtc_reset, 370 + .atomic_duplicate_state = vc4_crtc_duplicate_state, 371 + .atomic_destroy_state = vc4_crtc_destroy_state, 372 + .gamma_set = drm_atomic_helper_legacy_gamma_set, 373 + .enable_vblank = vc4_txp_enable_vblank, 374 + .disable_vblank = vc4_txp_disable_vblank, 375 + }; 376 + 377 + static int vc4_txp_atomic_check(struct drm_crtc *crtc, 378 + struct drm_crtc_state *state) 379 + { 380 + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); 381 + int ret; 382 + 383 + ret = vc4_hvs_atomic_check(crtc, state); 384 + if (ret) 385 + return ret; 386 + 387 + state->no_vblank = true; 388 + vc4_state->feed_txp = true; 389 + 390 + return 0; 391 + } 392 + 393 + static void vc4_txp_atomic_enable(struct drm_crtc *crtc, 394 + struct drm_crtc_state *old_state) 395 + { 396 + drm_crtc_vblank_on(crtc); 397 + vc4_hvs_atomic_enable(crtc, old_state); 398 + } 399 + 400 + static void vc4_txp_atomic_disable(struct drm_crtc *crtc, 401 + struct drm_crtc_state *old_state) 402 + { 403 + struct drm_device *dev = crtc->dev; 404 + 405 + /* Disable vblank irq handling before crtc is disabled. */ 406 + drm_crtc_vblank_off(crtc); 407 + 408 + vc4_hvs_atomic_disable(crtc, old_state); 409 + 410 + /* 411 + * Make sure we issue a vblank event after disabling the CRTC if 412 + * someone was waiting it. 413 + */ 414 + if (crtc->state->event) { 415 + unsigned long flags; 416 + 417 + spin_lock_irqsave(&dev->event_lock, flags); 418 + drm_crtc_send_vblank_event(crtc, crtc->state->event); 419 + crtc->state->event = NULL; 420 + spin_unlock_irqrestore(&dev->event_lock, flags); 421 + } 422 + } 423 + 424 + static const struct drm_crtc_helper_funcs vc4_txp_crtc_helper_funcs = { 425 + .atomic_check = vc4_txp_atomic_check, 426 + .atomic_flush = vc4_hvs_atomic_flush, 427 + .atomic_enable = vc4_txp_atomic_enable, 428 + .atomic_disable = vc4_txp_atomic_disable, 429 + .mode_set_nofb = vc4_hvs_mode_set_nofb, 430 + }; 431 + 368 432 static irqreturn_t vc4_txp_interrupt(int irq, void *data) 369 433 { 370 434 struct vc4_txp *txp = data; 435 + struct vc4_crtc *vc4_crtc = &txp->base; 371 436 372 437 TXP_WRITE(TXP_DST_CTRL, TXP_READ(TXP_DST_CTRL) & ~TXP_EI); 373 - vc4_crtc_handle_vblank(to_vc4_crtc(txp->connector.base.state->crtc)); 438 + vc4_crtc_handle_vblank(vc4_crtc); 374 439 drm_writeback_signal_completion(&txp->connector, 0); 375 440 376 441 return IRQ_HANDLED; 377 442 } 443 + 444 + static const struct vc4_crtc_data vc4_txp_crtc_data = { 445 + .hvs_channel = 2, 446 + }; 378 447 379 448 static int vc4_txp_bind(struct device *dev, struct device *master, void *data) 380 449 { 381 450 struct platform_device *pdev = to_platform_device(dev); 382 451 struct drm_device *drm = dev_get_drvdata(master); 383 452 struct vc4_dev *vc4 = to_vc4_dev(drm); 453 + struct vc4_crtc *vc4_crtc; 384 454 struct vc4_txp *txp; 455 + struct drm_crtc *crtc; 456 + struct drm_encoder *encoder; 385 457 int ret, irq; 386 458 387 459 irq = platform_get_irq(pdev, 0); ··· 473 381 txp = devm_kzalloc(dev, sizeof(*txp), GFP_KERNEL); 474 382 if (!txp) 475 383 return -ENOMEM; 384 + vc4_crtc = &txp->base; 385 + crtc = &vc4_crtc->base; 386 + 387 + vc4_crtc->pdev = pdev; 388 + vc4_crtc->data = &vc4_txp_crtc_data; 476 389 477 390 txp->pdev = pdev; 478 391 ··· 496 399 drm_fmts, ARRAY_SIZE(drm_fmts)); 497 400 if (ret) 498 401 return ret; 402 + 403 + ret = vc4_crtc_init(drm, vc4_crtc, 404 + &vc4_txp_crtc_funcs, &vc4_txp_crtc_helper_funcs); 405 + if (ret) 406 + return ret; 407 + 408 + encoder = &txp->connector.encoder; 409 + encoder->possible_crtcs |= drm_crtc_mask(crtc); 499 410 500 411 ret = devm_request_irq(dev, irq, vc4_txp_interrupt, 0, 501 412 dev_name(dev), txp);
-27
drivers/gpu/drm/vgem/vgem_drv.c
··· 230 230 return 0; 231 231 } 232 232 233 - static int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev, 234 - uint32_t handle, uint64_t *offset) 235 - { 236 - struct drm_gem_object *obj; 237 - int ret; 238 - 239 - obj = drm_gem_object_lookup(file, handle); 240 - if (!obj) 241 - return -ENOENT; 242 - 243 - if (!obj->filp) { 244 - ret = -EINVAL; 245 - goto unref; 246 - } 247 - 248 - ret = drm_gem_create_mmap_offset(obj); 249 - if (ret) 250 - goto unref; 251 - 252 - *offset = drm_vma_node_offset_addr(&obj->vma_node); 253 - unref: 254 - drm_gem_object_put(obj); 255 - 256 - return ret; 257 - } 258 - 259 233 static struct drm_ioctl_desc vgem_ioctls[] = { 260 234 DRM_IOCTL_DEF_DRV(VGEM_FENCE_ATTACH, vgem_fence_attach_ioctl, DRM_RENDER_ALLOW), 261 235 DRM_IOCTL_DEF_DRV(VGEM_FENCE_SIGNAL, vgem_fence_signal_ioctl, DRM_RENDER_ALLOW), ··· 420 446 .fops = &vgem_driver_fops, 421 447 422 448 .dumb_create = vgem_gem_dumb_create, 423 - .dumb_map_offset = vgem_gem_dumb_map, 424 449 425 450 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 426 451 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
-20
drivers/gpu/drm/virtio/virtgpu_display.c
··· 314 314 return &virtio_gpu_fb->base; 315 315 } 316 316 317 - static void vgdev_atomic_commit_tail(struct drm_atomic_state *state) 318 - { 319 - struct drm_device *dev = state->dev; 320 - 321 - drm_atomic_helper_commit_modeset_disables(dev, state); 322 - drm_atomic_helper_commit_modeset_enables(dev, state); 323 - drm_atomic_helper_commit_planes(dev, state, 0); 324 - 325 - drm_atomic_helper_fake_vblank(state); 326 - drm_atomic_helper_commit_hw_done(state); 327 - 328 - drm_atomic_helper_wait_for_vblanks(dev, state); 329 - drm_atomic_helper_cleanup_planes(dev, state); 330 - } 331 - 332 - static const struct drm_mode_config_helper_funcs virtio_mode_config_helpers = { 333 - .atomic_commit_tail = vgdev_atomic_commit_tail, 334 - }; 335 - 336 317 static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = { 337 318 .fb_create = virtio_gpu_user_framebuffer_create, 338 319 .atomic_check = drm_atomic_helper_check, ··· 327 346 drm_mode_config_init(vgdev->ddev); 328 347 vgdev->ddev->mode_config.quirk_addfb_prefer_host_byte_order = true; 329 348 vgdev->ddev->mode_config.funcs = &virtio_gpu_mode_funcs; 330 - vgdev->ddev->mode_config.helper_private = &virtio_mode_config_helpers; 331 349 332 350 /* modes will be validated against the framebuffer size */ 333 351 vgdev->ddev->mode_config.min_width = XRES_MIN;
+2
drivers/gpu/drm/vkms/vkms_drv.c
··· 133 133 dev->mode_config.min_height = YRES_MIN; 134 134 dev->mode_config.max_width = XRES_MAX; 135 135 dev->mode_config.max_height = YRES_MAX; 136 + dev->mode_config.cursor_width = 512; 137 + dev->mode_config.cursor_height = 512; 136 138 dev->mode_config.preferred_depth = 24; 137 139 dev->mode_config.helper_private = &vkms_mode_config_helpers; 138 140
+2 -2
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
··· 258 258 ret = ttm_bo_validate(bo, &placement, &ctx); 259 259 260 260 /* For some reason we didn't end up at the start of vram */ 261 - WARN_ON(ret == 0 && bo->offset != 0); 261 + WARN_ON(ret == 0 && bo->mem.start != 0); 262 262 if (!ret) 263 263 vmw_bo_pin_reserved(buf, true); 264 264 ··· 317 317 { 318 318 if (bo->mem.mem_type == TTM_PL_VRAM) { 319 319 ptr->gmrId = SVGA_GMR_FRAMEBUFFER; 320 - ptr->offset = bo->offset; 320 + ptr->offset = bo->mem.start << PAGE_SHIFT; 321 321 } else { 322 322 ptr->gmrId = bo->mem.start; 323 323 ptr->offset = 0;
+1 -1
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
··· 3696 3696 bo = &reloc->vbo->base; 3697 3697 switch (bo->mem.mem_type) { 3698 3698 case TTM_PL_VRAM: 3699 - reloc->location->offset += bo->offset; 3699 + reloc->location->offset += bo->mem.start << PAGE_SHIFT; 3700 3700 reloc->location->gmrId = SVGA_GMR_FRAMEBUFFER; 3701 3701 break; 3702 3702 case VMW_PL_GMR:
+1 -1
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
··· 610 610 611 611 if (bo->mem.mem_type == TTM_PL_VRAM) { 612 612 cmd->body.guestResult.gmrId = SVGA_GMR_FRAMEBUFFER; 613 - cmd->body.guestResult.offset = bo->offset; 613 + cmd->body.guestResult.offset = bo->mem.start << PAGE_SHIFT; 614 614 } else { 615 615 cmd->body.guestResult.gmrId = bo->mem.start; 616 616 cmd->body.guestResult.offset = 0;
+1 -3
drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
··· 53 53 (struct vmwgfx_gmrid_man *)man->priv; 54 54 int id; 55 55 56 - mem->mm_node = NULL; 57 - 58 56 id = ida_alloc_max(&gman->gmr_ida, gman->max_gmr_ids - 1, GFP_KERNEL); 59 57 if (id < 0) 60 58 return (id != -ENOMEM ? 0 : id); ··· 76 78 gman->used_gmr_pages -= bo->num_pages; 77 79 spin_unlock(&gman->lock); 78 80 ida_free(&gman->gmr_ida, id); 79 - return 0; 81 + return -ENOSPC; 80 82 } 81 83 82 84 static void vmw_gmrid_man_put_node(struct ttm_mem_type_manager *man,
+1 -2
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
··· 629 629 return; 630 630 } 631 631 632 - crtc->state = &vcs->base; 633 - crtc->state->crtc = crtc; 632 + __drm_atomic_helper_crtc_reset(crtc, &vcs->base); 634 633 } 635 634 636 635
-2
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
··· 750 750 case TTM_PL_VRAM: 751 751 /* "On-card" video ram */ 752 752 man->func = &vmw_thp_func; 753 - man->gpu_offset = 0; 754 753 man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE; 755 754 man->available_caching = TTM_PL_FLAG_CACHED; 756 755 man->default_caching = TTM_PL_FLAG_CACHED; ··· 762 763 * slots as well as the bo size. 763 764 */ 764 765 man->func = &vmw_gmrid_manager_func; 765 - man->gpu_offset = 0; 766 766 man->flags = TTM_MEMTYPE_FLAG_CMA | TTM_MEMTYPE_FLAG_MAPPABLE; 767 767 man->available_caching = TTM_PL_FLAG_CACHED; 768 768 man->default_caching = TTM_PL_FLAG_CACHED;
+3 -3
drivers/gpu/drm/zte/zx_vga.c
··· 155 155 if (ret) { 156 156 DRM_DEV_ERROR(dev, "failed to init encoder: %d\n", ret); 157 157 return ret; 158 - }; 158 + } 159 159 160 160 drm_encoder_helper_add(encoder, &zx_vga_encoder_helper_funcs); 161 161 ··· 168 168 if (ret) { 169 169 DRM_DEV_ERROR(dev, "failed to init connector: %d\n", ret); 170 170 goto clean_encoder; 171 - }; 171 + } 172 172 173 173 drm_connector_helper_add(connector, &zx_vga_connector_helper_funcs); 174 174 ··· 176 176 if (ret) { 177 177 DRM_DEV_ERROR(dev, "failed to attach encoder: %d\n", ret); 178 178 goto clean_connector; 179 - }; 179 + } 180 180 181 181 return 0; 182 182
+23
drivers/of/property.c
··· 30 30 #include "of_private.h" 31 31 32 32 /** 33 + * of_graph_is_present() - check graph's presence 34 + * @node: pointer to device_node containing graph port 35 + * 36 + * Return: True if @node has a port or ports (with a port) sub-node, 37 + * false otherwise. 38 + */ 39 + bool of_graph_is_present(const struct device_node *node) 40 + { 41 + struct device_node *ports, *port; 42 + 43 + ports = of_get_child_by_name(node, "ports"); 44 + if (ports) 45 + node = ports; 46 + 47 + port = of_get_child_by_name(node, "port"); 48 + of_node_put(ports); 49 + of_node_put(port); 50 + 51 + return !!port; 52 + } 53 + EXPORT_SYMBOL(of_graph_is_present); 54 + 55 + /** 33 56 * of_property_count_elems_of_size - Count the number of elements in a property 34 57 * 35 58 * @np: device node from which the property value is to be read.
-20
drivers/video/fbdev/Kconfig
··· 272 272 help 273 273 Support the Permedia2 FIFO disconnect feature. 274 274 275 - config FB_ARMCLCD 276 - tristate "ARM PrimeCell PL110 support" 277 - depends on ARM || ARM64 || COMPILE_TEST 278 - depends on FB && ARM_AMBA && HAS_IOMEM 279 - select FB_CFB_FILLRECT 280 - select FB_CFB_COPYAREA 281 - select FB_CFB_IMAGEBLIT 282 - select FB_MODE_HELPERS if OF 283 - select VIDEOMODE_HELPERS if OF 284 - select BACKLIGHT_CLASS_DEVICE if OF 285 - help 286 - This framebuffer device driver is for the ARM PrimeCell PL110 287 - Colour LCD controller. ARM PrimeCells provide the building 288 - blocks for System on a Chip devices. 289 - 290 - If you want to compile this as a module (=code which can be 291 - inserted into and removed from the running kernel), say M 292 - here and read <file:Documentation/kbuild/modules.rst>. The module 293 - will be called amba-clcd. 294 - 295 275 config FB_ACORN 296 276 bool "Acorn VIDC support" 297 277 depends on (FB = y) && ARM && ARCH_ACORN
-1
drivers/video/fbdev/Makefile
··· 75 75 obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o 76 76 obj-$(CONFIG_FB_PVR2) += pvr2fb.o 77 77 obj-$(CONFIG_FB_VOODOO1) += sstfb.o 78 - obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o 79 78 obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o 80 79 obj-$(CONFIG_FB_68328) += 68328fb.o 81 80 obj-$(CONFIG_FB_GBE) += gbefb.o
-986
drivers/video/fbdev/amba-clcd.c
··· 1 - /* 2 - * linux/drivers/video/amba-clcd.c 3 - * 4 - * Copyright (C) 2001 ARM Limited, by David A Rusling 5 - * Updated to 2.5, Deep Blue Solutions Ltd. 6 - * 7 - * This file is subject to the terms and conditions of the GNU General Public 8 - * License. See the file COPYING in the main directory of this archive 9 - * for more details. 10 - * 11 - * ARM PrimeCell PL110 Color LCD Controller 12 - */ 13 - #include <linux/amba/bus.h> 14 - #include <linux/amba/clcd.h> 15 - #include <linux/backlight.h> 16 - #include <linux/clk.h> 17 - #include <linux/delay.h> 18 - #include <linux/dma-mapping.h> 19 - #include <linux/fb.h> 20 - #include <linux/init.h> 21 - #include <linux/ioport.h> 22 - #include <linux/list.h> 23 - #include <linux/mm.h> 24 - #include <linux/module.h> 25 - #include <linux/of_address.h> 26 - #include <linux/of_graph.h> 27 - #include <linux/slab.h> 28 - #include <linux/string.h> 29 - #include <video/display_timing.h> 30 - #include <video/of_display_timing.h> 31 - #include <video/videomode.h> 32 - 33 - #define to_clcd(info) container_of(info, struct clcd_fb, fb) 34 - 35 - /* This is limited to 16 characters when displayed by X startup */ 36 - static const char *clcd_name = "CLCD FB"; 37 - 38 - /* 39 - * Unfortunately, the enable/disable functions may be called either from 40 - * process or IRQ context, and we _need_ to delay. This is _not_ good. 41 - */ 42 - static inline void clcdfb_sleep(unsigned int ms) 43 - { 44 - if (in_atomic()) { 45 - mdelay(ms); 46 - } else { 47 - msleep(ms); 48 - } 49 - } 50 - 51 - static inline void clcdfb_set_start(struct clcd_fb *fb) 52 - { 53 - unsigned long ustart = fb->fb.fix.smem_start; 54 - unsigned long lstart; 55 - 56 - ustart += fb->fb.var.yoffset * fb->fb.fix.line_length; 57 - lstart = ustart + fb->fb.var.yres * fb->fb.fix.line_length / 2; 58 - 59 - writel(ustart, fb->regs + CLCD_UBAS); 60 - writel(lstart, fb->regs + CLCD_LBAS); 61 - } 62 - 63 - static void clcdfb_disable(struct clcd_fb *fb) 64 - { 65 - u32 val; 66 - 67 - if (fb->board->disable) 68 - fb->board->disable(fb); 69 - 70 - if (fb->panel->backlight) { 71 - fb->panel->backlight->props.power = FB_BLANK_POWERDOWN; 72 - backlight_update_status(fb->panel->backlight); 73 - } 74 - 75 - val = readl(fb->regs + fb->off_cntl); 76 - if (val & CNTL_LCDPWR) { 77 - val &= ~CNTL_LCDPWR; 78 - writel(val, fb->regs + fb->off_cntl); 79 - 80 - clcdfb_sleep(20); 81 - } 82 - if (val & CNTL_LCDEN) { 83 - val &= ~CNTL_LCDEN; 84 - writel(val, fb->regs + fb->off_cntl); 85 - } 86 - 87 - /* 88 - * Disable CLCD clock source. 89 - */ 90 - if (fb->clk_enabled) { 91 - fb->clk_enabled = false; 92 - clk_disable(fb->clk); 93 - } 94 - } 95 - 96 - static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) 97 - { 98 - /* 99 - * Enable the CLCD clock source. 100 - */ 101 - if (!fb->clk_enabled) { 102 - fb->clk_enabled = true; 103 - clk_enable(fb->clk); 104 - } 105 - 106 - /* 107 - * Bring up by first enabling.. 108 - */ 109 - cntl |= CNTL_LCDEN; 110 - writel(cntl, fb->regs + fb->off_cntl); 111 - 112 - clcdfb_sleep(20); 113 - 114 - /* 115 - * and now apply power. 116 - */ 117 - cntl |= CNTL_LCDPWR; 118 - writel(cntl, fb->regs + fb->off_cntl); 119 - 120 - /* 121 - * Turn on backlight 122 - */ 123 - if (fb->panel->backlight) { 124 - fb->panel->backlight->props.power = FB_BLANK_UNBLANK; 125 - backlight_update_status(fb->panel->backlight); 126 - } 127 - 128 - /* 129 - * finally, enable the interface. 130 - */ 131 - if (fb->board->enable) 132 - fb->board->enable(fb); 133 - } 134 - 135 - static int 136 - clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) 137 - { 138 - u32 caps; 139 - int ret = 0; 140 - 141 - if (fb->panel->caps && fb->board->caps) 142 - caps = fb->panel->caps & fb->board->caps; 143 - else { 144 - /* Old way of specifying what can be used */ 145 - caps = fb->panel->cntl & CNTL_BGR ? 146 - CLCD_CAP_BGR : CLCD_CAP_RGB; 147 - /* But mask out 444 modes as they weren't supported */ 148 - caps &= ~CLCD_CAP_444; 149 - } 150 - 151 - /* Only TFT panels can do RGB888/BGR888 */ 152 - if (!(fb->panel->cntl & CNTL_LCDTFT)) 153 - caps &= ~CLCD_CAP_888; 154 - 155 - memset(&var->transp, 0, sizeof(var->transp)); 156 - 157 - var->red.msb_right = 0; 158 - var->green.msb_right = 0; 159 - var->blue.msb_right = 0; 160 - 161 - switch (var->bits_per_pixel) { 162 - case 1: 163 - case 2: 164 - case 4: 165 - case 8: 166 - /* If we can't do 5551, reject */ 167 - caps &= CLCD_CAP_5551; 168 - if (!caps) { 169 - ret = -EINVAL; 170 - break; 171 - } 172 - 173 - var->red.length = var->bits_per_pixel; 174 - var->red.offset = 0; 175 - var->green.length = var->bits_per_pixel; 176 - var->green.offset = 0; 177 - var->blue.length = var->bits_per_pixel; 178 - var->blue.offset = 0; 179 - break; 180 - 181 - case 16: 182 - /* If we can't do 444, 5551 or 565, reject */ 183 - if (!(caps & (CLCD_CAP_444 | CLCD_CAP_5551 | CLCD_CAP_565))) { 184 - ret = -EINVAL; 185 - break; 186 - } 187 - 188 - /* 189 - * Green length can be 4, 5 or 6 depending whether 190 - * we're operating in 444, 5551 or 565 mode. 191 - */ 192 - if (var->green.length == 4 && caps & CLCD_CAP_444) 193 - caps &= CLCD_CAP_444; 194 - if (var->green.length == 5 && caps & CLCD_CAP_5551) 195 - caps &= CLCD_CAP_5551; 196 - else if (var->green.length == 6 && caps & CLCD_CAP_565) 197 - caps &= CLCD_CAP_565; 198 - else { 199 - /* 200 - * PL110 officially only supports RGB555, 201 - * but may be wired up to allow RGB565. 202 - */ 203 - if (caps & CLCD_CAP_565) { 204 - var->green.length = 6; 205 - caps &= CLCD_CAP_565; 206 - } else if (caps & CLCD_CAP_5551) { 207 - var->green.length = 5; 208 - caps &= CLCD_CAP_5551; 209 - } else { 210 - var->green.length = 4; 211 - caps &= CLCD_CAP_444; 212 - } 213 - } 214 - 215 - if (var->green.length >= 5) { 216 - var->red.length = 5; 217 - var->blue.length = 5; 218 - } else { 219 - var->red.length = 4; 220 - var->blue.length = 4; 221 - } 222 - break; 223 - case 32: 224 - /* If we can't do 888, reject */ 225 - caps &= CLCD_CAP_888; 226 - if (!caps) { 227 - ret = -EINVAL; 228 - break; 229 - } 230 - 231 - var->red.length = 8; 232 - var->green.length = 8; 233 - var->blue.length = 8; 234 - break; 235 - default: 236 - ret = -EINVAL; 237 - break; 238 - } 239 - 240 - /* 241 - * >= 16bpp displays have separate colour component bitfields 242 - * encoded in the pixel data. Calculate their position from 243 - * the bitfield length defined above. 244 - */ 245 - if (ret == 0 && var->bits_per_pixel >= 16) { 246 - bool bgr, rgb; 247 - 248 - bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0; 249 - rgb = caps & CLCD_CAP_RGB && var->red.offset == 0; 250 - 251 - if (!bgr && !rgb) 252 - /* 253 - * The requested format was not possible, try just 254 - * our capabilities. One of BGR or RGB must be 255 - * supported. 256 - */ 257 - bgr = caps & CLCD_CAP_BGR; 258 - 259 - if (bgr) { 260 - var->blue.offset = 0; 261 - var->green.offset = var->blue.offset + var->blue.length; 262 - var->red.offset = var->green.offset + var->green.length; 263 - } else { 264 - var->red.offset = 0; 265 - var->green.offset = var->red.offset + var->red.length; 266 - var->blue.offset = var->green.offset + var->green.length; 267 - } 268 - } 269 - 270 - return ret; 271 - } 272 - 273 - static int clcdfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 274 - { 275 - struct clcd_fb *fb = to_clcd(info); 276 - int ret = -EINVAL; 277 - 278 - if (fb->board->check) 279 - ret = fb->board->check(fb, var); 280 - 281 - if (ret == 0 && 282 - var->xres_virtual * var->bits_per_pixel / 8 * 283 - var->yres_virtual > fb->fb.fix.smem_len) 284 - ret = -EINVAL; 285 - 286 - if (ret == 0) 287 - ret = clcdfb_set_bitfields(fb, var); 288 - 289 - return ret; 290 - } 291 - 292 - static int clcdfb_set_par(struct fb_info *info) 293 - { 294 - struct clcd_fb *fb = to_clcd(info); 295 - struct clcd_regs regs; 296 - 297 - fb->fb.fix.line_length = fb->fb.var.xres_virtual * 298 - fb->fb.var.bits_per_pixel / 8; 299 - 300 - if (fb->fb.var.bits_per_pixel <= 8) 301 - fb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; 302 - else 303 - fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; 304 - 305 - fb->board->decode(fb, &regs); 306 - 307 - clcdfb_disable(fb); 308 - 309 - writel(regs.tim0, fb->regs + CLCD_TIM0); 310 - writel(regs.tim1, fb->regs + CLCD_TIM1); 311 - writel(regs.tim2, fb->regs + CLCD_TIM2); 312 - writel(regs.tim3, fb->regs + CLCD_TIM3); 313 - 314 - clcdfb_set_start(fb); 315 - 316 - clk_set_rate(fb->clk, (1000000000 / regs.pixclock) * 1000); 317 - 318 - fb->clcd_cntl = regs.cntl; 319 - 320 - clcdfb_enable(fb, regs.cntl); 321 - 322 - #ifdef DEBUG 323 - printk(KERN_INFO 324 - "CLCD: Registers set to\n" 325 - " %08x %08x %08x %08x\n" 326 - " %08x %08x %08x %08x\n", 327 - readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1), 328 - readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3), 329 - readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS), 330 - readl(fb->regs + fb->off_ienb), readl(fb->regs + fb->off_cntl)); 331 - #endif 332 - 333 - return 0; 334 - } 335 - 336 - static inline u32 convert_bitfield(int val, struct fb_bitfield *bf) 337 - { 338 - unsigned int mask = (1 << bf->length) - 1; 339 - 340 - return (val >> (16 - bf->length) & mask) << bf->offset; 341 - } 342 - 343 - /* 344 - * Set a single color register. The values supplied have a 16 bit 345 - * magnitude. Return != 0 for invalid regno. 346 - */ 347 - static int 348 - clcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, 349 - unsigned int blue, unsigned int transp, struct fb_info *info) 350 - { 351 - struct clcd_fb *fb = to_clcd(info); 352 - 353 - if (regno < 16) 354 - fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) | 355 - convert_bitfield(blue, &fb->fb.var.blue) | 356 - convert_bitfield(green, &fb->fb.var.green) | 357 - convert_bitfield(red, &fb->fb.var.red); 358 - 359 - if (fb->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) { 360 - int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3); 361 - u32 val, mask, newval; 362 - 363 - newval = (red >> 11) & 0x001f; 364 - newval |= (green >> 6) & 0x03e0; 365 - newval |= (blue >> 1) & 0x7c00; 366 - 367 - /* 368 - * 3.2.11: if we're configured for big endian 369 - * byte order, the palette entries are swapped. 370 - */ 371 - if (fb->clcd_cntl & CNTL_BEBO) 372 - regno ^= 1; 373 - 374 - if (regno & 1) { 375 - newval <<= 16; 376 - mask = 0x0000ffff; 377 - } else { 378 - mask = 0xffff0000; 379 - } 380 - 381 - val = readl(fb->regs + hw_reg) & mask; 382 - writel(val | newval, fb->regs + hw_reg); 383 - } 384 - 385 - return regno > 255; 386 - } 387 - 388 - /* 389 - * Blank the screen if blank_mode != 0, else unblank. If blank == NULL 390 - * then the caller blanks by setting the CLUT (Color Look Up Table) to all 391 - * black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due 392 - * to e.g. a video mode which doesn't support it. Implements VESA suspend 393 - * and powerdown modes on hardware that supports disabling hsync/vsync: 394 - * blank_mode == 2: suspend vsync 395 - * blank_mode == 3: suspend hsync 396 - * blank_mode == 4: powerdown 397 - */ 398 - static int clcdfb_blank(int blank_mode, struct fb_info *info) 399 - { 400 - struct clcd_fb *fb = to_clcd(info); 401 - 402 - if (blank_mode != 0) { 403 - clcdfb_disable(fb); 404 - } else { 405 - clcdfb_enable(fb, fb->clcd_cntl); 406 - } 407 - return 0; 408 - } 409 - 410 - static int clcdfb_mmap(struct fb_info *info, 411 - struct vm_area_struct *vma) 412 - { 413 - struct clcd_fb *fb = to_clcd(info); 414 - unsigned long len, off = vma->vm_pgoff << PAGE_SHIFT; 415 - int ret = -EINVAL; 416 - 417 - len = info->fix.smem_len; 418 - 419 - if (off <= len && vma->vm_end - vma->vm_start <= len - off && 420 - fb->board->mmap) 421 - ret = fb->board->mmap(fb, vma); 422 - 423 - return ret; 424 - } 425 - 426 - static const struct fb_ops clcdfb_ops = { 427 - .owner = THIS_MODULE, 428 - .fb_check_var = clcdfb_check_var, 429 - .fb_set_par = clcdfb_set_par, 430 - .fb_setcolreg = clcdfb_setcolreg, 431 - .fb_blank = clcdfb_blank, 432 - .fb_fillrect = cfb_fillrect, 433 - .fb_copyarea = cfb_copyarea, 434 - .fb_imageblit = cfb_imageblit, 435 - .fb_mmap = clcdfb_mmap, 436 - }; 437 - 438 - static int clcdfb_register(struct clcd_fb *fb) 439 - { 440 - int ret; 441 - 442 - /* 443 - * ARM PL111 always has IENB at 0x1c; it's only PL110 444 - * which is reversed on some platforms. 445 - */ 446 - if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) { 447 - fb->off_ienb = CLCD_PL111_IENB; 448 - fb->off_cntl = CLCD_PL111_CNTL; 449 - } else { 450 - fb->off_ienb = CLCD_PL110_IENB; 451 - fb->off_cntl = CLCD_PL110_CNTL; 452 - } 453 - 454 - fb->clk = clk_get(&fb->dev->dev, NULL); 455 - if (IS_ERR(fb->clk)) { 456 - ret = PTR_ERR(fb->clk); 457 - goto out; 458 - } 459 - 460 - ret = clk_prepare(fb->clk); 461 - if (ret) 462 - goto free_clk; 463 - 464 - fb->fb.device = &fb->dev->dev; 465 - 466 - fb->fb.fix.mmio_start = fb->dev->res.start; 467 - fb->fb.fix.mmio_len = resource_size(&fb->dev->res); 468 - 469 - fb->regs = ioremap(fb->fb.fix.mmio_start, fb->fb.fix.mmio_len); 470 - if (!fb->regs) { 471 - printk(KERN_ERR "CLCD: unable to remap registers\n"); 472 - ret = -ENOMEM; 473 - goto clk_unprep; 474 - } 475 - 476 - fb->fb.fbops = &clcdfb_ops; 477 - fb->fb.flags = FBINFO_FLAG_DEFAULT; 478 - fb->fb.pseudo_palette = fb->cmap; 479 - 480 - strncpy(fb->fb.fix.id, clcd_name, sizeof(fb->fb.fix.id)); 481 - fb->fb.fix.type = FB_TYPE_PACKED_PIXELS; 482 - fb->fb.fix.type_aux = 0; 483 - fb->fb.fix.xpanstep = 0; 484 - fb->fb.fix.ypanstep = 0; 485 - fb->fb.fix.ywrapstep = 0; 486 - fb->fb.fix.accel = FB_ACCEL_NONE; 487 - 488 - fb->fb.var.xres = fb->panel->mode.xres; 489 - fb->fb.var.yres = fb->panel->mode.yres; 490 - fb->fb.var.xres_virtual = fb->panel->mode.xres; 491 - fb->fb.var.yres_virtual = fb->panel->mode.yres; 492 - fb->fb.var.bits_per_pixel = fb->panel->bpp; 493 - fb->fb.var.grayscale = fb->panel->grayscale; 494 - fb->fb.var.pixclock = fb->panel->mode.pixclock; 495 - fb->fb.var.left_margin = fb->panel->mode.left_margin; 496 - fb->fb.var.right_margin = fb->panel->mode.right_margin; 497 - fb->fb.var.upper_margin = fb->panel->mode.upper_margin; 498 - fb->fb.var.lower_margin = fb->panel->mode.lower_margin; 499 - fb->fb.var.hsync_len = fb->panel->mode.hsync_len; 500 - fb->fb.var.vsync_len = fb->panel->mode.vsync_len; 501 - fb->fb.var.sync = fb->panel->mode.sync; 502 - fb->fb.var.vmode = fb->panel->mode.vmode; 503 - fb->fb.var.activate = FB_ACTIVATE_NOW; 504 - fb->fb.var.nonstd = 0; 505 - fb->fb.var.height = fb->panel->height; 506 - fb->fb.var.width = fb->panel->width; 507 - fb->fb.var.accel_flags = 0; 508 - 509 - fb->fb.monspecs.hfmin = 0; 510 - fb->fb.monspecs.hfmax = 100000; 511 - fb->fb.monspecs.vfmin = 0; 512 - fb->fb.monspecs.vfmax = 400; 513 - fb->fb.monspecs.dclkmin = 1000000; 514 - fb->fb.monspecs.dclkmax = 100000000; 515 - 516 - /* 517 - * Make sure that the bitfields are set appropriately. 518 - */ 519 - clcdfb_set_bitfields(fb, &fb->fb.var); 520 - 521 - /* 522 - * Allocate colourmap. 523 - */ 524 - ret = fb_alloc_cmap(&fb->fb.cmap, 256, 0); 525 - if (ret) 526 - goto unmap; 527 - 528 - /* 529 - * Ensure interrupts are disabled. 530 - */ 531 - writel(0, fb->regs + fb->off_ienb); 532 - 533 - fb_set_var(&fb->fb, &fb->fb.var); 534 - 535 - dev_info(&fb->dev->dev, "%s hardware, %s display\n", 536 - fb->board->name, fb->panel->mode.name); 537 - 538 - ret = register_framebuffer(&fb->fb); 539 - if (ret == 0) 540 - goto out; 541 - 542 - printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret); 543 - 544 - fb_dealloc_cmap(&fb->fb.cmap); 545 - unmap: 546 - iounmap(fb->regs); 547 - clk_unprep: 548 - clk_unprepare(fb->clk); 549 - free_clk: 550 - clk_put(fb->clk); 551 - out: 552 - return ret; 553 - } 554 - 555 - #ifdef CONFIG_OF 556 - static int clcdfb_of_get_dpi_panel_mode(struct device_node *node, 557 - struct clcd_panel *clcd_panel) 558 - { 559 - int err; 560 - struct display_timing timing; 561 - struct videomode video; 562 - 563 - err = of_get_display_timing(node, "panel-timing", &timing); 564 - if (err) { 565 - pr_err("%pOF: problems parsing panel-timing (%d)\n", node, err); 566 - return err; 567 - } 568 - 569 - videomode_from_timing(&timing, &video); 570 - 571 - err = fb_videomode_from_videomode(&video, &clcd_panel->mode); 572 - if (err) 573 - return err; 574 - 575 - /* Set up some inversion flags */ 576 - if (timing.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) 577 - clcd_panel->tim2 |= TIM2_IPC; 578 - else if (!(timing.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)) 579 - /* 580 - * To preserve backwards compatibility, the IPC (inverted 581 - * pixel clock) flag needs to be set on any display that 582 - * doesn't explicitly specify that the pixel clock is 583 - * active on the negative or positive edge. 584 - */ 585 - clcd_panel->tim2 |= TIM2_IPC; 586 - 587 - if (timing.flags & DISPLAY_FLAGS_HSYNC_LOW) 588 - clcd_panel->tim2 |= TIM2_IHS; 589 - 590 - if (timing.flags & DISPLAY_FLAGS_VSYNC_LOW) 591 - clcd_panel->tim2 |= TIM2_IVS; 592 - 593 - if (timing.flags & DISPLAY_FLAGS_DE_LOW) 594 - clcd_panel->tim2 |= TIM2_IOE; 595 - 596 - return 0; 597 - } 598 - 599 - static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode) 600 - { 601 - return snprintf(buf, size, "%ux%u@%u", mode->xres, mode->yres, 602 - mode->refresh); 603 - } 604 - 605 - static int clcdfb_of_get_backlight(struct device *dev, 606 - struct clcd_panel *clcd_panel) 607 - { 608 - struct backlight_device *backlight; 609 - 610 - /* Look up the optional backlight device */ 611 - backlight = devm_of_find_backlight(dev); 612 - if (IS_ERR(backlight)) 613 - return PTR_ERR(backlight); 614 - 615 - clcd_panel->backlight = backlight; 616 - return 0; 617 - } 618 - 619 - static int clcdfb_of_get_mode(struct device *dev, struct device_node *panel, 620 - struct clcd_panel *clcd_panel) 621 - { 622 - int err; 623 - struct fb_videomode *mode; 624 - char *name; 625 - int len; 626 - 627 - /* Only directly connected DPI panels supported for now */ 628 - if (of_device_is_compatible(panel, "panel-dpi")) 629 - err = clcdfb_of_get_dpi_panel_mode(panel, clcd_panel); 630 - else 631 - err = -ENOENT; 632 - if (err) 633 - return err; 634 - mode = &clcd_panel->mode; 635 - 636 - len = clcdfb_snprintf_mode(NULL, 0, mode); 637 - name = devm_kzalloc(dev, len + 1, GFP_KERNEL); 638 - if (!name) 639 - return -ENOMEM; 640 - 641 - clcdfb_snprintf_mode(name, len + 1, mode); 642 - mode->name = name; 643 - 644 - return 0; 645 - } 646 - 647 - static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0) 648 - { 649 - static struct { 650 - unsigned int part; 651 - u32 r0, g0, b0; 652 - u32 caps; 653 - } panels[] = { 654 - { 0x110, 1, 7, 13, CLCD_CAP_5551 }, 655 - { 0x110, 0, 8, 16, CLCD_CAP_888 }, 656 - { 0x110, 16, 8, 0, CLCD_CAP_888 }, 657 - { 0x111, 4, 14, 20, CLCD_CAP_444 }, 658 - { 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 }, 659 - { 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 | 660 - CLCD_CAP_565 }, 661 - { 0x111, 0, 8, 16, CLCD_CAP_444 | CLCD_CAP_5551 | 662 - CLCD_CAP_565 | CLCD_CAP_888 }, 663 - }; 664 - int i; 665 - 666 - /* Bypass pixel clock divider */ 667 - fb->panel->tim2 |= TIM2_BCD; 668 - 669 - /* TFT display, vert. comp. interrupt at the start of the back porch */ 670 - fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1); 671 - 672 - fb->panel->caps = 0; 673 - 674 - /* Match the setup with known variants */ 675 - for (i = 0; i < ARRAY_SIZE(panels) && !fb->panel->caps; i++) { 676 - if (amba_part(fb->dev) != panels[i].part) 677 - continue; 678 - if (g0 != panels[i].g0) 679 - continue; 680 - if (r0 == panels[i].r0 && b0 == panels[i].b0) 681 - fb->panel->caps = panels[i].caps; 682 - } 683 - 684 - /* 685 - * If we actually physically connected the R lines to B and 686 - * vice versa 687 - */ 688 - if (r0 != 0 && b0 == 0) 689 - fb->panel->bgr_connection = true; 690 - 691 - return fb->panel->caps ? 0 : -EINVAL; 692 - } 693 - 694 - static int clcdfb_of_init_display(struct clcd_fb *fb) 695 - { 696 - struct device_node *endpoint, *panel; 697 - int err; 698 - unsigned int bpp; 699 - u32 max_bandwidth; 700 - u32 tft_r0b0g0[3]; 701 - 702 - fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL); 703 - if (!fb->panel) 704 - return -ENOMEM; 705 - 706 - /* 707 - * Fetch the panel endpoint. 708 - */ 709 - endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL); 710 - if (!endpoint) 711 - return -ENODEV; 712 - 713 - panel = of_graph_get_remote_port_parent(endpoint); 714 - if (!panel) 715 - return -ENODEV; 716 - 717 - err = clcdfb_of_get_backlight(&fb->dev->dev, fb->panel); 718 - if (err) 719 - return err; 720 - 721 - err = clcdfb_of_get_mode(&fb->dev->dev, panel, fb->panel); 722 - if (err) 723 - return err; 724 - 725 - err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth", 726 - &max_bandwidth); 727 - if (!err) { 728 - /* 729 - * max_bandwidth is in bytes per second and pixclock in 730 - * pico-seconds, so the maximum allowed bits per pixel is 731 - * 8 * max_bandwidth / (PICOS2KHZ(pixclock) * 1000) 732 - * Rearrange this calculation to avoid overflow and then ensure 733 - * result is a valid format. 734 - */ 735 - bpp = max_bandwidth / (1000 / 8) 736 - / PICOS2KHZ(fb->panel->mode.pixclock); 737 - bpp = rounddown_pow_of_two(bpp); 738 - if (bpp > 32) 739 - bpp = 32; 740 - } else 741 - bpp = 32; 742 - fb->panel->bpp = bpp; 743 - 744 - #ifdef CONFIG_CPU_BIG_ENDIAN 745 - fb->panel->cntl |= CNTL_BEBO; 746 - #endif 747 - fb->panel->width = -1; 748 - fb->panel->height = -1; 749 - 750 - if (of_property_read_u32_array(endpoint, 751 - "arm,pl11x,tft-r0g0b0-pads", 752 - tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0) 753 - return -ENOENT; 754 - 755 - return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0], 756 - tft_r0b0g0[1], tft_r0b0g0[2]); 757 - } 758 - 759 - static int clcdfb_of_vram_setup(struct clcd_fb *fb) 760 - { 761 - int err; 762 - struct device_node *memory; 763 - u64 size; 764 - 765 - err = clcdfb_of_init_display(fb); 766 - if (err) 767 - return err; 768 - 769 - memory = of_parse_phandle(fb->dev->dev.of_node, "memory-region", 0); 770 - if (!memory) 771 - return -ENODEV; 772 - 773 - fb->fb.screen_base = of_iomap(memory, 0); 774 - if (!fb->fb.screen_base) 775 - return -ENOMEM; 776 - 777 - fb->fb.fix.smem_start = of_translate_address(memory, 778 - of_get_address(memory, 0, &size, NULL)); 779 - fb->fb.fix.smem_len = size; 780 - 781 - return 0; 782 - } 783 - 784 - static int clcdfb_of_vram_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) 785 - { 786 - unsigned long off, user_size, kernel_size; 787 - 788 - 789 - off = vma->vm_pgoff << PAGE_SHIFT; 790 - user_size = vma->vm_end - vma->vm_start; 791 - kernel_size = fb->fb.fix.smem_len; 792 - 793 - if (off >= kernel_size || user_size > (kernel_size - off)) 794 - return -ENXIO; 795 - 796 - return remap_pfn_range(vma, vma->vm_start, 797 - __phys_to_pfn(fb->fb.fix.smem_start) + vma->vm_pgoff, 798 - user_size, 799 - pgprot_writecombine(vma->vm_page_prot)); 800 - } 801 - 802 - static void clcdfb_of_vram_remove(struct clcd_fb *fb) 803 - { 804 - iounmap(fb->fb.screen_base); 805 - } 806 - 807 - static int clcdfb_of_dma_setup(struct clcd_fb *fb) 808 - { 809 - unsigned long framesize; 810 - dma_addr_t dma; 811 - int err; 812 - 813 - err = clcdfb_of_init_display(fb); 814 - if (err) 815 - return err; 816 - 817 - framesize = PAGE_ALIGN(fb->panel->mode.xres * fb->panel->mode.yres * 818 - fb->panel->bpp / 8); 819 - fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize, 820 - &dma, GFP_KERNEL); 821 - if (!fb->fb.screen_base) 822 - return -ENOMEM; 823 - 824 - fb->fb.fix.smem_start = dma; 825 - fb->fb.fix.smem_len = framesize; 826 - 827 - return 0; 828 - } 829 - 830 - static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) 831 - { 832 - return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base, 833 - fb->fb.fix.smem_start, fb->fb.fix.smem_len); 834 - } 835 - 836 - static void clcdfb_of_dma_remove(struct clcd_fb *fb) 837 - { 838 - dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len, 839 - fb->fb.screen_base, fb->fb.fix.smem_start); 840 - } 841 - 842 - static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev) 843 - { 844 - struct clcd_board *board = devm_kzalloc(&dev->dev, sizeof(*board), 845 - GFP_KERNEL); 846 - struct device_node *node = dev->dev.of_node; 847 - 848 - if (!board) 849 - return NULL; 850 - 851 - board->name = of_node_full_name(node); 852 - board->caps = CLCD_CAP_ALL; 853 - board->check = clcdfb_check; 854 - board->decode = clcdfb_decode; 855 - if (of_find_property(node, "memory-region", NULL)) { 856 - board->setup = clcdfb_of_vram_setup; 857 - board->mmap = clcdfb_of_vram_mmap; 858 - board->remove = clcdfb_of_vram_remove; 859 - } else { 860 - board->setup = clcdfb_of_dma_setup; 861 - board->mmap = clcdfb_of_dma_mmap; 862 - board->remove = clcdfb_of_dma_remove; 863 - } 864 - 865 - return board; 866 - } 867 - #else 868 - static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev) 869 - { 870 - return NULL; 871 - } 872 - #endif 873 - 874 - static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) 875 - { 876 - struct clcd_board *board = dev_get_platdata(&dev->dev); 877 - struct clcd_fb *fb; 878 - int ret; 879 - 880 - if (!board) 881 - board = clcdfb_of_get_board(dev); 882 - 883 - if (!board) 884 - return -EINVAL; 885 - 886 - ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); 887 - if (ret) 888 - goto out; 889 - 890 - ret = amba_request_regions(dev, NULL); 891 - if (ret) { 892 - printk(KERN_ERR "CLCD: unable to reserve regs region\n"); 893 - goto out; 894 - } 895 - 896 - fb = kzalloc(sizeof(*fb), GFP_KERNEL); 897 - if (!fb) { 898 - ret = -ENOMEM; 899 - goto free_region; 900 - } 901 - 902 - fb->dev = dev; 903 - fb->board = board; 904 - 905 - dev_info(&fb->dev->dev, "PL%03x designer %02x rev%u at 0x%08llx\n", 906 - amba_part(dev), amba_manf(dev), amba_rev(dev), 907 - (unsigned long long)dev->res.start); 908 - 909 - ret = fb->board->setup(fb); 910 - if (ret) 911 - goto free_fb; 912 - 913 - ret = clcdfb_register(fb); 914 - if (ret == 0) { 915 - amba_set_drvdata(dev, fb); 916 - goto out; 917 - } 918 - 919 - fb->board->remove(fb); 920 - free_fb: 921 - kfree(fb); 922 - free_region: 923 - amba_release_regions(dev); 924 - out: 925 - return ret; 926 - } 927 - 928 - static int clcdfb_remove(struct amba_device *dev) 929 - { 930 - struct clcd_fb *fb = amba_get_drvdata(dev); 931 - 932 - clcdfb_disable(fb); 933 - unregister_framebuffer(&fb->fb); 934 - if (fb->fb.cmap.len) 935 - fb_dealloc_cmap(&fb->fb.cmap); 936 - iounmap(fb->regs); 937 - clk_unprepare(fb->clk); 938 - clk_put(fb->clk); 939 - 940 - fb->board->remove(fb); 941 - 942 - kfree(fb); 943 - 944 - amba_release_regions(dev); 945 - 946 - return 0; 947 - } 948 - 949 - static const struct amba_id clcdfb_id_table[] = { 950 - { 951 - .id = 0x00041110, 952 - .mask = 0x000ffffe, 953 - }, 954 - { 0, 0 }, 955 - }; 956 - 957 - MODULE_DEVICE_TABLE(amba, clcdfb_id_table); 958 - 959 - static struct amba_driver clcd_driver = { 960 - .drv = { 961 - .name = "clcd-pl11x", 962 - }, 963 - .probe = clcdfb_probe, 964 - .remove = clcdfb_remove, 965 - .id_table = clcdfb_id_table, 966 - }; 967 - 968 - static int __init amba_clcdfb_init(void) 969 - { 970 - if (fb_get_options("ambafb", NULL)) 971 - return -ENODEV; 972 - 973 - return amba_driver_register(&clcd_driver); 974 - } 975 - 976 - module_init(amba_clcdfb_init); 977 - 978 - static void __exit amba_clcdfb_exit(void) 979 - { 980 - amba_driver_unregister(&clcd_driver); 981 - } 982 - 983 - module_exit(amba_clcdfb_exit); 984 - 985 - MODULE_DESCRIPTION("ARM PrimeCell PL110 CLCD core driver"); 986 - MODULE_LICENSE("GPL");
+8
drivers/video/fbdev/amifb.c
··· 575 575 #define downx(x, v) ((v) & -(x)) 576 576 #define modx(x, v) ((v) & ((x) - 1)) 577 577 578 + /* 579 + * FIXME: Use C variants of the code marked with #ifdef __mc68000__ 580 + * in the driver. It shouldn't negatively affect the performance and 581 + * is required for APUS support (once it is re-added to the kernel). 582 + * Needs to be tested on the hardware though.. 583 + */ 578 584 /* if x1 is not a constant, this macro won't make real sense :-) */ 579 585 #ifdef __mc68000__ 580 586 #define DIVUL(x1, x2) ({int res; asm("divul %1,%2,%3": "=d" (res): \ ··· 1890 1884 | ((datawords >> 15) & 1)); 1891 1885 datawords <<= 1; 1892 1886 #endif 1887 + /* FIXME: check the return value + test the change */ 1893 1888 put_user(color, data++); 1894 1889 } 1895 1890 if (bits > 0) { ··· 1959 1952 bits = 16; words = delta; datawords = 0; 1960 1953 for (width = (short)var->width - 1; width >= 0; width--) { 1961 1954 unsigned long tdata = 0; 1955 + /* FIXME: check the return value + test the change */ 1962 1956 get_user(tdata, data); 1963 1957 data++; 1964 1958 #ifdef __mc68000__
+2 -2
drivers/video/fbdev/core/fbcon.c
··· 639 639 GFP_KERNEL); 640 640 if (save) { 641 641 int i = cols < new_cols ? cols : new_cols; 642 - scr_memsetw(save, erase, logo_lines * new_cols * 2); 642 + scr_memsetw(save, erase, array3_size(logo_lines, new_cols, 2)); 643 643 r = q - step; 644 644 for (cnt = 0; cnt < logo_lines; cnt++, r += i) 645 645 scr_memcpyw(save + cnt * new_cols, r, 2 * i); ··· 676 676 q = (unsigned short *) (vc->vc_origin + 677 677 vc->vc_size_row * 678 678 rows); 679 - scr_memcpyw(q, save, logo_lines * new_cols * 2); 679 + scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2)); 680 680 vc->vc_y += logo_lines; 681 681 vc->vc_pos += logo_lines * vc->vc_size_row; 682 682 kfree(save);
+2 -2
drivers/video/fbdev/da8xx-fb.c
··· 1402 1402 if (IS_ERR(par->lcd_supply)) { 1403 1403 if (PTR_ERR(par->lcd_supply) == -EPROBE_DEFER) { 1404 1404 ret = -EPROBE_DEFER; 1405 - goto err_pm_runtime_disable; 1405 + goto err_release_fb; 1406 1406 } 1407 1407 1408 1408 par->lcd_supply = NULL; 1409 1409 } else { 1410 1410 ret = regulator_enable(par->lcd_supply); 1411 1411 if (ret) 1412 - goto err_pm_runtime_disable; 1412 + goto err_release_fb; 1413 1413 } 1414 1414 1415 1415 fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
+1
drivers/video/fbdev/neofb.c
··· 1819 1819 #else 1820 1820 printk(KERN_ERR 1821 1821 "neofb: Only 640x480, 800x600/480 and 1024x768 panels are currently supported\n"); 1822 + kfree(info->monspecs.modedb); 1822 1823 return -1; 1823 1824 #endif 1824 1825 default:
+5 -2
drivers/video/fbdev/omap2/omapfb/dss/dispc.c
··· 520 520 DSSDBG("dispc_runtime_get\n"); 521 521 522 522 r = pm_runtime_get_sync(&dispc.pdev->dev); 523 - WARN_ON(r < 0); 524 - return r < 0 ? r : 0; 523 + if (WARN_ON(r < 0)) { 524 + pm_runtime_put_sync(&dispc.pdev->dev); 525 + return r; 526 + } 527 + return 0; 525 528 } 526 529 EXPORT_SYMBOL(dispc_runtime_get); 527 530
+5 -2
drivers/video/fbdev/omap2/omapfb/dss/dsi.c
··· 1137 1137 DSSDBG("dsi_runtime_get\n"); 1138 1138 1139 1139 r = pm_runtime_get_sync(&dsi->pdev->dev); 1140 - WARN_ON(r < 0); 1141 - return r < 0 ? r : 0; 1140 + if (WARN_ON(r < 0)) { 1141 + pm_runtime_put_sync(&dsi->pdev->dev); 1142 + return r; 1143 + } 1144 + return 0; 1142 1145 } 1143 1146 1144 1147 static void dsi_runtime_put(struct platform_device *dsidev)
+6 -3
drivers/video/fbdev/omap2/omapfb/dss/dss.c
··· 768 768 DSSDBG("dss_runtime_get\n"); 769 769 770 770 r = pm_runtime_get_sync(&dss.pdev->dev); 771 - WARN_ON(r < 0); 772 - return r < 0 ? r : 0; 771 + if (WARN_ON(r < 0)) { 772 + pm_runtime_put_sync(&dss.pdev->dev); 773 + return r; 774 + } 775 + return 0; 773 776 } 774 777 775 778 void dss_runtime_put(void) ··· 836 833 }; 837 834 838 835 static const struct dss_features omap3630_dss_feats = { 839 - .fck_div_max = 32, 836 + .fck_div_max = 31, 840 837 .dss_fck_multiplier = 1, 841 838 .parent_clk_name = "dpll4_ck", 842 839 .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+3 -2
drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
··· 39 39 DSSDBG("hdmi_runtime_get\n"); 40 40 41 41 r = pm_runtime_get_sync(&hdmi.pdev->dev); 42 - WARN_ON(r < 0); 43 - if (r < 0) 42 + if (WARN_ON(r < 0)) { 43 + pm_runtime_put_sync(&hdmi.pdev->dev); 44 44 return r; 45 + } 45 46 46 47 return 0; 47 48 }
+3 -2
drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
··· 43 43 DSSDBG("hdmi_runtime_get\n"); 44 44 45 45 r = pm_runtime_get_sync(&hdmi.pdev->dev); 46 - WARN_ON(r < 0); 47 - if (r < 0) 46 + if (WARN_ON(r < 0)) { 47 + pm_runtime_put_sync(&hdmi.pdev->dev); 48 48 return r; 49 + } 49 50 50 51 return 0; 51 52 }
+5 -2
drivers/video/fbdev/omap2/omapfb/dss/venc.c
··· 348 348 DSSDBG("venc_runtime_get\n"); 349 349 350 350 r = pm_runtime_get_sync(&venc.pdev->dev); 351 - WARN_ON(r < 0); 352 - return r < 0 ? r : 0; 351 + if (WARN_ON(r < 0)) { 352 + pm_runtime_put_sync(&venc.pdev->dev); 353 + return r; 354 + } 355 + return 0; 353 356 } 354 357 355 358 static void venc_runtime_put(void)
+2
drivers/video/fbdev/savage/savagefb_driver.c
··· 2157 2157 info->flags |= FBINFO_HWACCEL_COPYAREA | 2158 2158 FBINFO_HWACCEL_FILLRECT | 2159 2159 FBINFO_HWACCEL_IMAGEBLIT; 2160 + else 2161 + kfree(info->pixmap.addr); 2160 2162 } 2161 2163 #endif 2162 2164 return err;
+1 -1
drivers/video/fbdev/sm712fb.c
··· 1616 1616 default: 1617 1617 dev_err(&pdev->dev, 1618 1618 "No valid Silicon Motion display chip was detected!\n"); 1619 - 1619 + err = -ENODEV; 1620 1620 goto failed_fb; 1621 1621 } 1622 1622
+16 -16
drivers/video/fbdev/vt8623fb.c
··· 62 62 63 63 /* CRT timing register sets */ 64 64 65 - static struct vga_regset vt8623_h_total_regs[] = {{0x00, 0, 7}, {0x36, 3, 3}, VGA_REGSET_END}; 66 - static struct vga_regset vt8623_h_display_regs[] = {{0x01, 0, 7}, VGA_REGSET_END}; 67 - static struct vga_regset vt8623_h_blank_start_regs[] = {{0x02, 0, 7}, VGA_REGSET_END}; 68 - static struct vga_regset vt8623_h_blank_end_regs[] = {{0x03, 0, 4}, {0x05, 7, 7}, {0x33, 5, 5}, VGA_REGSET_END}; 69 - static struct vga_regset vt8623_h_sync_start_regs[] = {{0x04, 0, 7}, {0x33, 4, 4}, VGA_REGSET_END}; 70 - static struct vga_regset vt8623_h_sync_end_regs[] = {{0x05, 0, 4}, VGA_REGSET_END}; 65 + static const struct vga_regset vt8623_h_total_regs[] = {{0x00, 0, 7}, {0x36, 3, 3}, VGA_REGSET_END}; 66 + static const struct vga_regset vt8623_h_display_regs[] = {{0x01, 0, 7}, VGA_REGSET_END}; 67 + static const struct vga_regset vt8623_h_blank_start_regs[] = {{0x02, 0, 7}, VGA_REGSET_END}; 68 + static const struct vga_regset vt8623_h_blank_end_regs[] = {{0x03, 0, 4}, {0x05, 7, 7}, {0x33, 5, 5}, VGA_REGSET_END}; 69 + static const struct vga_regset vt8623_h_sync_start_regs[] = {{0x04, 0, 7}, {0x33, 4, 4}, VGA_REGSET_END}; 70 + static const struct vga_regset vt8623_h_sync_end_regs[] = {{0x05, 0, 4}, VGA_REGSET_END}; 71 71 72 - static struct vga_regset vt8623_v_total_regs[] = {{0x06, 0, 7}, {0x07, 0, 0}, {0x07, 5, 5}, {0x35, 0, 0}, VGA_REGSET_END}; 73 - static struct vga_regset vt8623_v_display_regs[] = {{0x12, 0, 7}, {0x07, 1, 1}, {0x07, 6, 6}, {0x35, 2, 2}, VGA_REGSET_END}; 74 - static struct vga_regset vt8623_v_blank_start_regs[] = {{0x15, 0, 7}, {0x07, 3, 3}, {0x09, 5, 5}, {0x35, 3, 3}, VGA_REGSET_END}; 75 - static struct vga_regset vt8623_v_blank_end_regs[] = {{0x16, 0, 7}, VGA_REGSET_END}; 76 - static struct vga_regset vt8623_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07, 2, 2}, {0x07, 7, 7}, {0x35, 1, 1}, VGA_REGSET_END}; 77 - static struct vga_regset vt8623_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END}; 72 + static const struct vga_regset vt8623_v_total_regs[] = {{0x06, 0, 7}, {0x07, 0, 0}, {0x07, 5, 5}, {0x35, 0, 0}, VGA_REGSET_END}; 73 + static const struct vga_regset vt8623_v_display_regs[] = {{0x12, 0, 7}, {0x07, 1, 1}, {0x07, 6, 6}, {0x35, 2, 2}, VGA_REGSET_END}; 74 + static const struct vga_regset vt8623_v_blank_start_regs[] = {{0x15, 0, 7}, {0x07, 3, 3}, {0x09, 5, 5}, {0x35, 3, 3}, VGA_REGSET_END}; 75 + static const struct vga_regset vt8623_v_blank_end_regs[] = {{0x16, 0, 7}, VGA_REGSET_END}; 76 + static const struct vga_regset vt8623_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07, 2, 2}, {0x07, 7, 7}, {0x35, 1, 1}, VGA_REGSET_END}; 77 + static const struct vga_regset vt8623_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END}; 78 78 79 - static struct vga_regset vt8623_offset_regs[] = {{0x13, 0, 7}, {0x35, 5, 7}, VGA_REGSET_END}; 80 - static struct vga_regset vt8623_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x33, 0, 2}, {0x35, 4, 4}, VGA_REGSET_END}; 81 - static struct vga_regset vt8623_fetch_count_regs[] = {{0x1C, 0, 7}, {0x1D, 0, 1}, VGA_REGSET_END}; 82 - static struct vga_regset vt8623_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x34, 0, 7}, {0x48, 0, 1}, VGA_REGSET_END}; 79 + static const struct vga_regset vt8623_offset_regs[] = {{0x13, 0, 7}, {0x35, 5, 7}, VGA_REGSET_END}; 80 + static const struct vga_regset vt8623_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x33, 0, 2}, {0x35, 4, 4}, VGA_REGSET_END}; 81 + static const struct vga_regset vt8623_fetch_count_regs[] = {{0x1C, 0, 7}, {0x1D, 0, 1}, VGA_REGSET_END}; 82 + static const struct vga_regset vt8623_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x34, 0, 7}, {0x48, 0, 1}, VGA_REGSET_END}; 83 83 84 84 static const struct svga_timing_regs vt8623_timing_regs = { 85 85 vt8623_h_total_regs, vt8623_h_display_regs, vt8623_h_blank_start_regs,
+1 -1
include/drm/drm_atomic.h
··· 103 103 * 104 104 * Will be signalled when all hw register changes for this commit have 105 105 * been written out. Especially when disabling a pipe this can be much 106 - * later than than @flip_done, since that can signal already when the 106 + * later than @flip_done, since that can signal already when the 107 107 * screen goes black, whereas to fully shut down a pipe more register 108 108 * I/O is required. 109 109 *
+1 -1
include/drm/drm_bridge.h
··· 475 475 * one of them should be provided. 476 476 * 477 477 * If drivers need to tweak &drm_bridge_state.input_bus_cfg.flags or 478 - * &drm_bridge_state.output_bus_cfg.flags it should should happen in 478 + * &drm_bridge_state.output_bus_cfg.flags it should happen in 479 479 * this function. By default the &drm_bridge_state.output_bus_cfg.flags 480 480 * field is set to the next bridge 481 481 * &drm_bridge_state.input_bus_cfg.flags value or
+87 -39
include/drm/drm_connector.h
··· 320 320 * opposite edge of the driving edge. Transmitters and receivers may however 321 321 * need to take other signal timings into account to convert between driving 322 322 * and sample edges. 323 - * 324 - * @DRM_BUS_FLAG_DE_LOW: The Data Enable signal is active low 325 - * @DRM_BUS_FLAG_DE_HIGH: The Data Enable signal is active high 326 - * @DRM_BUS_FLAG_PIXDATA_POSEDGE: Legacy value, do not use 327 - * @DRM_BUS_FLAG_PIXDATA_NEGEDGE: Legacy value, do not use 328 - * @DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE: Data is driven on the rising edge of 329 - * the pixel clock 330 - * @DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE: Data is driven on the falling edge of 331 - * the pixel clock 332 - * @DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE: Data is sampled on the rising edge of 333 - * the pixel clock 334 - * @DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE: Data is sampled on the falling edge of 335 - * the pixel clock 336 - * @DRM_BUS_FLAG_DATA_MSB_TO_LSB: Data is transmitted MSB to LSB on the bus 337 - * @DRM_BUS_FLAG_DATA_LSB_TO_MSB: Data is transmitted LSB to MSB on the bus 338 - * @DRM_BUS_FLAG_SYNC_POSEDGE: Legacy value, do not use 339 - * @DRM_BUS_FLAG_SYNC_NEGEDGE: Legacy value, do not use 340 - * @DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE: Sync signals are driven on the rising 341 - * edge of the pixel clock 342 - * @DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE: Sync signals are driven on the falling 343 - * edge of the pixel clock 344 - * @DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE: Sync signals are sampled on the rising 345 - * edge of the pixel clock 346 - * @DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE: Sync signals are sampled on the falling 347 - * edge of the pixel clock 348 - * @DRM_BUS_FLAG_SHARP_SIGNALS: Set if the Sharp-specific signals 349 - * (SPL, CLS, PS, REV) must be used 350 323 */ 351 324 enum drm_bus_flags { 325 + /** 326 + * @DRM_BUS_FLAG_DE_LOW: 327 + * 328 + * The Data Enable signal is active low 329 + */ 352 330 DRM_BUS_FLAG_DE_LOW = BIT(0), 331 + 332 + /** 333 + * @DRM_BUS_FLAG_DE_HIGH: 334 + * 335 + * The Data Enable signal is active high 336 + */ 353 337 DRM_BUS_FLAG_DE_HIGH = BIT(1), 354 - DRM_BUS_FLAG_PIXDATA_POSEDGE = BIT(2), 355 - DRM_BUS_FLAG_PIXDATA_NEGEDGE = BIT(3), 356 - DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE = DRM_BUS_FLAG_PIXDATA_POSEDGE, 357 - DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE = DRM_BUS_FLAG_PIXDATA_NEGEDGE, 358 - DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE = DRM_BUS_FLAG_PIXDATA_NEGEDGE, 359 - DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE = DRM_BUS_FLAG_PIXDATA_POSEDGE, 338 + 339 + /** 340 + * @DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE: 341 + * 342 + * Data is driven on the rising edge of the pixel clock 343 + */ 344 + DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE = BIT(2), 345 + 346 + /** 347 + * @DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE: 348 + * 349 + * Data is driven on the falling edge of the pixel clock 350 + */ 351 + DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE = BIT(3), 352 + 353 + /** 354 + * @DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE: 355 + * 356 + * Data is sampled on the rising edge of the pixel clock 357 + */ 358 + DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE = DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, 359 + 360 + /** 361 + * @DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE: 362 + * 363 + * Data is sampled on the falling edge of the pixel clock 364 + */ 365 + DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, 366 + 367 + /** 368 + * @DRM_BUS_FLAG_DATA_MSB_TO_LSB: 369 + * 370 + * Data is transmitted MSB to LSB on the bus 371 + */ 360 372 DRM_BUS_FLAG_DATA_MSB_TO_LSB = BIT(4), 373 + 374 + /** 375 + * @DRM_BUS_FLAG_DATA_LSB_TO_MSB: 376 + * 377 + * Data is transmitted LSB to MSB on the bus 378 + */ 361 379 DRM_BUS_FLAG_DATA_LSB_TO_MSB = BIT(5), 362 - DRM_BUS_FLAG_SYNC_POSEDGE = BIT(6), 363 - DRM_BUS_FLAG_SYNC_NEGEDGE = BIT(7), 364 - DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE = DRM_BUS_FLAG_SYNC_POSEDGE, 365 - DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE = DRM_BUS_FLAG_SYNC_NEGEDGE, 366 - DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE = DRM_BUS_FLAG_SYNC_NEGEDGE, 367 - DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE = DRM_BUS_FLAG_SYNC_POSEDGE, 380 + 381 + /** 382 + * @DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE: 383 + * 384 + * Sync signals are driven on the rising edge of the pixel clock 385 + */ 386 + DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE = BIT(6), 387 + 388 + /** 389 + * @DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE: 390 + * 391 + * Sync signals are driven on the falling edge of the pixel clock 392 + */ 393 + DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE = BIT(7), 394 + 395 + /** 396 + * @DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE: 397 + * 398 + * Sync signals are sampled on the rising edge of the pixel clock 399 + */ 400 + DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE = DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE, 401 + 402 + /** 403 + * @DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE: 404 + * 405 + * Sync signals are sampled on the falling edge of the pixel clock 406 + */ 407 + DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE = DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE, 408 + 409 + /** 410 + * @DRM_BUS_FLAG_SHARP_SIGNALS: 411 + * 412 + * Set if the Sharp-specific signals (SPL, CLS, PS, REV) must be used 413 + */ 368 414 DRM_BUS_FLAG_SHARP_SIGNALS = BIT(8), 369 415 }; 370 416 ··· 1375 1329 enum drm_connector_force force; 1376 1330 /** @override_edid: has the EDID been overwritten through debugfs for testing? */ 1377 1331 bool override_edid; 1332 + /** @epoch_counter: used to detect any other changes in connector, besides status */ 1333 + u64 epoch_counter; 1378 1334 1379 1335 /** 1380 1336 * @possible_encoders: Bit mask of encoders that can drive this
+9
include/drm/drm_edid.h
··· 359 359 } 360 360 #endif 361 361 362 + /** 363 + * drm_edid_are_equal - compare two edid blobs. 364 + * @edid1: pointer to first blob 365 + * @edid2: pointer to second blob 366 + * This helper can be used during probing to determine if 367 + * edid had changed. 368 + */ 369 + bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2); 370 + 362 371 int 363 372 drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, 364 373 const struct drm_connector *connector,
+2 -2
include/drm/drm_gem.h
··· 143 143 /** 144 144 * @vunmap: 145 145 * 146 - * Releases the the address previously returned by @vmap. Used by the 146 + * Releases the address previously returned by @vmap. Used by the 147 147 * drm_gem_dmabuf_vunmap() helper. 148 148 * 149 149 * This callback is optional. ··· 157 157 * 158 158 * This callback is optional. 159 159 * 160 - * The callback is used by by both drm_gem_mmap_obj() and 160 + * The callback is used by both drm_gem_mmap_obj() and 161 161 * drm_gem_prime_mmap(). When @mmap is present @vm_ops is not 162 162 * used, the @mmap callback must set vma->vm_ops instead. 163 163 */
+4 -4
include/drm/drm_mode_config.h
··· 603 603 struct drm_property *prop_src_h; 604 604 /** 605 605 * @prop_crtc_x: Default atomic plane property for the plane destination 606 - * position in the &drm_crtc is is being shown on. 606 + * position in the &drm_crtc is being shown on. 607 607 */ 608 608 struct drm_property *prop_crtc_x; 609 609 /** 610 610 * @prop_crtc_y: Default atomic plane property for the plane destination 611 - * position in the &drm_crtc is is being shown on. 611 + * position in the &drm_crtc is being shown on. 612 612 */ 613 613 struct drm_property *prop_crtc_y; 614 614 /** 615 615 * @prop_crtc_w: Default atomic plane property for the plane destination 616 - * position in the &drm_crtc is is being shown on. 616 + * position in the &drm_crtc is being shown on. 617 617 */ 618 618 struct drm_property *prop_crtc_w; 619 619 /** 620 620 * @prop_crtc_h: Default atomic plane property for the plane destination 621 - * position in the &drm_crtc is is being shown on. 621 + * position in the &drm_crtc is being shown on. 622 622 */ 623 623 struct drm_property *prop_crtc_h; 624 624 /**
+1 -1
include/drm/drm_rect.h
··· 180 180 } 181 181 182 182 /** 183 - * drm_rect_visible - determine if the the rectangle is visible 183 + * drm_rect_visible - determine if the rectangle is visible 184 184 * @r: rectangle whose visibility is returned 185 185 * 186 186 * RETURNS:
+3 -3
include/drm/gpu_scheduler.h
··· 263 263 * @job_list_lock: lock to protect the ring_mirror_list. 264 264 * @hang_limit: once the hangs by a job crosses this limit then it is marked 265 265 * guilty and it will be considered for scheduling further. 266 - * @num_jobs: the number of jobs in queue in the scheduler 266 + * @score: score to help loadbalancer pick a idle sched 267 267 * @ready: marks if the underlying HW is ready to work 268 268 * @free_guilty: A hit to time out handler to free the guilty job. 269 269 * ··· 284 284 struct list_head ring_mirror_list; 285 285 spinlock_t job_list_lock; 286 286 int hang_limit; 287 - atomic_t num_jobs; 288 - bool ready; 287 + atomic_t score; 288 + bool ready; 289 289 bool free_guilty; 290 290 }; 291 291
-2
include/drm/ttm/ttm_bo_api.h
··· 213 213 * either of these locks held. 214 214 */ 215 215 216 - uint64_t offset; /* GPU address space is independent of CPU word size */ 217 - 218 216 struct sg_table *sg; 219 217 }; 220 218
-3
include/drm/ttm/ttm_bo_driver.h
··· 177 177 bool has_type; 178 178 bool use_type; 179 179 uint32_t flags; 180 - uint64_t gpu_offset; /* GPU address space is independent of CPU word size */ 181 180 uint64_t size; 182 181 uint32_t available_caching; 183 182 uint32_t default_caching; ··· 564 565 struct ttm_operation_ctx *ctx); 565 566 566 567 void ttm_bo_mem_put(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem); 567 - void ttm_bo_mem_put_locked(struct ttm_buffer_object *bo, 568 - struct ttm_mem_reg *mem); 569 568 570 569 int ttm_bo_device_release(struct ttm_bo_device *bdev); 571 570
-87
include/linux/amba/clcd-regs.h
··· 1 - /* 2 - * David A Rusling 3 - * 4 - * Copyright (C) 2001 ARM Limited 5 - * 6 - * This file is subject to the terms and conditions of the GNU General Public 7 - * License. See the file COPYING in the main directory of this archive 8 - * for more details. 9 - */ 10 - 11 - #ifndef AMBA_CLCD_REGS_H 12 - #define AMBA_CLCD_REGS_H 13 - 14 - /* 15 - * CLCD Controller Internal Register addresses 16 - */ 17 - #define CLCD_TIM0 0x00000000 18 - #define CLCD_TIM1 0x00000004 19 - #define CLCD_TIM2 0x00000008 20 - #define CLCD_TIM3 0x0000000c 21 - #define CLCD_UBAS 0x00000010 22 - #define CLCD_LBAS 0x00000014 23 - 24 - #define CLCD_PL110_IENB 0x00000018 25 - #define CLCD_PL110_CNTL 0x0000001c 26 - #define CLCD_PL110_STAT 0x00000020 27 - #define CLCD_PL110_INTR 0x00000024 28 - #define CLCD_PL110_UCUR 0x00000028 29 - #define CLCD_PL110_LCUR 0x0000002C 30 - 31 - #define CLCD_PL111_CNTL 0x00000018 32 - #define CLCD_PL111_IENB 0x0000001c 33 - #define CLCD_PL111_RIS 0x00000020 34 - #define CLCD_PL111_MIS 0x00000024 35 - #define CLCD_PL111_ICR 0x00000028 36 - #define CLCD_PL111_UCUR 0x0000002c 37 - #define CLCD_PL111_LCUR 0x00000030 38 - 39 - #define CLCD_PALL 0x00000200 40 - #define CLCD_PALETTE 0x00000200 41 - 42 - #define TIM2_PCD_LO_MASK GENMASK(4, 0) 43 - #define TIM2_PCD_LO_BITS 5 44 - #define TIM2_CLKSEL (1 << 5) 45 - #define TIM2_ACB_MASK GENMASK(10, 6) 46 - #define TIM2_IVS (1 << 11) 47 - #define TIM2_IHS (1 << 12) 48 - #define TIM2_IPC (1 << 13) 49 - #define TIM2_IOE (1 << 14) 50 - #define TIM2_BCD (1 << 26) 51 - #define TIM2_PCD_HI_MASK GENMASK(31, 27) 52 - #define TIM2_PCD_HI_BITS 5 53 - #define TIM2_PCD_HI_SHIFT 27 54 - 55 - #define CNTL_LCDEN (1 << 0) 56 - #define CNTL_LCDBPP1 (0 << 1) 57 - #define CNTL_LCDBPP2 (1 << 1) 58 - #define CNTL_LCDBPP4 (2 << 1) 59 - #define CNTL_LCDBPP8 (3 << 1) 60 - #define CNTL_LCDBPP16 (4 << 1) 61 - #define CNTL_LCDBPP16_565 (6 << 1) 62 - #define CNTL_LCDBPP16_444 (7 << 1) 63 - #define CNTL_LCDBPP24 (5 << 1) 64 - #define CNTL_LCDBW (1 << 4) 65 - #define CNTL_LCDTFT (1 << 5) 66 - #define CNTL_LCDMONO8 (1 << 6) 67 - #define CNTL_LCDDUAL (1 << 7) 68 - #define CNTL_BGR (1 << 8) 69 - #define CNTL_BEBO (1 << 9) 70 - #define CNTL_BEPO (1 << 10) 71 - #define CNTL_LCDPWR (1 << 11) 72 - #define CNTL_LCDVCOMP(x) ((x) << 12) 73 - #define CNTL_LDMAFIFOTIME (1 << 15) 74 - #define CNTL_WATERMARK (1 << 16) 75 - 76 - /* ST Microelectronics variant bits */ 77 - #define CNTL_ST_1XBPP_444 0x0 78 - #define CNTL_ST_1XBPP_5551 (1 << 17) 79 - #define CNTL_ST_1XBPP_565 (1 << 18) 80 - #define CNTL_ST_CDWID_12 0x0 81 - #define CNTL_ST_CDWID_16 (1 << 19) 82 - #define CNTL_ST_CDWID_18 (1 << 20) 83 - #define CNTL_ST_CDWID_24 ((1 << 19)|(1 << 20)) 84 - #define CNTL_ST_CEAEN (1 << 21) 85 - #define CNTL_ST_LCDBPP24_PACKED (6 << 1) 86 - 87 - #endif /* AMBA_CLCD_REGS_H */
-290
include/linux/amba/clcd.h
··· 1 - /* 2 - * linux/include/asm-arm/hardware/amba_clcd.h -- Integrator LCD panel. 3 - * 4 - * David A Rusling 5 - * 6 - * Copyright (C) 2001 ARM Limited 7 - * 8 - * This file is subject to the terms and conditions of the GNU General Public 9 - * License. See the file COPYING in the main directory of this archive 10 - * for more details. 11 - */ 12 - #include <linux/fb.h> 13 - #include <linux/amba/clcd-regs.h> 14 - 15 - enum { 16 - /* individual formats */ 17 - CLCD_CAP_RGB444 = (1 << 0), 18 - CLCD_CAP_RGB5551 = (1 << 1), 19 - CLCD_CAP_RGB565 = (1 << 2), 20 - CLCD_CAP_RGB888 = (1 << 3), 21 - CLCD_CAP_BGR444 = (1 << 4), 22 - CLCD_CAP_BGR5551 = (1 << 5), 23 - CLCD_CAP_BGR565 = (1 << 6), 24 - CLCD_CAP_BGR888 = (1 << 7), 25 - 26 - /* connection layouts */ 27 - CLCD_CAP_444 = CLCD_CAP_RGB444 | CLCD_CAP_BGR444, 28 - CLCD_CAP_5551 = CLCD_CAP_RGB5551 | CLCD_CAP_BGR5551, 29 - CLCD_CAP_565 = CLCD_CAP_RGB565 | CLCD_CAP_BGR565, 30 - CLCD_CAP_888 = CLCD_CAP_RGB888 | CLCD_CAP_BGR888, 31 - 32 - /* red/blue ordering */ 33 - CLCD_CAP_RGB = CLCD_CAP_RGB444 | CLCD_CAP_RGB5551 | 34 - CLCD_CAP_RGB565 | CLCD_CAP_RGB888, 35 - CLCD_CAP_BGR = CLCD_CAP_BGR444 | CLCD_CAP_BGR5551 | 36 - CLCD_CAP_BGR565 | CLCD_CAP_BGR888, 37 - 38 - CLCD_CAP_ALL = CLCD_CAP_BGR | CLCD_CAP_RGB, 39 - }; 40 - 41 - struct backlight_device; 42 - 43 - struct clcd_panel { 44 - struct fb_videomode mode; 45 - signed short width; /* width in mm */ 46 - signed short height; /* height in mm */ 47 - u32 tim2; 48 - u32 tim3; 49 - u32 cntl; 50 - u32 caps; 51 - unsigned int bpp:8, 52 - fixedtimings:1, 53 - grayscale:1; 54 - unsigned int connector; 55 - struct backlight_device *backlight; 56 - /* 57 - * If the B/R lines are switched between the CLCD 58 - * and the panel we need to know this and not try to 59 - * compensate with the BGR bit in the control register. 60 - */ 61 - bool bgr_connection; 62 - }; 63 - 64 - struct clcd_regs { 65 - u32 tim0; 66 - u32 tim1; 67 - u32 tim2; 68 - u32 tim3; 69 - u32 cntl; 70 - unsigned long pixclock; 71 - }; 72 - 73 - struct clcd_fb; 74 - 75 - /* 76 - * the board-type specific routines 77 - */ 78 - struct clcd_board { 79 - const char *name; 80 - 81 - /* 82 - * Optional. Hardware capability flags. 83 - */ 84 - u32 caps; 85 - 86 - /* 87 - * Optional. Check whether the var structure is acceptable 88 - * for this display. 89 - */ 90 - int (*check)(struct clcd_fb *fb, struct fb_var_screeninfo *var); 91 - 92 - /* 93 - * Compulsory. Decode fb->fb.var into regs->*. In the case of 94 - * fixed timing, set regs->* to the register values required. 95 - */ 96 - void (*decode)(struct clcd_fb *fb, struct clcd_regs *regs); 97 - 98 - /* 99 - * Optional. Disable any extra display hardware. 100 - */ 101 - void (*disable)(struct clcd_fb *); 102 - 103 - /* 104 - * Optional. Enable any extra display hardware. 105 - */ 106 - void (*enable)(struct clcd_fb *); 107 - 108 - /* 109 - * Setup platform specific parts of CLCD driver 110 - */ 111 - int (*setup)(struct clcd_fb *); 112 - 113 - /* 114 - * mmap the framebuffer memory 115 - */ 116 - int (*mmap)(struct clcd_fb *, struct vm_area_struct *); 117 - 118 - /* 119 - * Remove platform specific parts of CLCD driver 120 - */ 121 - void (*remove)(struct clcd_fb *); 122 - }; 123 - 124 - struct amba_device; 125 - struct clk; 126 - 127 - /* this data structure describes each frame buffer device we find */ 128 - struct clcd_fb { 129 - struct fb_info fb; 130 - struct amba_device *dev; 131 - struct clk *clk; 132 - struct clcd_panel *panel; 133 - struct clcd_board *board; 134 - void *board_data; 135 - void __iomem *regs; 136 - u16 off_ienb; 137 - u16 off_cntl; 138 - u32 clcd_cntl; 139 - u32 cmap[16]; 140 - bool clk_enabled; 141 - }; 142 - 143 - static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) 144 - { 145 - struct fb_var_screeninfo *var = &fb->fb.var; 146 - u32 val, cpl; 147 - 148 - /* 149 - * Program the CLCD controller registers and start the CLCD 150 - */ 151 - val = ((var->xres / 16) - 1) << 2; 152 - val |= (var->hsync_len - 1) << 8; 153 - val |= (var->right_margin - 1) << 16; 154 - val |= (var->left_margin - 1) << 24; 155 - regs->tim0 = val; 156 - 157 - val = var->yres; 158 - if (fb->panel->cntl & CNTL_LCDDUAL) 159 - val /= 2; 160 - val -= 1; 161 - val |= (var->vsync_len - 1) << 10; 162 - val |= var->lower_margin << 16; 163 - val |= var->upper_margin << 24; 164 - regs->tim1 = val; 165 - 166 - val = fb->panel->tim2; 167 - val |= var->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : TIM2_IHS; 168 - val |= var->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : TIM2_IVS; 169 - 170 - cpl = var->xres_virtual; 171 - if (fb->panel->cntl & CNTL_LCDTFT) /* TFT */ 172 - /* / 1 */; 173 - else if (!var->grayscale) /* STN color */ 174 - cpl = cpl * 8 / 3; 175 - else if (fb->panel->cntl & CNTL_LCDMONO8) /* STN monochrome, 8bit */ 176 - cpl /= 8; 177 - else /* STN monochrome, 4bit */ 178 - cpl /= 4; 179 - 180 - regs->tim2 = val | ((cpl - 1) << 16); 181 - 182 - regs->tim3 = fb->panel->tim3; 183 - 184 - val = fb->panel->cntl; 185 - if (var->grayscale) 186 - val |= CNTL_LCDBW; 187 - 188 - if (fb->panel->caps && fb->board->caps && var->bits_per_pixel >= 16) { 189 - /* 190 - * if board and panel supply capabilities, we can support 191 - * changing BGR/RGB depending on supplied parameters. Here 192 - * we switch to what the framebuffer is providing if need 193 - * be, so if the framebuffer is BGR but the display connection 194 - * is RGB (first case) we switch it around. Vice versa mutatis 195 - * mutandis if the framebuffer is RGB but the display connection 196 - * is BGR, we flip it around. 197 - */ 198 - if (var->red.offset == 0) 199 - val &= ~CNTL_BGR; 200 - else 201 - val |= CNTL_BGR; 202 - if (fb->panel->bgr_connection) 203 - val ^= CNTL_BGR; 204 - } 205 - 206 - switch (var->bits_per_pixel) { 207 - case 1: 208 - val |= CNTL_LCDBPP1; 209 - break; 210 - case 2: 211 - val |= CNTL_LCDBPP2; 212 - break; 213 - case 4: 214 - val |= CNTL_LCDBPP4; 215 - break; 216 - case 8: 217 - val |= CNTL_LCDBPP8; 218 - break; 219 - case 16: 220 - /* 221 - * PL110 cannot choose between 5551 and 565 modes in its 222 - * control register. It is possible to use 565 with 223 - * custom external wiring. 224 - */ 225 - if (amba_part(fb->dev) == 0x110 || 226 - var->green.length == 5) 227 - val |= CNTL_LCDBPP16; 228 - else if (var->green.length == 6) 229 - val |= CNTL_LCDBPP16_565; 230 - else 231 - val |= CNTL_LCDBPP16_444; 232 - break; 233 - case 32: 234 - val |= CNTL_LCDBPP24; 235 - break; 236 - } 237 - 238 - regs->cntl = val; 239 - regs->pixclock = var->pixclock; 240 - } 241 - 242 - static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var) 243 - { 244 - var->xres_virtual = var->xres = (var->xres + 15) & ~15; 245 - var->yres_virtual = var->yres = (var->yres + 1) & ~1; 246 - 247 - #define CHECK(e,l,h) (var->e < l || var->e > h) 248 - if (CHECK(right_margin, (5+1), 256) || /* back porch */ 249 - CHECK(left_margin, (5+1), 256) || /* front porch */ 250 - CHECK(hsync_len, (5+1), 256) || 251 - var->xres > 4096 || 252 - var->lower_margin > 255 || /* back porch */ 253 - var->upper_margin > 255 || /* front porch */ 254 - var->vsync_len > 32 || 255 - var->yres > 1024) 256 - return -EINVAL; 257 - #undef CHECK 258 - 259 - /* single panel mode: PCD = max(PCD, 1) */ 260 - /* dual panel mode: PCD = max(PCD, 5) */ 261 - 262 - /* 263 - * You can't change the grayscale setting, and 264 - * we can only do non-interlaced video. 265 - */ 266 - if (var->grayscale != fb->fb.var.grayscale || 267 - (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) 268 - return -EINVAL; 269 - 270 - #define CHECK(e) (var->e != fb->fb.var.e) 271 - if (fb->panel->fixedtimings && 272 - (CHECK(xres) || 273 - CHECK(yres) || 274 - CHECK(bits_per_pixel) || 275 - CHECK(pixclock) || 276 - CHECK(left_margin) || 277 - CHECK(right_margin) || 278 - CHECK(upper_margin) || 279 - CHECK(lower_margin) || 280 - CHECK(hsync_len) || 281 - CHECK(vsync_len) || 282 - CHECK(sync))) 283 - return -EINVAL; 284 - #undef CHECK 285 - 286 - var->nonstd = 0; 287 - var->accel_flags = 0; 288 - 289 - return 0; 290 - }
+3 -2
include/linux/fb.h
··· 506 506 }; 507 507 508 508 static inline struct apertures_struct *alloc_apertures(unsigned int max_num) { 509 - struct apertures_struct *a = kzalloc(sizeof(struct apertures_struct) 510 - + max_num * sizeof(struct aperture), GFP_KERNEL); 509 + struct apertures_struct *a; 510 + 511 + a = kzalloc(struct_size(a, ranges, max_num), GFP_KERNEL); 511 512 if (!a) 512 513 return NULL; 513 514 a->count = max_num;
+6
include/linux/of_graph.h
··· 38 38 child = of_graph_get_next_endpoint(parent, child)) 39 39 40 40 #ifdef CONFIG_OF 41 + bool of_graph_is_present(const struct device_node *node); 41 42 int of_graph_parse_endpoint(const struct device_node *node, 42 43 struct of_endpoint *endpoint); 43 44 int of_graph_get_endpoint_count(const struct device_node *np); ··· 56 55 struct device_node *of_graph_get_remote_node(const struct device_node *node, 57 56 u32 port, u32 endpoint); 58 57 #else 58 + 59 + static inline bool of_graph_is_present(const struct device_node *node) 60 + { 61 + return false; 62 + } 59 63 60 64 static inline int of_graph_parse_endpoint(const struct device_node *node, 61 65 struct of_endpoint *endpoint)
+106
include/uapi/drm/drm_fourcc.h
··· 331 331 #define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07 332 332 #define DRM_FORMAT_MOD_VENDOR_ARM 0x08 333 333 #define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09 334 + #define DRM_FORMAT_MOD_VENDOR_AMLOGIC 0x0a 334 335 335 336 /* add more to the end as needed */ 336 337 ··· 346 345 * When adding a new token please document the layout with a code comment, 347 346 * similar to the fourcc codes above. drm_fourcc.h is considered the 348 347 * authoritative source for all of these. 348 + * 349 + * Generic modifier names: 350 + * 351 + * DRM_FORMAT_MOD_GENERIC_* definitions are used to provide vendor-neutral names 352 + * for layouts which are common across multiple vendors. To preserve 353 + * compatibility, in cases where a vendor-specific definition already exists and 354 + * a generic name for it is desired, the common name is a purely symbolic alias 355 + * and must use the same numerical value as the original definition. 356 + * 357 + * Note that generic names should only be used for modifiers which describe 358 + * generic layouts (such as pixel re-ordering), which may have 359 + * independently-developed support across multiple vendors. 360 + * 361 + * In future cases where a generic layout is identified before merging with a 362 + * vendor-specific modifier, a new 'GENERIC' vendor or modifier using vendor 363 + * 'NONE' could be considered. This should only be for obvious, exceptional 364 + * cases to avoid polluting the 'GENERIC' namespace with modifiers which only 365 + * apply to a single vendor. 366 + * 367 + * Generic names should not be used for cases where multiple hardware vendors 368 + * have implementations of the same standardised compression scheme (such as 369 + * AFBC). In those cases, all implementations should use the same format 370 + * modifier(s), reflecting the vendor of the standard. 349 371 */ 372 + 373 + #define DRM_FORMAT_MOD_GENERIC_16_16_TILE DRM_FORMAT_MOD_SAMSUNG_16_16_TILE 350 374 351 375 /* 352 376 * Invalid Modifier ··· 975 949 * both in row-major order. 976 950 */ 977 951 #define DRM_FORMAT_MOD_ALLWINNER_TILED fourcc_mod_code(ALLWINNER, 1) 952 + 953 + /* 954 + * Amlogic Video Framebuffer Compression modifiers 955 + * 956 + * Amlogic uses a proprietary lossless image compression protocol and format 957 + * for their hardware video codec accelerators, either video decoders or 958 + * video input encoders. 959 + * 960 + * It considerably reduces memory bandwidth while writing and reading 961 + * frames in memory. 962 + * 963 + * The underlying storage is considered to be 3 components, 8bit or 10-bit 964 + * per component YCbCr 420, single plane : 965 + * - DRM_FORMAT_YUV420_8BIT 966 + * - DRM_FORMAT_YUV420_10BIT 967 + * 968 + * The first 8 bits of the mode defines the layout, then the following 8 bits 969 + * defines the options changing the layout. 970 + * 971 + * Not all combinations are valid, and different SoCs may support different 972 + * combinations of layout and options. 973 + */ 974 + #define __fourcc_mod_amlogic_layout_mask 0xf 975 + #define __fourcc_mod_amlogic_options_shift 8 976 + #define __fourcc_mod_amlogic_options_mask 0xf 977 + 978 + #define DRM_FORMAT_MOD_AMLOGIC_FBC(__layout, __options) \ 979 + fourcc_mod_code(AMLOGIC, \ 980 + ((__layout) & __fourcc_mod_amlogic_layout_mask) | \ 981 + ((__options) & __fourcc_mod_amlogic_options_mask \ 982 + << __fourcc_mod_amlogic_options_shift)) 983 + 984 + /* Amlogic FBC Layouts */ 985 + 986 + /* 987 + * Amlogic FBC Basic Layout 988 + * 989 + * The basic layout is composed of: 990 + * - a body content organized in 64x32 superblocks with 4096 bytes per 991 + * superblock in default mode. 992 + * - a 32 bytes per 128x64 header block 993 + * 994 + * This layout is transferrable between Amlogic SoCs supporting this modifier. 995 + */ 996 + #define AMLOGIC_FBC_LAYOUT_BASIC (1ULL) 997 + 998 + /* 999 + * Amlogic FBC Scatter Memory layout 1000 + * 1001 + * Indicates the header contains IOMMU references to the compressed 1002 + * frames content to optimize memory access and layout. 1003 + * 1004 + * In this mode, only the header memory address is needed, thus the 1005 + * content memory organization is tied to the current producer 1006 + * execution and cannot be saved/dumped neither transferrable between 1007 + * Amlogic SoCs supporting this modifier. 1008 + * 1009 + * Due to the nature of the layout, these buffers are not expected to 1010 + * be accessible by the user-space clients, but only accessible by the 1011 + * hardware producers and consumers. 1012 + * 1013 + * The user-space clients should expect a failure while trying to mmap 1014 + * the DMA-BUF handle returned by the producer. 1015 + */ 1016 + #define AMLOGIC_FBC_LAYOUT_SCATTER (2ULL) 1017 + 1018 + /* Amlogic FBC Layout Options Bit Mask */ 1019 + 1020 + /* 1021 + * Amlogic FBC Memory Saving mode 1022 + * 1023 + * Indicates the storage is packed when pixel size is multiple of word 1024 + * boudaries, i.e. 8bit should be stored in this mode to save allocation 1025 + * memory. 1026 + * 1027 + * This mode reduces body layout to 3072 bytes per 64x32 superblock with 1028 + * the basic layout and 3200 bytes per 64x32 superblock combined with 1029 + * the scatter layout. 1030 + */ 1031 + #define AMLOGIC_FBC_OPTION_MEM_SAVING (1ULL << 0) 978 1032 979 1033 #if defined(__cplusplus) 980 1034 }
+2 -2
include/uapi/drm/i915_drm.h
··· 55 55 * cause the related events to not be seen. 56 56 * 57 57 * I915_RESET_UEVENT - Event is generated just before an attempt to reset the 58 - * the GPU. The value supplied with the event is always 1. NOTE: Disable 58 + * GPU. The value supplied with the event is always 1. NOTE: Disable 59 59 * reset via module parameter will cause this event to not be seen. 60 60 */ 61 61 #define I915_L3_PARITY_UEVENT "L3_PARITY_ERROR" ··· 1934 1934 1935 1935 /** 1936 1936 * The value specifies which set of OA unit metrics should be 1937 - * be configured, defining the contents of any OA unit reports. 1937 + * configured, defining the contents of any OA unit reports. 1938 1938 * 1939 1939 * This property is available in perf revision 1. 1940 1940 */
+2 -2
include/uapi/drm/msm_drm.h
··· 252 252 __u64 cmds; /* in, ptr to array of submit_cmd's */ 253 253 __s32 fence_fd; /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */ 254 254 __u32 queueid; /* in, submitqueue id */ 255 - __u64 in_syncobjs; /* in, ptr to to array of drm_msm_gem_submit_syncobj */ 256 - __u64 out_syncobjs; /* in, ptr to to array of drm_msm_gem_submit_syncobj */ 255 + __u64 in_syncobjs; /* in, ptr to array of drm_msm_gem_submit_syncobj */ 256 + __u64 out_syncobjs; /* in, ptr to array of drm_msm_gem_submit_syncobj */ 257 257 __u32 nr_in_syncobjs; /* in, number of entries in in_syncobj */ 258 258 __u32 nr_out_syncobjs; /* in, number of entries in out_syncobj. */ 259 259 __u32 syncobj_stride; /* in, stride of syncobj arrays. */