From 94b292b277343190175d39172c903c0c5fb814f1 Mon Sep 17 00:00:00 2001 From: Ben Davis Date: Mon, 1 Jun 2020 17:28:17 +0100 Subject: drm: drm_fourcc: add NV15, Q410, Q401 YUV formats DRM_FORMAT_NV15 is a 2 plane format suitable for linear and 16x16 block-linear memory layouts (DRM_FORMAT_MOD_SAMSUNG_16_16_TILE). The format is similar to P010 with 4:2:0 sub-sampling but has no padding between components. Instead, luminance and chrominance samples are grouped into 4s so that each group is packed into an integer number of bytes: YYYY = UVUV = 4 * 10 bits = 40 bits = 5 bytes The '15' suffix refers to the optimum effective bits per pixel which is achieved when the total number of luminance samples is a multiple of 8. Q410 and Q401 are both 3 plane non-subsampled formats with 16 bits per component, but only 10 bits are used and 6 are padded. 'Q' is chosen as the first letter to denote 3 plane YUV444, (and is the next letter along from P which is usually 2 plane). V2: Updated block_w of NV15 to {4, 2, 0} V3: Updated commit message to include specific modifier name NV15: Tested-by: Jonas Karlman Reviewed-by: Brian Starkey Signed-off-by: Ben Davis Signed-off-by: Liviu Dudau Link: https://patchwork.freedesktop.org/patch/msgid/20200601162817.18230-1-ben.davis@arm.com --- drivers/gpu/drm/drm_fourcc.c | 12 ++++++++++++ include/uapi/drm/drm_fourcc.h | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c index b234bfaeda06..722c7ebe4e88 100644 --- a/drivers/gpu/drm/drm_fourcc.c +++ b/drivers/gpu/drm/drm_fourcc.c @@ -274,6 +274,18 @@ const struct drm_format_info *__drm_format_info(u32 format) { .format = DRM_FORMAT_YUV420_10BIT, .depth = 0, .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true }, + { .format = DRM_FORMAT_NV15, .depth = 0, + .num_planes = 2, .char_per_block = { 5, 5, 0 }, + .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, + .vsub = 2, .is_yuv = true }, + { .format = DRM_FORMAT_Q410, .depth = 0, + .num_planes = 3, .char_per_block = { 2, 2, 2 }, + .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0, + .vsub = 0, .is_yuv = true }, + { .format = DRM_FORMAT_Q401, .depth = 0, + .num_planes = 3, .char_per_block = { 2, 2, 2 }, + .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0, + .vsub = 0, .is_yuv = true }, }; unsigned int i; diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 9e488d10f8b4..3c4055e48371 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -236,6 +236,12 @@ extern "C" { #define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ #define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */ #define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */ +/* + * 2 plane YCbCr + * index 0 = Y plane, [39:0] Y3:Y2:Y1:Y0 little endian + * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian + */ +#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ /* * 2 plane YCbCr MSB aligned @@ -265,6 +271,22 @@ extern "C" { */ #define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6') /* 2x2 subsampled Cr:Cb plane 16 bits per channel */ +/* 3 plane non-subsampled (444) YCbCr + * 16 bits per component, but only 10 bits are used and 6 bits are padded + * index 0: Y plane, [15:0] Y:x [10:6] little endian + * index 1: Cb plane, [15:0] Cb:x [10:6] little endian + * index 2: Cr plane, [15:0] Cr:x [10:6] little endian + */ +#define DRM_FORMAT_Q410 fourcc_code('Q', '4', '1', '0') + +/* 3 plane non-subsampled (444) YCrCb + * 16 bits per component, but only 10 bits are used and 6 bits are padded + * index 0: Y plane, [15:0] Y:x [10:6] little endian + * index 1: Cr plane, [15:0] Cr:x [10:6] little endian + * index 2: Cb plane, [15:0] Cb:x [10:6] little endian + */ +#define DRM_FORMAT_Q401 fourcc_code('Q', '4', '0', '1') + /* * 3 plane YCbCr * index 0: Y plane, [7:0] Y -- cgit v1.2.3 From 79ce058032c391b12af928b1e30abf92482a270f Mon Sep 17 00:00:00 2001 From: Ben Davis Date: Thu, 30 Apr 2020 09:32:20 +0100 Subject: drm: drm_fourcc: Add uncompressed AFBC modifier AFBC has a mode that guarantees use of AFBC with an uncompressed payloads, we add a new modifier to support this mode. V2: updated modifier comment Signed-off-by: Ben Davis Acked-by: Liviu Dudau Signed-off-by: Liviu Dudau Link: https://patchwork.freedesktop.org/patch/msgid/20200430083220.17347-1-ben.davis@arm.com --- include/uapi/drm/drm_fourcc.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 3c4055e48371..299f9ac4840b 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -808,6 +808,18 @@ extern "C" { */ #define AFBC_FORMAT_MOD_BCH (1ULL << 11) +/* AFBC uncompressed storage mode + * + * Indicates that the buffer is using AFBC uncompressed storage mode. + * In this mode all superblock payloads in the buffer use the uncompressed + * storage mode, which is usually only used for data which cannot be compressed. + * The buffer layout is the same as for AFBC buffers without USM set, this only + * affects the storage mode of the individual superblocks. Note that even a + * buffer without USM set may use uncompressed storage mode for some or all + * superblocks, USM just guarantees it for all. + */ +#define AFBC_FORMAT_MOD_USM (1ULL << 12) + /* * Arm 16x16 Block U-Interleaved modifier * -- cgit v1.2.3 From 5f368ddea6fec519bdb93b5368f6a844b6ea27a6 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 18 Jun 2020 11:04:00 +0100 Subject: drm/arm: fix unintentional integer overflow on left shift Shifting the integer value 1 is evaluated using 32-bit arithmetic and then used in an expression that expects a long value leads to a potential integer overflow. Fix this by using the BIT macro to perform the shift to avoid the overflow. Addresses-Coverity: ("Unintentional integer overflow") Fixes: ad49f8602fe8 ("drm/arm: Add support for Mali Display Processors") Signed-off-by: Colin Ian King Acked-by: Liviu Dudau Signed-off-by: Liviu Dudau Link: https://patchwork.freedesktop.org/patch/msgid/20200618100400.11464-1-colin.king@canonical.com --- drivers/gpu/drm/arm/malidp_planes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 37715cc6064e..ab45ac445045 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -928,7 +928,7 @@ int malidp_de_planes_init(struct drm_device *drm) const struct malidp_hw_regmap *map = &malidp->dev->hw->map; struct malidp_plane *plane = NULL; enum drm_plane_type plane_type; - unsigned long crtcs = 1 << drm->mode_config.num_crtc; + unsigned long crtcs = BIT(drm->mode_config.num_crtc); unsigned long flags = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y; unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | -- cgit v1.2.3 From 24cfbec99647d241c3c31a72d247ee81f9061b5b Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Sat, 20 Jun 2020 02:53:54 +0530 Subject: drm/dp: DRM DP helper for reading Ignore MSA from DPCD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DP sink device sets the Ignore MSA bit in its DP_DOWNSTREAM_PORT_COUNT register to indicate its ability to ignore the MSA video timing parameters and its ability to support seamless video timing change over a range of timing exposed by DisplayID and EDID. This is required for the sink to indicate that it is Adaptive sync capable. v3: * Fi the typo in commit message (Manasi) v2: * Rename to describe what the function does (Jani Nikula) Cc: Jani Nikula Cc: Ville Syrjälä Cc: Harry Wentland Cc: Nicholas Kazlauskas Signed-off-by: Manasi Navare Reviewed-by: Harry Wentland Link: https://patchwork.freedesktop.org/patch/msgid/20200619212356.19285-2-bhanuprakash.modem@intel.com --- include/drm/drm_dp_helper.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index aed08e8cb22c..92b8d326ab4a 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1324,6 +1324,14 @@ drm_dp_alternate_scrambler_reset_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) DP_ALTERNATE_SCRAMBLER_RESET_CAP; } +/* Ignore MSA timing for Adaptive Sync support on DP 1.4 */ +static inline bool +drm_dp_sink_can_do_video_without_timing_msa(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) +{ + return dpcd[DP_DOWN_STREAM_PORT_COUNT] & + DP_MSA_TIMING_PAR_IGNORED; +} + /* * DisplayPort AUX channel */ -- cgit v1.2.3 From b27ff5c187dd18cdc0b78ad5f5a78069d168c860 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 18 Jun 2020 13:46:50 +0000 Subject: drm/panel: otm8009a: Drop unnessary backlight_device_unregister() It's not necessary to unregister backlight device which registered with devm_backlight_device_register(). Fixes: 12a6cbd4f3f1 ("drm/panel: otm8009a: Use new backlight API") Reported-by: Hulk Robot Signed-off-by: Wei Yongjun Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200618134650.44311-1-weiyongjun1@huawei.com --- drivers/gpu/drm/panel/panel-orisetech-otm8009a.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c index 895ee3d1371e..d956522f32ee 100644 --- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c +++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c @@ -479,7 +479,6 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi) if (ret < 0) { dev_err(dev, "mipi_dsi_attach failed. Is host ready?\n"); drm_panel_remove(&ctx->panel); - backlight_device_unregister(ctx->bl_dev); return ret; } -- cgit v1.2.3 From 94f07917ebe86aa660b739cf54e41d4476acde5b Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 18 Jun 2020 01:27:03 +0300 Subject: drm/panel-simple: Add missing connector type for some panels The DRM panel bridge core requires connector type to be set up properly, otherwise it rejects the panel. The missing connector type problem popped up while I was trying to wrap CLAA070WP03XG panel into a DRM bridge in order to test whether panel's rotation property work properly using panel-simple driver on NVIDIA Tegra30 Nexus 7 tablet device, which uses CLAA070WP03XG display panel. The NVIDIA Tegra DRM driver recently gained DRM bridges support for the RGB output and now driver wraps directly-connected panels into DRM bridge. Hence all panels should have connector type set properly now, otherwise the panel's wrapping fails. This patch adds missing connector types for the LVDS panels that are found on NVIDIA Tegra devices: 1. AUO B101AW03 2. Chunghwa CLAA070WP03XG 3. Chunghwa CLAA101WA01A 4. Chunghwa CLAA101WB01 5. EDT ET057090DHU 6. Innolux N156BGE L21 7. Samsung LTN101NT05 Signed-off-by: Dmitry Osipenko Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200617222703.17080-8-digetx@gmail.com --- drivers/gpu/drm/panel/panel-simple.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 6764ac630e22..9eb2dbb7bfa6 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -687,6 +687,7 @@ static const struct panel_desc auo_b101aw03 = { .width = 223, .height = 125, }, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing auo_b101ean01_timing = { @@ -1340,6 +1341,7 @@ static const struct panel_desc chunghwa_claa070wp03xg = { .width = 94, .height = 150, }, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode chunghwa_claa101wa01a_mode = { @@ -1362,6 +1364,7 @@ static const struct panel_desc chunghwa_claa101wa01a = { .width = 220, .height = 120, }, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode chunghwa_claa101wb01_mode = { @@ -1384,6 +1387,7 @@ static const struct panel_desc chunghwa_claa101wb01 = { .width = 223, .height = 125, }, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode dataimage_scf0700c48ggu18_mode = { @@ -1573,6 +1577,7 @@ static const struct panel_desc edt_et057090dhu = { }, .bus_format = MEDIA_BUS_FMT_RGB666_1X18, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode edt_etm0700g0dh6_mode = { @@ -2055,6 +2060,7 @@ static const struct panel_desc innolux_n156bge_l21 = { .width = 344, .height = 193, }, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode innolux_p120zdg_bf1_mode = { @@ -3001,6 +3007,7 @@ static const struct panel_desc samsung_ltn101nt05 = { .width = 223, .height = 125, }, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode samsung_ltn140at29_301_mode = { -- cgit v1.2.3 From 1dd8915291d58f8d89b67b24e5f4b52a0fa633bb Mon Sep 17 00:00:00 2001 From: Ricardo Cañuelo Date: Wed, 17 Jun 2020 11:46:30 +0200 Subject: dt-bindings: display: ti,tfp410.txt: convert to yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the DT binding documentation for the TI TFP410 DPI-to-DVI encoder to json-schema. Signed-off-by: Ricardo Cañuelo Reviewed-by: Laurent Pinchart Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200617094633.19663-2-ricardo.canuelo@collabora.com --- .../bindings/display/bridge/ti,tfp410.txt | 66 ----------- .../bindings/display/bridge/ti,tfp410.yaml | 130 +++++++++++++++++++++ 2 files changed, 130 insertions(+), 66 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt create mode 100644 Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt deleted file mode 100644 index 5ff4f64ef8e8..000000000000 --- a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt +++ /dev/null @@ -1,66 +0,0 @@ -TFP410 DPI to DVI encoder -========================= - -Required properties: -- compatible: "ti,tfp410" - -Optional properties: -- powerdown-gpios: power-down gpio -- reg: I2C address. If and only if present the device node should be placed - into the I2C controller node where the TFP410 I2C is connected to. -- ti,deskew: data de-skew in 350ps increments, from -4 to +3, as configured - through th DK[3:1] pins. This property shall be present only if the TFP410 - is not connected through I2C. - -Required nodes: - -This device has two video ports. Their connections are modeled using the OF -graph bindings specified in [1]. Each port node shall have a single endpoint. - -- Port 0 is the DPI input port. Its endpoint subnode shall contain a - pclk-sample and bus-width property and a remote-endpoint property as specified - in [1]. - - If pclk-sample is not defined, pclk-sample = 0 should be assumed for - backward compatibility. - - If bus-width is not defined then bus-width = 24 should be assumed for - backward compatibility. - bus-width = 24: 24 data lines are connected and single-edge mode - bus-width = 12: 12 data lines are connected and dual-edge mode - -- Port 1 is the DVI output port. Its endpoint subnode shall contain a - remote-endpoint property is specified in [1]. - -[1] Documentation/devicetree/bindings/media/video-interfaces.txt - - -Example -------- - -tfp410: encoder@0 { - compatible = "ti,tfp410"; - powerdown-gpios = <&twl_gpio 2 GPIO_ACTIVE_LOW>; - ti,deskew = <4>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - tfp410_in: endpoint@0 { - pclk-sample = <1>; - bus-width = <24>; - remote-endpoint = <&dpi_out>; - }; - }; - - port@1 { - reg = <1>; - - tfp410_out: endpoint@0 { - remote-endpoint = <&dvi_connector_in>; - }; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml new file mode 100644 index 000000000000..5569a4907765 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml @@ -0,0 +1,130 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/ti,tfp410.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TFP410 DPI to DVI encoder + +maintainers: + - Tomi Valkeinen + - Jyri Sarha + +properties: + compatible: + const: ti,tfp410 + + reg: + description: I2C address of the device. + maxItems: 1 + + powerdown-gpios: + maxItems: 1 + + ti,deskew: + description: + Data de-skew in 350ps increments, from -4 to +3, as configured + through th DK[3:1] pins. This property shall be present only if the TFP410 + is not connected through I2C. + maxItems: 1 + $ref: /schemas/types.yaml#/definitions/uint32 + + ports: + description: + A node containing input and output port nodes with endpoint + definitions as documented in + Documentation/devicetree/bindings/media/video-interfaces.txt + type: object + + properties: + port@0: + description: DPI input port. + type: object + + properties: + reg: + const: 0 + + endpoint: + type: object + + properties: + pclk-sample: + description: + Endpoint sampling edge. + enum: + - 0 # Falling edge + - 1 # Rising edge + default: 0 + + bus-width: + description: + Endpoint bus width. + enum: + - 12 # 12 data lines connected and dual-edge mode + - 24 # 24 data lines connected and single-edge mode + default: 24 + + port@1: + description: DVI output port. + type: object + + properties: + reg: + const: 1 + + endpoint: + type: object + + required: + - port@0 + - port@1 + +required: + - compatible + - ports + +if: + required: + - reg +then: + properties: + ti,deskew: false +else: + required: + - ti,deskew + +additionalProperties: false + +examples: + - | + #include + + tfp410: encoder { + compatible = "ti,tfp410"; + powerdown-gpios = <&twl_gpio 2 GPIO_ACTIVE_LOW>; + ti,deskew = <3>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + tfp410_in: endpoint { + pclk-sample = <1>; + bus-width = <24>; + remote-endpoint = <&dpi_out>; + }; + }; + + port@1 { + reg = <1>; + tfp410_out: endpoint { + remote-endpoint = <&dvi_connector_in>; + }; + }; + }; + }; + +... -- cgit v1.2.3 From 520a994de09ea2f2d6d93919e6b6e0d2864c52b9 Mon Sep 17 00:00:00 2001 From: Ricardo Cañuelo Date: Wed, 17 Jun 2020 11:46:31 +0200 Subject: dt-bindings: display: ti, tfp410.yaml: Redefine ti, deskew property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes how the 'ti,deskew' property is defined. It's now an unsigned value from 0 to 7 instead of a signed value from -4 to 3. Until the dtc carries the integer sign through to the yaml output it's easier to define signed types as unsigned. Signed-off-by: Ricardo Cañuelo Reviewed-by: Laurent Pinchart Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200617094633.19663-3-ricardo.canuelo@collabora.com --- Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml index 5569a4907765..605831c1e836 100644 --- a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml +++ b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.yaml @@ -23,11 +23,12 @@ properties: ti,deskew: description: - Data de-skew in 350ps increments, from -4 to +3, as configured - through th DK[3:1] pins. This property shall be present only if the TFP410 - is not connected through I2C. - maxItems: 1 + Data de-skew value in 350ps increments, from 0 to 7, as configured + through the DK[3:1] pins. The de-skew multiplier is computed as + (DK[3:1] - 4), so it ranges from -4 to 3. $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 7 ports: description: -- cgit v1.2.3 From db8f92a5e627ffb11ff2d9f35cf54442f5771a49 Mon Sep 17 00:00:00 2001 From: Ricardo Cañuelo Date: Wed, 17 Jun 2020 11:46:32 +0200 Subject: drm/bridge: tfp410: fix de-skew value retrieval from DT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tfp410 has a data de-skew feature that allows the user to compensate the skew between IDCK and the pixel data and control signals. In the driver, the setup and hold times are calculated from the de-skew value. This retrieves the deskew value from the DT using the proper datatype and range check as described by the binding (u32 from 0 to 7). This fix results from a change in the ti,tfp410 DT binding. Signed-off-by: Ricardo Cañuelo Reviewed-by: Laurent Pinchart Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200617094633.19663-4-ricardo.canuelo@collabora.com --- drivers/gpu/drm/bridge/ti-tfp410.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c index e3eb6364c0f7..dfde811f3411 100644 --- a/drivers/gpu/drm/bridge/ti-tfp410.c +++ b/drivers/gpu/drm/bridge/ti-tfp410.c @@ -220,7 +220,7 @@ static int tfp410_parse_timings(struct tfp410 *dvi, bool i2c) struct device_node *ep; u32 pclk_sample = 0; u32 bus_width = 24; - s32 deskew = 0; + u32 deskew = 0; /* Start with defaults. */ *timings = tfp410_default_timings; @@ -274,12 +274,12 @@ static int tfp410_parse_timings(struct tfp410 *dvi, bool i2c) } /* Get the setup and hold time from vendor-specific properties. */ - of_property_read_u32(dvi->dev->of_node, "ti,deskew", (u32 *)&deskew); - if (deskew < -4 || deskew > 3) + of_property_read_u32(dvi->dev->of_node, "ti,deskew", &deskew); + if (deskew > 7) return -EINVAL; - timings->setup_time_ps = min(0, 1200 - 350 * deskew); - timings->hold_time_ps = min(0, 1300 + 350 * deskew); + timings->setup_time_ps = min(0, 1200 - 350 * ((s32)deskew - 4)); + timings->hold_time_ps = min(0, 1300 + 350 * ((s32)deskew - 4)); return 0; } -- cgit v1.2.3 From b9fe86204b06655204534ac5e0562d6a3e503b16 Mon Sep 17 00:00:00 2001 From: Ricardo Cañuelo Date: Wed, 17 Jun 2020 11:46:33 +0200 Subject: drm/bridge: tfp410: Fix setup and hold time calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a bug in the calculation of the setup and hold times based on the deskew configuration. Signed-off-by: Ricardo Cañuelo Reviewed-by: Laurent Pinchart Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200617094633.19663-5-ricardo.canuelo@collabora.com --- drivers/gpu/drm/bridge/ti-tfp410.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c index dfde811f3411..21d99b4ea0c9 100644 --- a/drivers/gpu/drm/bridge/ti-tfp410.c +++ b/drivers/gpu/drm/bridge/ti-tfp410.c @@ -278,8 +278,8 @@ static int tfp410_parse_timings(struct tfp410 *dvi, bool i2c) if (deskew > 7) return -EINVAL; - timings->setup_time_ps = min(0, 1200 - 350 * ((s32)deskew - 4)); - timings->hold_time_ps = min(0, 1300 + 350 * ((s32)deskew - 4)); + timings->setup_time_ps = 1200 - 350 * ((s32)deskew - 4); + timings->hold_time_ps = max(0, 1300 + 350 * ((s32)deskew - 4)); return 0; } -- cgit v1.2.3 From 290855d538dc6a800e1b47c8e12a2e8cc810caa2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 12 Jun 2020 09:22:16 +0200 Subject: dt-bindings: display: simple: add CDTech S070PWS19HP-FC21 and S070SWV29HG-DC44 Add the CDTech Electronics displays S070PWS19HP-FC21 (7.0" WSVGA) and S070SWV29HG-DC44 (7.0" WVGA) to the panel-simple compatible list. Signed-off-by: Matthias Schiffer Reviewed-by: Rob Herring Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200612072219.13669-2-matthias.schiffer@ew.tq-group.com --- Documentation/devicetree/bindings/display/panel/panel-simple.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 31e3efc73e00..2ddb520edc6d 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -81,6 +81,10 @@ properties: - boe,nv140fhmn49 # CDTech(H.K.) Electronics Limited 4.3" 480x272 color TFT-LCD panel - cdtech,s043wq26h-ct7 + # CDTech(H.K.) Electronics Limited 7" WSVGA (1024x600) TFT LCD Panel + - cdtech,s070pws19hp-fc21 + # CDTech(H.K.) Electronics Limited 7" WVGA (800x480) TFT LCD Panel + - cdtech,s070swv29hg-dc44 # CDTech(H.K.) Electronics Limited 7" 800x480 color TFT-LCD panel - cdtech,s070wv95-ct16 # Chunghwa Picture Tubes Ltd. 7" WXGA TFT LCD panel -- cgit v1.2.3 From ac4a36ee277d2930d202d418077b98acb143ed87 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 12 Jun 2020 09:22:17 +0200 Subject: dt-bindings: display: simple: add Tianma TM070JVHG33 Add the Tianma Micro-electronics TM070JVHG33 7.0" WXGA display to the panel-simple compatible list. Signed-off-by: Matthias Schiffer Reviewed-by: Rob Herring Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200612072219.13669-3-matthias.schiffer@ew.tq-group.com --- Documentation/devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 2ddb520edc6d..6deeeed59e59 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -251,6 +251,8 @@ properties: - starry,kr122ea0sra # Tianma Micro-electronics TM070JDHG30 7.0" WXGA TFT LCD panel - tianma,tm070jdhg30 + # Tianma Micro-electronics TM070JVHG33 7.0" WXGA TFT LCD panel + - tianma,tm070jvhg33 # Tianma Micro-electronics TM070RVHG71 7.0" WXGA TFT LCD panel - tianma,tm070rvhg71 # Toshiba 8.9" WXGA (1280x768) TFT LCD panel -- cgit v1.2.3 From 0e3b67f6d7e6c1bc34a0ed1f43d0d95577ae5b09 Mon Sep 17 00:00:00 2001 From: Michael Krummsdorf Date: Fri, 12 Jun 2020 09:22:18 +0200 Subject: drm/panel: simple: add CDTech S070PWS19HP-FC21 and S070SWV29HG-DC44 Add support for the CDTech Electronics displays S070PWS19HP-FC21 (7.0" WSVGA) and S070SWV29HG-DC44 (7.0" WVGA) to panel-simple. Signed-off-by: Michael Krummsdorf Signed-off-by: Matthias Schiffer Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200612072219.13669-4-matthias.schiffer@ew.tq-group.com --- drivers/gpu/drm/panel/panel-simple.c | 60 ++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 9eb2dbb7bfa6..5b2beff9f977 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1297,6 +1297,60 @@ static const struct panel_desc cdtech_s043wq26h_ct7 = { .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, }; +/* S070PWS19HP-FC21 2017/04/22 */ +static const struct drm_display_mode cdtech_s070pws19hp_fc21_mode = { + .clock = 51200, + .hdisplay = 1024, + .hsync_start = 1024 + 160, + .hsync_end = 1024 + 160 + 20, + .htotal = 1024 + 160 + 20 + 140, + .vdisplay = 600, + .vsync_start = 600 + 12, + .vsync_end = 600 + 12 + 3, + .vtotal = 600 + 12 + 3 + 20, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, +}; + +static const struct panel_desc cdtech_s070pws19hp_fc21 = { + .modes = &cdtech_s070pws19hp_fc21_mode, + .num_modes = 1, + .bpc = 6, + .size = { + .width = 154, + .height = 86, + }, + .bus_format = MEDIA_BUS_FMT_RGB666_1X18, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE, + .connector_type = DRM_MODE_CONNECTOR_DPI, +}; + +/* S070SWV29HG-DC44 2017/09/21 */ +static const struct drm_display_mode cdtech_s070swv29hg_dc44_mode = { + .clock = 33300, + .hdisplay = 800, + .hsync_start = 800 + 210, + .hsync_end = 800 + 210 + 2, + .htotal = 800 + 210 + 2 + 44, + .vdisplay = 480, + .vsync_start = 480 + 22, + .vsync_end = 480 + 22 + 2, + .vtotal = 480 + 22 + 2 + 21, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, +}; + +static const struct panel_desc cdtech_s070swv29hg_dc44 = { + .modes = &cdtech_s070swv29hg_dc44_mode, + .num_modes = 1, + .bpc = 6, + .size = { + .width = 154, + .height = 86, + }, + .bus_format = MEDIA_BUS_FMT_RGB666_1X18, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE, + .connector_type = DRM_MODE_CONNECTOR_DPI, +}; + static const struct drm_display_mode cdtech_s070wv95_ct16_mode = { .clock = 35000, .hdisplay = 800, @@ -3681,6 +3735,12 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "cdtech,s043wq26h-ct7", .data = &cdtech_s043wq26h_ct7, + }, { + .compatible = "cdtech,s070pws19hp-fc21", + .data = &cdtech_s070pws19hp_fc21, + }, { + .compatible = "cdtech,s070swv29hg-dc44", + .data = &cdtech_s070swv29hg_dc44, }, { .compatible = "cdtech,s070wv95-ct16", .data = &cdtech_s070wv95_ct16, -- cgit v1.2.3 From b3bfcdf8a3b623aee3fc40a3e6b17d8ec1f14b50 Mon Sep 17 00:00:00 2001 From: Max Merchel Date: Fri, 12 Jun 2020 09:22:19 +0200 Subject: drm/panel: simple: add Tianma TM070JVHG33 Add support for the Tianma Micro-electronics TM070JVHG33 7.0" WXGA display to panel-simple. Signed-off-by: Max Merchel Signed-off-by: Matthias Schiffer Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200612072219.13669-5-matthias.schiffer@ew.tq-group.com --- drivers/gpu/drm/panel/panel-simple.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 5b2beff9f977..95eb2122a767 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -3387,6 +3387,18 @@ static const struct panel_desc tianma_tm070jdhg30 = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; +static const struct panel_desc tianma_tm070jvhg33 = { + .timings = &tianma_tm070jdhg30_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 150, + .height = 94, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct display_timing tianma_tm070rvhg71_timing = { .pixelclock = { 27700000, 29200000, 39600000 }, .hactive = { 800, 800, 800 }, @@ -3990,6 +4002,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "tianma,tm070jdhg30", .data = &tianma_tm070jdhg30, + }, { + .compatible = "tianma,tm070jvhg33", + .data = &tianma_tm070jvhg33, }, { .compatible = "tianma,tm070rvhg71", .data = &tianma_tm070rvhg71, -- cgit v1.2.3 From 05f13f5b5996d20a9819e0c6fd0cda4956c8aff9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 17 Jun 2020 10:03:37 +0200 Subject: drm/ast: Remove unused code paths for AST 1180 The ast driver contains code paths for AST 1180 chips. The chip is not supported and the rsp code has never been tested. Simplify the driver by removing the AST 1180 code. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Reviewed-by: Emil Velikov Link: https://patchwork.freedesktop.org/patch/msgid/20200617080340.29584-2-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.c | 1 - drivers/gpu/drm/ast/ast_drv.h | 2 - drivers/gpu/drm/ast/ast_main.c | 89 ++++++++++++++++++------------------------ drivers/gpu/drm/ast/ast_mode.c | 10 +---- drivers/gpu/drm/ast/ast_post.c | 10 ++--- 5 files changed, 43 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 48a9cc4e080a..f7a14e4e1df0 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -59,7 +59,6 @@ static struct drm_driver driver; static const struct pci_device_id pciidlist[] = { AST_VGA_DEVICE(PCI_CHIP_AST2000, NULL), AST_VGA_DEVICE(PCI_CHIP_AST2100, NULL), - /* AST_VGA_DEVICE(PCI_CHIP_AST1180, NULL), - don't bind to 1180 for now */ {0, 0, 0}, }; diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 656d591b154b..09f2659e2911 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -52,7 +52,6 @@ #define PCI_CHIP_AST2000 0x2000 #define PCI_CHIP_AST2100 0x2010 -#define PCI_CHIP_AST1180 0x1180 enum ast_chip { @@ -64,7 +63,6 @@ enum ast_chip { AST2300, AST2400, AST2500, - AST1180, }; enum ast_tx_chip { diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 1b35728ad871..3e64e7c8d325 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -142,50 +142,42 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) ast_detect_config_mode(dev, &scu_rev); /* Identify chipset */ - if (dev->pdev->device == PCI_CHIP_AST1180) { - ast->chip = AST1100; - DRM_INFO("AST 1180 detected\n"); - } else { - if (dev->pdev->revision >= 0x40) { - ast->chip = AST2500; - DRM_INFO("AST 2500 detected\n"); - } else if (dev->pdev->revision >= 0x30) { - ast->chip = AST2400; - DRM_INFO("AST 2400 detected\n"); - } else if (dev->pdev->revision >= 0x20) { - ast->chip = AST2300; - DRM_INFO("AST 2300 detected\n"); - } else if (dev->pdev->revision >= 0x10) { - switch (scu_rev & 0x0300) { - case 0x0200: - ast->chip = AST1100; - DRM_INFO("AST 1100 detected\n"); - break; - case 0x0100: - ast->chip = AST2200; - DRM_INFO("AST 2200 detected\n"); - break; - case 0x0000: - ast->chip = AST2150; - DRM_INFO("AST 2150 detected\n"); - break; - default: - ast->chip = AST2100; - DRM_INFO("AST 2100 detected\n"); - break; - } - ast->vga2_clone = false; - } else { - ast->chip = AST2000; - DRM_INFO("AST 2000 detected\n"); + if (dev->pdev->revision >= 0x40) { + ast->chip = AST2500; + DRM_INFO("AST 2500 detected\n"); + } else if (dev->pdev->revision >= 0x30) { + ast->chip = AST2400; + DRM_INFO("AST 2400 detected\n"); + } else if (dev->pdev->revision >= 0x20) { + ast->chip = AST2300; + DRM_INFO("AST 2300 detected\n"); + } else if (dev->pdev->revision >= 0x10) { + switch (scu_rev & 0x0300) { + case 0x0200: + ast->chip = AST1100; + DRM_INFO("AST 1100 detected\n"); + break; + case 0x0100: + ast->chip = AST2200; + DRM_INFO("AST 2200 detected\n"); + break; + case 0x0000: + ast->chip = AST2150; + DRM_INFO("AST 2150 detected\n"); + break; + default: + ast->chip = AST2100; + DRM_INFO("AST 2100 detected\n"); + break; } + ast->vga2_clone = false; + } else { + ast->chip = AST2000; + DRM_INFO("AST 2000 detected\n"); } /* Check if we support wide screen */ switch (ast->chip) { - case AST1180: - ast->support_wide_screen = true; - break; case AST2000: ast->support_wide_screen = false; break; @@ -469,15 +461,13 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) if (need_post) ast_post_gpu(dev); - if (ast->chip != AST1180) { - ret = ast_get_dram_info(dev); - if (ret) - goto out_free; - ast->vram_size = ast_get_vram_info(dev); - DRM_INFO("dram MCLK=%u Mhz type=%d bus_width=%d size=%08x\n", - ast->mclk, ast->dram_type, - ast->dram_bus_width, ast->vram_size); - } + ret = ast_get_dram_info(dev); + if (ret) + goto out_free; + ast->vram_size = ast_get_vram_info(dev); + DRM_INFO("dram MCLK=%u Mhz type=%d bus_width=%d size=%08x\n", + ast->mclk, ast->dram_type, + ast->dram_bus_width, ast->vram_size); ret = ast_mm_init(ast); if (ret) @@ -496,8 +486,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) ast->chip == AST2200 || ast->chip == AST2300 || ast->chip == AST2400 || - ast->chip == AST2500 || - ast->chip == AST1180) { + ast->chip == AST2500) { dev->mode_config.max_width = 1920; dev->mode_config.max_height = 2048; } else { diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 7d39b858c9f1..be0e2250708f 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -768,9 +768,6 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) { struct ast_private *ast = crtc->dev->dev_private; - if (ast->chip == AST1180) - return; - /* TODO: Maybe control display signal generation with * Sync Enable (bit CR17.7). */ @@ -797,11 +794,6 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, const struct drm_format_info *format; bool succ; - if (ast->chip == AST1180) { - DRM_ERROR("AST 1180 modesetting not supported\n"); - return -EINVAL; - } - if (!state->enable) return 0; /* no mode checks if CRTC is being disabled */ @@ -1043,7 +1035,7 @@ static enum drm_mode_status ast_mode_valid(struct drm_connector *connector, if ((ast->chip == AST2100) || (ast->chip == AST2200) || (ast->chip == AST2300) || (ast->chip == AST2400) || - (ast->chip == AST2500) || (ast->chip == AST1180)) { + (ast->chip == AST2500)) { if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080)) return MODE_OK; diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 2d1b18619743..af0c8ebb009a 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -58,13 +58,9 @@ bool ast_is_vga_enabled(struct drm_device *dev) struct ast_private *ast = dev->dev_private; u8 ch; - if (ast->chip == AST1180) { - /* TODO 1180 */ - } else { - ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); - return !!(ch & 0x01); - } - return false; + ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); + + return !!(ch & 0x01); } static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff }; -- cgit v1.2.3 From 5534bc8f184020ace49b1dfdcdc07ad6555968ac Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 17 Jun 2020 10:03:38 +0200 Subject: drm/ast: Remove test for device from ast_pm_freeze() The driver cannot suspend before it has loaded completely. So the test for device pointers is not required. Remove it. v3: * s/them/it/ in commit message Signed-off-by: Thomas Zimmermann Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200617080340.29584-3-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index f7a14e4e1df0..0b58f7aee6b0 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -188,9 +188,6 @@ static int ast_pm_freeze(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *ddev = pci_get_drvdata(pdev); - - if (!ddev || !ddev->dev_private) - return -ENODEV; return ast_drm_freeze(ddev); } -- cgit v1.2.3 From fa7dbd7688849d1d4d3c69da57a1dce7c24b1e45 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 17 Jun 2020 10:03:39 +0200 Subject: drm/ast: Upcast from DRM device to ast structure via to_ast_private() All upcasting from struct drm_device to struct ast_private is now performed via to_ast_private(). Using struct drm_device.dev_private is deprecated. The ast variable in ast_crtc_helper_atomic_check() is unused, so removed it. v2: * fix typo in commit message Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Reviewed-by: Emil Velikov Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200617080340.29584-4-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp501.c | 24 ++++++++++++------------ drivers/gpu/drm/ast/ast_drv.h | 5 +++++ drivers/gpu/drm/ast/ast_main.c | 10 +++++----- drivers/gpu/drm/ast/ast_mode.c | 41 ++++++++++++++++++++--------------------- drivers/gpu/drm/ast/ast_post.c | 16 ++++++++-------- 5 files changed, 50 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index 98cd69269263..4b85a504825a 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -10,7 +10,7 @@ MODULE_FIRMWARE("ast_dp501_fw.bin"); static int ast_load_dp501_microcode(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); return request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev); } @@ -93,7 +93,7 @@ static bool wait_fw_ready(struct ast_private *ast) static bool ast_write_cmd(struct drm_device *dev, u8 data) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); int retry = 0; if (wait_nack(ast)) { send_nack(ast); @@ -115,7 +115,7 @@ static bool ast_write_cmd(struct drm_device *dev, u8 data) static bool ast_write_data(struct drm_device *dev, u8 data) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); if (wait_nack(ast)) { send_nack(ast); @@ -133,7 +133,7 @@ static bool ast_write_data(struct drm_device *dev, u8 data) #if 0 static bool ast_read_data(struct drm_device *dev, u8 *data) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u8 tmp; *data = 0; @@ -172,7 +172,7 @@ static u32 get_fw_base(struct ast_private *ast) bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u32 i, data; u32 boot_address; @@ -188,7 +188,7 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size) static bool ast_launch_m68k(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u32 i, data, len = 0; u32 boot_address; u8 *fw_addr = NULL; @@ -255,7 +255,7 @@ static bool ast_launch_m68k(struct drm_device *dev) u8 ast_get_dp501_max_clk(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u32 boot_address, offset, data; u8 linkcap[4], linkrate, linklanes, maxclk = 0xff; @@ -283,7 +283,7 @@ u8 ast_get_dp501_max_clk(struct drm_device *dev) bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u32 i, boot_address, offset, data; boot_address = get_fw_base(ast); @@ -312,7 +312,7 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata) static bool ast_init_dvo(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u8 jreg; u32 data; ast_write32(ast, 0xf004, 0x1e6e0000); @@ -385,7 +385,7 @@ static bool ast_init_dvo(struct drm_device *dev) static void ast_init_analog(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u32 data; /* @@ -412,7 +412,7 @@ static void ast_init_analog(struct drm_device *dev) void ast_init_3rdtx(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u8 jreg; if (ast->chip == AST2300 || ast->chip == AST2400) { @@ -438,7 +438,7 @@ void ast_init_3rdtx(struct drm_device *dev) void ast_release_firmware(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); release_firmware(ast->dp501_fw); ast->dp501_fw = NULL; diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 09f2659e2911..c44c1376c697 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -136,6 +136,11 @@ struct ast_private { const struct firmware *dp501_fw; /* dp501 fw */ }; +static inline struct ast_private *to_ast_private(struct drm_device *dev) +{ + return dev->dev_private; +} + int ast_driver_load(struct drm_device *dev, unsigned long flags); void ast_driver_unload(struct drm_device *dev); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 3e64e7c8d325..3edfc6c92b9a 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -67,7 +67,7 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast, static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) { struct device_node *np = dev->pdev->dev.of_node; - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); uint32_t data, jregd0, jregd1; /* Defaults */ @@ -117,7 +117,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) static int ast_detect_chip(struct drm_device *dev, bool *need_post) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); uint32_t jreg, scu_rev; /* @@ -262,7 +262,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) static int ast_get_dram_info(struct drm_device *dev) { struct device_node *np = dev->pdev->dev.of_node; - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap; uint32_t denum, num, div, ref_pll, dsel; @@ -388,7 +388,7 @@ static const struct drm_mode_config_funcs ast_mode_funcs = { static u32 ast_get_vram_info(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u8 jreg; u32 vram_size; ast_open_key(ast); @@ -509,7 +509,7 @@ out_free: void ast_driver_unload(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); /* enable standard VGA decode */ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04); diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index be0e2250708f..10211751182d 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -565,7 +565,7 @@ static void ast_primary_plane_helper_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct ast_private *ast = plane->dev->dev_private; + struct ast_private *ast = to_ast_private(plane->dev); struct drm_plane_state *state = plane->state; struct drm_gem_vram_object *gbo; s64 gpu_addr; @@ -585,7 +585,7 @@ static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct ast_private *ast = plane->dev->dev_private; + struct ast_private *ast = to_ast_private(plane->dev); ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20); } @@ -633,7 +633,7 @@ ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, WARN_ON_ONCE(fb->height > AST_MAX_HWC_HEIGHT)) return -EINVAL; /* BUG: didn't test in atomic_check() */ - ast = crtc->dev->dev_private; + ast = to_ast_private(crtc->dev); gbo = drm_gem_vram_of_gem(fb->obj[0]); src = drm_gem_vram_vmap(gbo); @@ -705,7 +705,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, struct drm_plane_state *state = plane->state; struct drm_crtc *crtc = state->crtc; struct drm_framebuffer *fb = state->fb; - struct ast_private *ast = plane->dev->dev_private; + struct ast_private *ast = to_ast_private(plane->dev); struct ast_crtc *ast_crtc = to_ast_crtc(crtc); struct drm_gem_vram_object *gbo; s64 off; @@ -738,7 +738,7 @@ static void ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct ast_private *ast = plane->dev->dev_private; + struct ast_private *ast = to_ast_private(plane->dev); ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, 0xfc, 0x00); } @@ -766,7 +766,7 @@ static const struct drm_plane_funcs ast_cursor_plane_funcs = { static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) { - struct ast_private *ast = crtc->dev->dev_private; + struct ast_private *ast = to_ast_private(crtc->dev); /* TODO: Maybe control display signal generation with * Sync Enable (bit CR17.7). @@ -789,7 +789,6 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { - struct ast_private *ast = crtc->dev->dev_private; struct ast_crtc_state *ast_state; const struct drm_format_info *format; bool succ; @@ -815,7 +814,7 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, static void ast_crtc_helper_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { - struct ast_private *ast = crtc->dev->dev_private; + struct ast_private *ast = to_ast_private(crtc->dev); ast_open_key(ast); } @@ -824,7 +823,7 @@ static void ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { struct drm_device *dev = crtc->dev; - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); struct ast_crtc_state *ast_state; const struct drm_format_info *format; struct ast_vbios_mode_info *vbios_mode_info; @@ -937,7 +936,7 @@ static const struct drm_crtc_funcs ast_crtc_funcs = { static int ast_crtc_init(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); struct ast_crtc *crtc; int ret; @@ -966,7 +965,7 @@ err_kfree: static int ast_encoder_init(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); struct drm_encoder *encoder = &ast->encoder; int ret; @@ -986,7 +985,7 @@ static int ast_encoder_init(struct drm_device *dev) static int ast_get_modes(struct drm_connector *connector) { struct ast_connector *ast_connector = to_ast_connector(connector); - struct ast_private *ast = connector->dev->dev_private; + struct ast_private *ast = to_ast_private(connector->dev); struct edid *edid; int ret; bool flags = false; @@ -1017,7 +1016,7 @@ static int ast_get_modes(struct drm_connector *connector) static enum drm_mode_status ast_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct ast_private *ast = connector->dev->dev_private; + struct ast_private *ast = to_ast_private(connector->dev); int flags = MODE_NOMODE; uint32_t jtemp; @@ -1128,7 +1127,7 @@ static int ast_connector_init(struct drm_device *dev) /* allocate cursor cache and pin at start of VRAM */ static int ast_cursor_init(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); size_t size, i; struct drm_gem_vram_object *gbo; int ret; @@ -1166,7 +1165,7 @@ err_drm_gem_vram_put: static void ast_cursor_fini(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); size_t i; struct drm_gem_vram_object *gbo; @@ -1179,7 +1178,7 @@ static void ast_cursor_fini(struct drm_device *dev) int ast_mode_init(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); int ret; memset(&ast->primary_plane, 0, sizeof(ast->primary_plane)); @@ -1223,7 +1222,7 @@ void ast_mode_fini(struct drm_device *dev) static int get_clock(void *i2c_priv) { struct ast_i2c_chan *i2c = i2c_priv; - struct ast_private *ast = i2c->dev->dev_private; + struct ast_private *ast = to_ast_private(i2c->dev); uint32_t val, val2, count, pass; count = 0; @@ -1245,7 +1244,7 @@ static int get_clock(void *i2c_priv) static int get_data(void *i2c_priv) { struct ast_i2c_chan *i2c = i2c_priv; - struct ast_private *ast = i2c->dev->dev_private; + struct ast_private *ast = to_ast_private(i2c->dev); uint32_t val, val2, count, pass; count = 0; @@ -1267,7 +1266,7 @@ static int get_data(void *i2c_priv) static void set_clock(void *i2c_priv, int clock) { struct ast_i2c_chan *i2c = i2c_priv; - struct ast_private *ast = i2c->dev->dev_private; + struct ast_private *ast = to_ast_private(i2c->dev); int i; u8 ujcrb7, jtemp; @@ -1283,7 +1282,7 @@ static void set_clock(void *i2c_priv, int clock) static void set_data(void *i2c_priv, int data) { struct ast_i2c_chan *i2c = i2c_priv; - struct ast_private *ast = i2c->dev->dev_private; + struct ast_private *ast = to_ast_private(i2c->dev); int i; u8 ujcrb7, jtemp; @@ -1431,7 +1430,7 @@ static int ast_cursor_move(struct drm_crtc *crtc, int x, int y) { struct ast_crtc *ast_crtc = to_ast_crtc(crtc); - struct ast_private *ast = crtc->dev->dev_private; + struct ast_private *ast = to_ast_private(crtc->dev); struct drm_gem_vram_object *gbo; int x_offset, y_offset; u8 *dst, *sig; diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index af0c8ebb009a..226e1290227a 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -39,7 +39,7 @@ static void ast_post_chip_2500(struct drm_device *dev); void ast_enable_vga(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01); ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01); @@ -47,7 +47,7 @@ void ast_enable_vga(struct drm_device *dev) void ast_enable_mmio(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); } @@ -55,7 +55,7 @@ void ast_enable_mmio(struct drm_device *dev) bool ast_is_vga_enabled(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u8 ch; ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); @@ -70,7 +70,7 @@ static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff }; static void ast_set_def_ext_reg(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u8 i, index, reg; const u8 *ext_reg_info; @@ -272,7 +272,7 @@ cbr_start: static void ast_init_dram_reg(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u8 j; u32 data, temp, i; const struct ast_dramstruct *dram_reg_info; @@ -366,7 +366,7 @@ static void ast_init_dram_reg(struct drm_device *dev) void ast_post_gpu(struct drm_device *dev) { u32 reg; - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); pci_read_config_dword(ast->dev->pdev, 0x04, ®); reg |= 0x3; @@ -1596,7 +1596,7 @@ ddr2_init_start: static void ast_post_chip_2300(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); struct ast2300_dram_param param; u32 temp; u8 reg; @@ -2028,7 +2028,7 @@ static bool ast_dram_init_2500(struct ast_private *ast) void ast_post_chip_2500(struct drm_device *dev) { - struct ast_private *ast = dev->dev_private; + struct ast_private *ast = to_ast_private(dev); u32 temp; u8 reg; -- cgit v1.2.3 From 1a19b4cb162253fb6a3edbe80d954d066189dcee Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 17 Jun 2020 10:03:40 +0200 Subject: drm/ast: Use per-device logging macros Converts the ast driver to drm_info(), drm_err() and drm_WARN_*(). No functional changes are made. v2: * also convert WARN_*() macros Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Reviewed-by: Emil Velikov Link: https://patchwork.freedesktop.org/patch/msgid/20200617080340.29584-5-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_main.c | 34 +++++++++++++++++----------------- drivers/gpu/drm/ast/ast_mode.c | 26 +++++++++++++++----------- drivers/gpu/drm/ast/ast_post.c | 2 +- drivers/gpu/drm/ast/ast_ttm.c | 2 +- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 3edfc6c92b9a..2eab19a9056f 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -79,7 +79,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) scu_rev)) { /* We do, disable P2A access */ ast->config_mode = ast_use_dt; - DRM_INFO("Using device-tree for configuration\n"); + drm_info(dev, "Using device-tree for configuration\n"); return; } @@ -101,7 +101,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) /* P2A works, grab silicon revision */ ast->config_mode = ast_use_p2a; - DRM_INFO("Using P2A bridge for configuration\n"); + drm_info(dev, "Using P2A bridge for configuration\n"); /* Read SCU7c (silicon revision register) */ ast_write32(ast, 0xf004, 0x1e6e0000); @@ -112,7 +112,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) } /* We have a P2A bridge but it's disabled */ - DRM_INFO("P2A bridge disabled, using default configuration\n"); + drm_info(dev, "P2A bridge disabled, using default configuration\n"); } static int ast_detect_chip(struct drm_device *dev, bool *need_post) @@ -128,7 +128,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) */ if (!ast_is_vga_enabled(dev)) { ast_enable_vga(dev); - DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); + drm_info(dev, "VGA not enabled on entry, requesting chip POST\n"); *need_post = true; } else *need_post = false; @@ -144,36 +144,36 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) /* Identify chipset */ if (dev->pdev->revision >= 0x40) { ast->chip = AST2500; - DRM_INFO("AST 2500 detected\n"); + drm_info(dev, "AST 2500 detected\n"); } else if (dev->pdev->revision >= 0x30) { ast->chip = AST2400; - DRM_INFO("AST 2400 detected\n"); + drm_info(dev, "AST 2400 detected\n"); } else if (dev->pdev->revision >= 0x20) { ast->chip = AST2300; - DRM_INFO("AST 2300 detected\n"); + drm_info(dev, "AST 2300 detected\n"); } else if (dev->pdev->revision >= 0x10) { switch (scu_rev & 0x0300) { case 0x0200: ast->chip = AST1100; - DRM_INFO("AST 1100 detected\n"); + drm_info(dev, "AST 1100 detected\n"); break; case 0x0100: ast->chip = AST2200; - DRM_INFO("AST 2200 detected\n"); + drm_info(dev, "AST 2200 detected\n"); break; case 0x0000: ast->chip = AST2150; - DRM_INFO("AST 2150 detected\n"); + drm_info(dev, "AST 2150 detected\n"); break; default: ast->chip = AST2100; - DRM_INFO("AST 2100 detected\n"); + drm_info(dev, "AST 2100 detected\n"); break; } ast->vga2_clone = false; } else { ast->chip = AST2000; - DRM_INFO("AST 2000 detected\n"); + drm_info(dev, "AST 2000 detected\n"); } /* Check if we support wide screen */ @@ -248,13 +248,13 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) /* Print stuff for diagnostic purposes */ switch(ast->tx_chip_type) { case AST_TX_SIL164: - DRM_INFO("Using Sil164 TMDS transmitter\n"); + drm_info(dev, "Using Sil164 TMDS transmitter\n"); break; case AST_TX_DP501: - DRM_INFO("Using DP501 DisplayPort transmitter\n"); + drm_info(dev, "Using DP501 DisplayPort transmitter\n"); break; default: - DRM_INFO("Analog VGA only\n"); + drm_info(dev, "Analog VGA only\n"); } return 0; } @@ -443,7 +443,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) * and higher). */ if (!(pci_resource_flags(dev->pdev, 2) & IORESOURCE_IO)) { - DRM_INFO("platform has no IO space, trying MMIO\n"); + drm_info(dev, "platform has no IO space, trying MMIO\n"); ast->ioregs = ast->regs + AST_IO_MM_OFFSET; } @@ -465,7 +465,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) if (ret) goto out_free; ast->vram_size = ast_get_vram_info(dev); - DRM_INFO("dram MCLK=%u Mhz type=%d bus_width=%d size=%08x\n", + drm_info(dev, "dram MCLK=%u Mhz type=%d bus_width=%d size=%08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size); diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 10211751182d..54b496552a3d 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -565,14 +565,15 @@ static void ast_primary_plane_helper_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct ast_private *ast = to_ast_private(plane->dev); + struct drm_device *dev = plane->dev; + struct ast_private *ast = to_ast_private(dev); struct drm_plane_state *state = plane->state; struct drm_gem_vram_object *gbo; s64 gpu_addr; gbo = drm_gem_vram_of_gem(state->fb->obj[0]); gpu_addr = drm_gem_vram_offset(gbo); - if (WARN_ON_ONCE(gpu_addr < 0)) + if (drm_WARN_ON_ONCE(dev, gpu_addr < 0)) return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */ ast_set_offset_reg(ast, state->fb); @@ -619,6 +620,7 @@ static int ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, struct drm_plane_state *new_state) { + struct drm_device *dev = plane->dev; struct drm_framebuffer *fb = new_state->fb; struct drm_crtc *crtc = new_state->crtc; struct drm_gem_vram_object *gbo; @@ -629,11 +631,11 @@ ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, if (!crtc || !fb) return 0; - if (WARN_ON_ONCE(fb->width > AST_MAX_HWC_WIDTH) || - WARN_ON_ONCE(fb->height > AST_MAX_HWC_HEIGHT)) + if (drm_WARN_ON_ONCE(dev, fb->width > AST_MAX_HWC_WIDTH) || + drm_WARN_ON_ONCE(dev, fb->height > AST_MAX_HWC_HEIGHT)) return -EINVAL; /* BUG: didn't test in atomic_check() */ - ast = to_ast_private(crtc->dev); + ast = to_ast_private(dev); gbo = drm_gem_vram_of_gem(fb->obj[0]); src = drm_gem_vram_vmap(gbo); @@ -702,6 +704,7 @@ static void ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { + struct drm_device *dev = plane->dev; struct drm_plane_state *state = plane->state; struct drm_crtc *crtc = state->crtc; struct drm_framebuffer *fb = state->fb; @@ -718,7 +721,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, /* A new cursor image was installed. */ gbo = ast->cursor.gbo[ast->cursor.next_index]; off = drm_gem_vram_offset(gbo); - if (WARN_ON_ONCE(off < 0)) + if (drm_WARN_ON_ONCE(dev, off < 0)) return; /* Bug: we didn't pin cursor HW BO to VRAM. */ ast_cursor_set_base(ast, off); @@ -897,8 +900,9 @@ static struct drm_crtc_state * ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc) { struct ast_crtc_state *new_ast_state, *ast_state; + struct drm_device *dev = crtc->dev; - if (WARN_ON(!crtc->state)) + if (drm_WARN_ON(dev, !crtc->state)) return NULL; new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL); @@ -1104,7 +1108,7 @@ static int ast_connector_init(struct drm_device *dev) connector = &ast_connector->base; ast_connector->i2c = ast_i2c_create(dev); if (!ast_connector->i2c) - DRM_ERROR("failed to add ddc bus for connector\n"); + drm_err(dev, "failed to add ddc bus for connector\n"); drm_connector_init_with_ddc(dev, connector, &ast_connector_funcs, @@ -1188,7 +1192,7 @@ int ast_mode_init(struct drm_device *dev) ARRAY_SIZE(ast_primary_plane_formats), NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { - DRM_ERROR("ast: drm_universal_plane_init() failed: %d\n", ret); + drm_err(dev, "ast: drm_universal_plane_init() failed: %d\n", ret); return ret; } drm_plane_helper_add(&ast->primary_plane, @@ -1200,7 +1204,7 @@ int ast_mode_init(struct drm_device *dev) ARRAY_SIZE(ast_cursor_plane_formats), NULL, DRM_PLANE_TYPE_CURSOR, NULL); if (ret) { - DRM_ERROR("drm_universal_plane_failed(): %d\n", ret); + drm_err(dev, "drm_universal_plane_failed(): %d\n", ret); return ret; } drm_plane_helper_add(&ast->cursor_plane, @@ -1322,7 +1326,7 @@ static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev) i2c->bit.getscl = get_clock; ret = i2c_bit_add_bus(&i2c->adapter); if (ret) { - DRM_ERROR("Failed to register bit i2c\n"); + drm_err(dev, "Failed to register bit i2c\n"); goto out_free; } diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 226e1290227a..c043fe717553 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -2067,7 +2067,7 @@ void ast_post_chip_2500(struct drm_device *dev) } if (!ast_dram_init_2500(ast)) - DRM_ERROR("DRAM init failed !\n"); + drm_err(dev, "DRAM init failed !\n"); temp = ast_mindwm(ast, 0x1e6e2040); ast_moutdwm(ast, 0x1e6e2040, temp | 0x40); diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c index fad34106083a..9c3788a4c1c5 100644 --- a/drivers/gpu/drm/ast/ast_ttm.c +++ b/drivers/gpu/drm/ast/ast_ttm.c @@ -44,7 +44,7 @@ int ast_mm_init(struct ast_private *ast) ast->vram_size); if (IS_ERR(vmm)) { ret = PTR_ERR(vmm); - DRM_ERROR("Error initializing VRAM MM; %d\n", ret); + drm_err(dev, "Error initializing VRAM MM; %d\n", ret); return ret; } -- cgit v1.2.3 From 41c0e78aae53099852dab4d1050c06a43c827eb3 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 8 Jun 2020 17:27:01 +0200 Subject: drm/mm: remove unused rb_hole_size() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just some code cleanup. Signed-off-by: Christian König Reviewed-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/370296/ --- drivers/gpu/drm/drm_mm.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 82d2888eb7fe..425fcd3590e8 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -305,11 +305,6 @@ static inline struct drm_mm_node *rb_hole_addr_to_node(struct rb_node *rb) return rb_entry_safe(rb, struct drm_mm_node, rb_hole_addr); } -static inline u64 rb_hole_size(struct rb_node *rb) -{ - return rb_entry(rb, struct drm_mm_node, rb_hole_size)->hole_size; -} - static struct drm_mm_node *best_hole(struct drm_mm *mm, u64 size) { struct rb_node *rb = mm->holes_size.rb_root.rb_node; -- cgit v1.2.3 From 271e7decd707accfe6d4965b2c5e60d2d77c8e35 Mon Sep 17 00:00:00 2001 From: Christian König Date: Tue, 9 Jun 2020 14:47:33 +0200 Subject: drm/mm: optimize find_hole() as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Abort early if there isn't enough space to allocate from a subtree. Signed-off-by: Christian König Acked-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/370297/ --- drivers/gpu/drm/drm_mm.c | 11 +++++++---- drivers/gpu/drm/selftests/test-drm_mm.c | 11 ----------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 425fcd3590e8..177a5df0fe95 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -325,7 +325,7 @@ static struct drm_mm_node *best_hole(struct drm_mm *mm, u64 size) return best; } -static struct drm_mm_node *find_hole(struct drm_mm *mm, u64 addr) +static struct drm_mm_node *find_hole_addr(struct drm_mm *mm, u64 addr, u64 size) { struct rb_node *rb = mm->holes_addr.rb_node; struct drm_mm_node *node = NULL; @@ -333,6 +333,9 @@ static struct drm_mm_node *find_hole(struct drm_mm *mm, u64 addr) while (rb) { u64 hole_start; + if (rb_hole_addr_to_node(rb)->subtree_max_hole < size) + break; + node = rb_hole_addr_to_node(rb); hole_start = __drm_mm_hole_node_start(node); @@ -358,10 +361,10 @@ first_hole(struct drm_mm *mm, return best_hole(mm, size); case DRM_MM_INSERT_LOW: - return find_hole(mm, start); + return find_hole_addr(mm, start, size); case DRM_MM_INSERT_HIGH: - return find_hole(mm, end); + return find_hole_addr(mm, end, size); case DRM_MM_INSERT_EVICT: return list_first_entry_or_null(&mm->hole_stack, @@ -497,7 +500,7 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node) return -ENOSPC; /* Find the relevant hole to add our node to */ - hole = find_hole(mm, node->start); + hole = find_hole_addr(mm, node->start, 0); if (!hole) return -ENOSPC; diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c b/drivers/gpu/drm/selftests/test-drm_mm.c index 3846b0f5bae3..910eac289c76 100644 --- a/drivers/gpu/drm/selftests/test-drm_mm.c +++ b/drivers/gpu/drm/selftests/test-drm_mm.c @@ -1981,16 +1981,6 @@ static int __igt_once(unsigned int mode) } memset(&node, 0, sizeof(node)); - err = drm_mm_insert_node_generic(&mm, &node, - 2, 0, 0, - mode | DRM_MM_INSERT_ONCE); - if (!err) { - pr_err("Unexpectedly inserted the node into the wrong hole: node.start=%llx\n", - node.start); - err = -EINVAL; - goto err_node; - } - err = drm_mm_insert_node_generic(&mm, &node, 2, 0, 0, mode); if (err) { pr_err("Could not insert the node into the available hole!\n"); @@ -1998,7 +1988,6 @@ static int __igt_once(unsigned int mode) goto err_hi; } -err_node: drm_mm_remove_node(&node); err_hi: drm_mm_remove_node(&rsvd_hi); -- cgit v1.2.3 From 5fad79fd66ff90b8c0a95319dad0b099008f8347 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 15 Jun 2020 16:16:42 +0200 Subject: drm/mm: cleanup and improve next_hole_*_addr() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Skipping just one branch of the tree is not the most effective approach. Instead use a macro to define the traversal functions and sort out both branch sides. This improves the performance of the unit tests by a factor of more than 4. Signed-off-by: Christian König Reviewed-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/370298/ --- drivers/gpu/drm/drm_mm.c | 106 +++++++++++++++-------------------------------- 1 file changed, 34 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 177a5df0fe95..a4a04d246135 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -325,6 +325,11 @@ static struct drm_mm_node *best_hole(struct drm_mm *mm, u64 size) return best; } +static bool usable_hole_addr(struct rb_node *rb, u64 size) +{ + return rb && rb_hole_addr_to_node(rb)->subtree_max_hole >= size; +} + static struct drm_mm_node *find_hole_addr(struct drm_mm *mm, u64 addr, u64 size) { struct rb_node *rb = mm->holes_addr.rb_node; @@ -333,7 +338,7 @@ static struct drm_mm_node *find_hole_addr(struct drm_mm *mm, u64 addr, u64 size) while (rb) { u64 hole_start; - if (rb_hole_addr_to_node(rb)->subtree_max_hole < size) + if (!usable_hole_addr(rb, size)) break; node = rb_hole_addr_to_node(rb); @@ -374,82 +379,39 @@ first_hole(struct drm_mm *mm, } /** - * next_hole_high_addr - returns next hole for a DRM_MM_INSERT_HIGH mode request - * @entry: previously selected drm_mm_node - * @size: size of the a hole needed for the request - * - * This function will verify whether left subtree of @entry has hole big enough - * to fit the requtested size. If so, it will return previous node of @entry or - * else it will return parent node of @entry + * DECLARE_NEXT_HOLE_ADDR - macro to declare next hole functions + * @name: name of function to declare + * @first: first rb member to traverse (either rb_left or rb_right). + * @last: last rb member to traverse (either rb_right or rb_left). * - * It will also skip the complete left subtree if subtree_max_hole of that - * subtree is same as the subtree_max_hole of the @entry. - * - * Returns: - * previous node of @entry if left subtree of @entry can serve the request or - * else return parent of @entry + * This macro declares a function to return the next hole of the addr rb tree. + * While traversing the tree we take the searched size into account and only + * visit branches with potential big enough holes. */ -static struct drm_mm_node * -next_hole_high_addr(struct drm_mm_node *entry, u64 size) -{ - struct rb_node *rb_node, *left_rb_node, *parent_rb_node; - struct drm_mm_node *left_node; - - if (!entry) - return NULL; - rb_node = &entry->rb_hole_addr; - if (rb_node->rb_left) { - left_rb_node = rb_node->rb_left; - parent_rb_node = rb_parent(rb_node); - left_node = rb_entry(left_rb_node, - struct drm_mm_node, rb_hole_addr); - if (left_node->subtree_max_hole < size && - parent_rb_node && parent_rb_node->rb_left != rb_node) - return rb_hole_addr_to_node(parent_rb_node); - } - - return rb_hole_addr_to_node(rb_prev(rb_node)); +#define DECLARE_NEXT_HOLE_ADDR(name, first, last) \ +static struct drm_mm_node *name(struct drm_mm_node *entry, u64 size) \ +{ \ + struct rb_node *parent, *node = &entry->rb_hole_addr; \ + \ + if (!entry || RB_EMPTY_NODE(node)) \ + return NULL; \ + \ + if (usable_hole_addr(node->first, size)) { \ + node = node->first; \ + while (usable_hole_addr(node->last, size)) \ + node = node->last; \ + return rb_hole_addr_to_node(node); \ + } \ + \ + while ((parent = rb_parent(node)) && node == parent->first) \ + node = parent; \ + \ + return rb_hole_addr_to_node(parent); \ } -/** - * next_hole_low_addr - returns next hole for a DRM_MM_INSERT_LOW mode request - * @entry: previously selected drm_mm_node - * @size: size of the a hole needed for the request - * - * This function will verify whether right subtree of @entry has hole big enough - * to fit the requtested size. If so, it will return next node of @entry or - * else it will return parent node of @entry - * - * It will also skip the complete right subtree if subtree_max_hole of that - * subtree is same as the subtree_max_hole of the @entry. - * - * Returns: - * next node of @entry if right subtree of @entry can serve the request or - * else return parent of @entry - */ -static struct drm_mm_node * -next_hole_low_addr(struct drm_mm_node *entry, u64 size) -{ - struct rb_node *rb_node, *right_rb_node, *parent_rb_node; - struct drm_mm_node *right_node; - - if (!entry) - return NULL; - - rb_node = &entry->rb_hole_addr; - if (rb_node->rb_right) { - right_rb_node = rb_node->rb_right; - parent_rb_node = rb_parent(rb_node); - right_node = rb_entry(right_rb_node, - struct drm_mm_node, rb_hole_addr); - if (right_node->subtree_max_hole < size && - parent_rb_node && parent_rb_node->rb_right != rb_node) - return rb_hole_addr_to_node(parent_rb_node); - } - - return rb_hole_addr_to_node(rb_next(rb_node)); -} +DECLARE_NEXT_HOLE_ADDR(next_hole_high_addr, rb_left, rb_right) +DECLARE_NEXT_HOLE_ADDR(next_hole_low_addr, rb_right, rb_left) static struct drm_mm_node * next_hole(struct drm_mm *mm, -- cgit v1.2.3 From c9bb9d6685c0e8318c3a70fcdea319c84c94e5af Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Mon, 22 Jun 2020 15:45:33 +0200 Subject: drm/mm/selftests: fix wrong return type casting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Function prepare_igt_frag() and get_insert_time() were casting signed value to unsigned value before returning error. So error check in igt_frag() would not work with unsigned return value from get_insert_time() compared against negative value. Addresses-Coverity: ("Unsigned compared against 0, no effect") Signed-off-by: Nirmoy Das Reported-by: Colin Ian King Reviewed-by: Christian König Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/370636/ --- drivers/gpu/drm/selftests/test-drm_mm.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c b/drivers/gpu/drm/selftests/test-drm_mm.c index 910eac289c76..95e212a9a74d 100644 --- a/drivers/gpu/drm/selftests/test-drm_mm.c +++ b/drivers/gpu/drm/selftests/test-drm_mm.c @@ -1041,13 +1041,12 @@ static int prepare_igt_frag(struct drm_mm *mm, { unsigned int size = 4096; unsigned int i; - u64 ret = -EINVAL; for (i = 0; i < num_insert; i++) { if (!expect_insert(mm, &nodes[i], size, 0, i, mode) != 0) { pr_err("%s insert failed\n", mode->name); - goto out; + return -EINVAL; } } @@ -1057,8 +1056,7 @@ static int prepare_igt_frag(struct drm_mm *mm, drm_mm_remove_node(&nodes[i]); } -out: - return ret; + return 0; } @@ -1070,21 +1068,16 @@ static u64 get_insert_time(struct drm_mm *mm, unsigned int size = 8192; ktime_t start; unsigned int i; - u64 ret = -EINVAL; start = ktime_get(); for (i = 0; i < num_insert; i++) { if (!expect_insert(mm, &nodes[i], size, 0, i, mode) != 0) { pr_err("%s insert failed\n", mode->name); - goto out; + return 0; } } - ret = ktime_to_ns(ktime_sub(ktime_get(), start)); - -out: - return ret; - + return ktime_to_ns(ktime_sub(ktime_get(), start)); } static int igt_frag(void *ignored) @@ -1119,17 +1112,17 @@ static int igt_frag(void *ignored) continue; ret = prepare_igt_frag(&mm, nodes, insert_size, mode); - if (!ret) + if (ret) goto err; insert_time1 = get_insert_time(&mm, insert_size, nodes + insert_size, mode); - if (insert_time1 < 0) + if (insert_time1 == 0) goto err; insert_time2 = get_insert_time(&mm, (insert_size * 2), nodes + insert_size * 2, mode); - if (insert_time2 < 0) + if (insert_time2 == 0) goto err; pr_info("%s fragmented insert of %u and %u insertions took %llu and %llu nsecs\n", -- cgit v1.2.3 From fed9d35d71640cb8dfbfc15cd59fb21073af78ca Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:39 +0300 Subject: drm: bridge: adv7511: Split EDID read to a separate function To prepare for the implementation of the DRM bridge connector operations, move EDID read out of adv7511_get_modes() to a separate function. Signed-off-by: Laurent Pinchart Acked-by: Sam Ravnborg Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-2-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 87b58c1acff4..58d02e92b6b9 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -589,11 +589,10 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block, * ADV75xx helpers */ -static int adv7511_get_modes(struct adv7511 *adv7511, - struct drm_connector *connector) +static struct edid *adv7511_get_edid(struct adv7511 *adv7511, + struct drm_connector *connector) { struct edid *edid; - unsigned int count; /* Reading the EDID only works if the device is powered */ if (!adv7511->powered) { @@ -612,15 +611,25 @@ static int adv7511_get_modes(struct adv7511 *adv7511, if (!adv7511->powered) __adv7511_power_off(adv7511); - - drm_connector_update_edid_property(connector, edid); - count = drm_add_edid_modes(connector, edid); - adv7511_set_config_csc(adv7511, connector, adv7511->rgb, drm_detect_hdmi_monitor(edid)); cec_s_phys_addr_from_edid(adv7511->cec_adap, edid); + return edid; +} + +static int adv7511_get_modes(struct adv7511 *adv7511, + struct drm_connector *connector) +{ + struct edid *edid; + unsigned int count; + + edid = adv7511_get_edid(adv7511, connector); + + drm_connector_update_edid_property(connector, edid); + count = drm_add_edid_modes(connector, edid); + kfree(edid); return count; -- cgit v1.2.3 From c6533015b9b1956b702dfe3bb1f462c0f36a2beb Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:40 +0300 Subject: drm: bridge: adv7511: Split connector creation to a separate function To prepare for making the connector creation optional, move the related code out of adv7511_bridge_attach() to a separate function. Signed-off-by: Laurent Pinchart Acked-by: Sam Ravnborg Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-3-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 62 ++++++++++++++++++---------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 58d02e92b6b9..f0992b6d654f 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -783,7 +783,10 @@ static void adv7511_mode_set(struct adv7511 *adv7511, adv7511->f_tmds = mode->clock; } -/* Connector funcs */ +/* ----------------------------------------------------------------------------- + * DRM Connector Operations + */ + static struct adv7511 *connector_to_adv7511(struct drm_connector *connector) { return container_of(connector, struct adv7511, connector); @@ -827,7 +830,40 @@ static const struct drm_connector_funcs adv7511_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -/* Bridge funcs */ +static int adv7511_connector_init(struct adv7511 *adv) +{ + struct drm_bridge *bridge = &adv->bridge; + int ret; + + if (!bridge->encoder) { + DRM_ERROR("Parent encoder object not found"); + return -ENODEV; + } + + if (adv->i2c_main->irq) + adv->connector.polled = DRM_CONNECTOR_POLL_HPD; + else + adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT; + + ret = drm_connector_init(bridge->dev, &adv->connector, + &adv7511_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA); + if (ret < 0) { + DRM_ERROR("Failed to initialize connector with drm\n"); + return ret; + } + drm_connector_helper_add(&adv->connector, + &adv7511_connector_helper_funcs); + drm_connector_attach_encoder(&adv->connector, bridge->encoder); + + return 0; +} + +/* ----------------------------------------------------------------------------- + * DRM Bridge Operations + */ + static struct adv7511 *bridge_to_adv7511(struct drm_bridge *bridge) { return container_of(bridge, struct adv7511, bridge); @@ -867,27 +903,9 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge, return -EINVAL; } - if (!bridge->encoder) { - DRM_ERROR("Parent encoder object not found"); - return -ENODEV; - } - - if (adv->i2c_main->irq) - adv->connector.polled = DRM_CONNECTOR_POLL_HPD; - else - adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT; - - ret = drm_connector_init(bridge->dev, &adv->connector, - &adv7511_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA); - if (ret) { - DRM_ERROR("Failed to initialize connector with drm\n"); + ret = adv7511_connector_init(adv); + if (ret < 0) return ret; - } - drm_connector_helper_add(&adv->connector, - &adv7511_connector_helper_funcs); - drm_connector_attach_encoder(&adv->connector, bridge->encoder); if (adv->type == ADV7533 || adv->type == ADV7535) ret = adv7533_attach_dsi(adv); -- cgit v1.2.3 From 7c9361578b51ac091fe05117b63ad7423e25f175 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:41 +0300 Subject: drm: bridge: adv7511: Implement bridge connector operations Implement the bridge connector-related .get_edid(), .detect() and .hpd_notify() operations, and report the related bridge capabilities. Output status detection is implemented using the same backend as for the DRM connector, but requires making mode retrieval at detection time optional as no pointer to the connector is available to the bridge .detect() operation. The reason for the need to retrieve modes at detection time is unclear to me, and this may benefit from further refactoring of hot plug handling code. Hot plug detection is notified through the bridge HPD notification framework when the bridge is used without creating a connector, and falls back to the existing implementation otherwise. CEC handling of disconnection is handled in the new .hpd_notify() operation in the new code path. Signed-off-by: Laurent Pinchart Acked-by: Sam Ravnborg Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-4-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 43 +++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index f0992b6d654f..2662f28f8007 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -443,9 +443,14 @@ static void adv7511_hpd_work(struct work_struct *work) if (adv7511->connector.status != status) { adv7511->connector.status = status; - if (status == connector_status_disconnected) - cec_phys_addr_invalidate(adv7511->cec_adap); - drm_kms_helper_hotplug_event(adv7511->connector.dev); + + if (adv7511->connector.dev) { + if (status == connector_status_disconnected) + cec_phys_addr_invalidate(adv7511->cec_adap); + drm_kms_helper_hotplug_event(adv7511->connector.dev); + } else { + drm_bridge_hpd_notify(&adv7511->bridge, status); + } } } @@ -661,7 +666,8 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) if (status == connector_status_connected && hpd && adv7511->powered) { regcache_mark_dirty(adv7511->regmap); adv7511_power_on(adv7511); - adv7511_get_modes(adv7511, connector); + if (connector) + adv7511_get_modes(adv7511, connector); if (adv7511->status == connector_status_connected) status = connector_status_disconnected; } else { @@ -917,11 +923,38 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge, return ret; } +static enum drm_connector_status adv7511_bridge_detect(struct drm_bridge *bridge) +{ + struct adv7511 *adv = bridge_to_adv7511(bridge); + + return adv7511_detect(adv, NULL); +} + +static struct edid *adv7511_bridge_get_edid(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + struct adv7511 *adv = bridge_to_adv7511(bridge); + + return adv7511_get_edid(adv, connector); +} + +static void adv7511_bridge_hpd_notify(struct drm_bridge *bridge, + enum drm_connector_status status) +{ + struct adv7511 *adv = bridge_to_adv7511(bridge); + + if (status == connector_status_disconnected) + cec_phys_addr_invalidate(adv->cec_adap); +} + static const struct drm_bridge_funcs adv7511_bridge_funcs = { .enable = adv7511_bridge_enable, .disable = adv7511_bridge_disable, .mode_set = adv7511_bridge_mode_set, .attach = adv7511_bridge_attach, + .detect = adv7511_bridge_detect, + .get_edid = adv7511_bridge_get_edid, + .hpd_notify = adv7511_bridge_hpd_notify, }; /* ----------------------------------------------------------------------------- @@ -1250,6 +1283,8 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) goto err_unregister_cec; adv7511->bridge.funcs = &adv7511_bridge_funcs; + adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID + | DRM_BRIDGE_OP_HPD; adv7511->bridge.of_node = dev->of_node; drm_bridge_add(&adv7511->bridge); -- cgit v1.2.3 From 0bae6020b800195c944e2d44c8a99c7d78b1c86a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:42 +0300 Subject: drm: bridge: adv7511: Make connector creation optional Now that the driver supports all the connector-related bridge operations, make the connector creation optional. This enables usage of the adv7511 with the DRM bridge connector helper. Signed-off-by: Laurent Pinchart Acked-by: Sam Ravnborg Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-5-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 2662f28f8007..f45cdca9cce5 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -902,17 +902,14 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { struct adv7511 *adv = bridge_to_adv7511(bridge); - int ret; + int ret = 0; - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { - DRM_ERROR("Fix bridge driver to make connector optional!"); - return -EINVAL; + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { + ret = adv7511_connector_init(adv); + if (ret < 0) + return ret; } - ret = adv7511_connector_init(adv); - if (ret < 0) - return ret; - if (adv->type == ADV7533 || adv->type == ADV7535) ret = adv7533_attach_dsi(adv); -- cgit v1.2.3 From 11d3cf804591246bb5e09cb03cb30121eafc2f4c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:43 +0300 Subject: drm: bridge: Return NULL on error from drm_bridge_get_edid() The drm_bridge_get_edid() function is documented to return an error pointer on error. The underlying .get_edid() operation, however, returns NULL on error, and so do the drm_get_edid() and drm_do_get_edid() functions upon which .get_edid() is usually implemented. Make drm_bridge_get_edid() return NULL on error to be consistent. Signed-off-by: Laurent Pinchart Acked-by: Sam Ravnborg Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-6-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/ti-tfp410.c | 10 +++++++--- drivers/gpu/drm/drm_bridge.c | 6 +++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c index 21d99b4ea0c9..6467e6f2f1fa 100644 --- a/drivers/gpu/drm/bridge/ti-tfp410.c +++ b/drivers/gpu/drm/bridge/ti-tfp410.c @@ -51,11 +51,15 @@ static int tfp410_get_modes(struct drm_connector *connector) struct edid *edid; int ret; - edid = drm_bridge_get_edid(dvi->next_bridge, connector); - if (IS_ERR_OR_NULL(edid)) { - if (edid != ERR_PTR(-ENOTSUPP)) + if (dvi->next_bridge->ops & DRM_BRIDGE_OP_EDID) { + edid = drm_bridge_get_edid(dvi->next_bridge, connector); + if (!edid) DRM_INFO("EDID read failed. Fallback to standard modes\n"); + } else { + edid = NULL; + } + if (!edid) { /* * No EDID, fallback on the XGA standard modes and prefer a mode * pretty much anything can handle. diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index afdec8e5fc68..fe1e3460b486 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -1086,16 +1086,16 @@ EXPORT_SYMBOL_GPL(drm_bridge_get_modes); * * If the bridge supports output EDID retrieval, as reported by the * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.get_edid to - * get the EDID and return it. Otherwise return ERR_PTR(-ENOTSUPP). + * get the EDID and return it. Otherwise return NULL. * * RETURNS: - * The retrieved EDID on success, or an error pointer otherwise. + * The retrieved EDID on success, or NULL otherwise. */ struct edid *drm_bridge_get_edid(struct drm_bridge *bridge, struct drm_connector *connector) { if (!(bridge->ops & DRM_BRIDGE_OP_EDID)) - return ERR_PTR(-ENOTSUPP); + return NULL; return bridge->funcs->get_edid(bridge, connector); } -- cgit v1.2.3 From 00686ac55d0a2192bb5cdd443272b8a5d60e557f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:44 +0300 Subject: drm: bridge: simple-bridge: Delegate operations to next bridge Instead of poking into the DT node of the next bridge for its DDC bus and implementing the .get_modes() and .detect() connector operations manually, retrieve the next bridge in the chain and delegate these operations to it. Signed-off-by: Laurent Pinchart Acked-by: Sam Ravnborg Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-7-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/simple-bridge.c | 104 +++++++++++++-------------------- 1 file changed, 39 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/bridge/simple-bridge.c b/drivers/gpu/drm/bridge/simple-bridge.c index a2dca7a3ef03..a1be269d833a 100644 --- a/drivers/gpu/drm/bridge/simple-bridge.c +++ b/drivers/gpu/drm/bridge/simple-bridge.c @@ -29,7 +29,7 @@ struct simple_bridge { const struct simple_bridge_info *info; - struct i2c_adapter *ddc; + struct drm_bridge *next_bridge; struct regulator *vdd; struct gpio_desc *enable; }; @@ -52,29 +52,28 @@ static int simple_bridge_get_modes(struct drm_connector *connector) struct edid *edid; int ret; - if (!sbridge->ddc) - goto fallback; + if (sbridge->next_bridge->ops & DRM_BRIDGE_OP_EDID) { + edid = drm_bridge_get_edid(sbridge->next_bridge, connector); + if (!edid) + DRM_INFO("EDID read failed. Fallback to standard modes\n"); + } else { + edid = NULL; + } - edid = drm_get_edid(connector, sbridge->ddc); if (!edid) { - DRM_INFO("EDID readout failed, falling back to standard modes\n"); - goto fallback; + /* + * In case we cannot retrieve the EDIDs (missing or broken DDC + * bus from the next bridge), fallback on the XGA standards and + * prefer a mode pretty much anyone can handle. + */ + ret = drm_add_modes_noedid(connector, 1920, 1200); + drm_set_preferred_mode(connector, 1024, 768); + return ret; } drm_connector_update_edid_property(connector, edid); ret = drm_add_edid_modes(connector, edid); kfree(edid); - return ret; - -fallback: - /* - * In case we cannot retrieve the EDIDs (broken or missing i2c - * bus), fallback on the XGA standards - */ - ret = drm_add_modes_noedid(connector, 1920, 1200); - - /* And prefer a mode pretty much anyone can handle */ - drm_set_preferred_mode(connector, 1024, 768); return ret; } @@ -88,16 +87,7 @@ simple_bridge_connector_detect(struct drm_connector *connector, bool force) { struct simple_bridge *sbridge = drm_connector_to_simple_bridge(connector); - /* - * Even if we have an I2C bus, we can't assume that the cable - * is disconnected if drm_probe_ddc fails. Some cables don't - * wire the DDC pins, or the I2C bus might not be working at - * all. - */ - if (sbridge->ddc && drm_probe_ddc(sbridge->ddc)) - return connector_status_connected; - - return connector_status_unknown; + return drm_bridge_detect(sbridge->next_bridge); } static const struct drm_connector_funcs simple_bridge_con_funcs = { @@ -120,6 +110,11 @@ static int simple_bridge_attach(struct drm_bridge *bridge, return -EINVAL; } + ret = drm_bridge_attach(bridge->encoder, sbridge->next_bridge, bridge, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret < 0) + return ret; + if (!bridge->encoder) { DRM_ERROR("Missing encoder\n"); return -ENODEV; @@ -130,7 +125,7 @@ static int simple_bridge_attach(struct drm_bridge *bridge, ret = drm_connector_init_with_ddc(bridge->dev, &sbridge->connector, &simple_bridge_con_funcs, sbridge->info->connector_type, - sbridge->ddc); + sbridge->next_bridge->ddc); if (ret) { DRM_ERROR("Failed to initialize connector\n"); return ret; @@ -172,31 +167,10 @@ static const struct drm_bridge_funcs simple_bridge_bridge_funcs = { .disable = simple_bridge_disable, }; -static struct i2c_adapter *simple_bridge_retrieve_ddc(struct device *dev) -{ - struct device_node *phandle, *remote; - struct i2c_adapter *ddc; - - remote = of_graph_get_remote_node(dev->of_node, 1, -1); - if (!remote) - return ERR_PTR(-EINVAL); - - phandle = of_parse_phandle(remote, "ddc-i2c-bus", 0); - of_node_put(remote); - if (!phandle) - return ERR_PTR(-ENODEV); - - ddc = of_get_i2c_adapter_by_node(phandle); - of_node_put(phandle); - if (!ddc) - return ERR_PTR(-EPROBE_DEFER); - - return ddc; -} - static int simple_bridge_probe(struct platform_device *pdev) { struct simple_bridge *sbridge; + struct device_node *remote; sbridge = devm_kzalloc(&pdev->dev, sizeof(*sbridge), GFP_KERNEL); if (!sbridge) @@ -205,6 +179,20 @@ static int simple_bridge_probe(struct platform_device *pdev) sbridge->info = of_device_get_match_data(&pdev->dev); + /* Get the next bridge in the pipeline. */ + remote = of_graph_get_remote_node(pdev->dev.of_node, 1, -1); + if (!remote) + return -EINVAL; + + sbridge->next_bridge = of_drm_find_bridge(remote); + of_node_put(remote); + + if (!sbridge->next_bridge) { + dev_dbg(&pdev->dev, "Next bridge not found, deferring probe\n"); + return -EPROBE_DEFER; + } + + /* Get the regulator and GPIO resources. */ sbridge->vdd = devm_regulator_get_optional(&pdev->dev, "vdd"); if (IS_ERR(sbridge->vdd)) { int ret = PTR_ERR(sbridge->vdd); @@ -222,18 +210,7 @@ static int simple_bridge_probe(struct platform_device *pdev) return PTR_ERR(sbridge->enable); } - sbridge->ddc = simple_bridge_retrieve_ddc(&pdev->dev); - if (IS_ERR(sbridge->ddc)) { - if (PTR_ERR(sbridge->ddc) == -ENODEV) { - dev_dbg(&pdev->dev, - "No i2c bus specified. Disabling EDID readout\n"); - sbridge->ddc = NULL; - } else { - dev_err(&pdev->dev, "Couldn't retrieve i2c bus\n"); - return PTR_ERR(sbridge->ddc); - } - } - + /* Register the bridge. */ sbridge->bridge.funcs = &simple_bridge_bridge_funcs; sbridge->bridge.of_node = pdev->dev.of_node; sbridge->bridge.timings = sbridge->info->timings; @@ -249,9 +226,6 @@ static int simple_bridge_remove(struct platform_device *pdev) drm_bridge_remove(&sbridge->bridge); - if (sbridge->ddc) - i2c_put_adapter(sbridge->ddc); - return 0; } -- cgit v1.2.3 From 567e0d53097ce973a16e9fe115aac7568f892dfb Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:45 +0300 Subject: drm: bridge: simple-bridge: Make connector creation optional Make the connector creation optional to enable usage of the simple-bridge with the DRM bridge connector helper. Signed-off-by: Laurent Pinchart Acked-by: Sam Ravnborg Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-8-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/simple-bridge.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/simple-bridge.c b/drivers/gpu/drm/bridge/simple-bridge.c index a1be269d833a..d974282c12b2 100644 --- a/drivers/gpu/drm/bridge/simple-bridge.c +++ b/drivers/gpu/drm/bridge/simple-bridge.c @@ -105,16 +105,14 @@ static int simple_bridge_attach(struct drm_bridge *bridge, struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge); int ret; - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { - DRM_ERROR("Fix bridge driver to make connector optional!"); - return -EINVAL; - } - ret = drm_bridge_attach(bridge->encoder, sbridge->next_bridge, bridge, DRM_BRIDGE_ATTACH_NO_CONNECTOR); if (ret < 0) return ret; + if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) + return 0; + if (!bridge->encoder) { DRM_ERROR("Missing encoder\n"); return -ENODEV; @@ -131,8 +129,7 @@ static int simple_bridge_attach(struct drm_bridge *bridge, return ret; } - drm_connector_attach_encoder(&sbridge->connector, - bridge->encoder); + drm_connector_attach_encoder(&sbridge->connector, bridge->encoder); return 0; } -- cgit v1.2.3 From 192a3aa0e4e20e1087baa29183c5d64d48716fa9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:47 +0300 Subject: drm: edid: Constify connector argument to infoframe functions The drm_hdmi_avi_infoframe_from_display_mode(), drm_hdmi_vendor_infoframe_from_display_mode() and drm_hdmi_avi_infoframe_quant_range() functions take a drm_connector that they don't modify. Mark it as const. Signed-off-by: Laurent Pinchart Acked-by: Sam Ravnborg Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-10-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/drm_edid.c | 12 ++++++------ include/drm/drm_edid.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 57cac677269d..54b1d4f297df 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -5359,7 +5359,7 @@ void drm_set_preferred_mode(struct drm_connector *connector, } EXPORT_SYMBOL(drm_set_preferred_mode); -static bool is_hdmi2_sink(struct drm_connector *connector) +static bool is_hdmi2_sink(const struct drm_connector *connector) { /* * FIXME: sil-sii8620 doesn't have a connector around when @@ -5444,7 +5444,7 @@ drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame, } EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata); -static u8 drm_mode_hdmi_vic(struct drm_connector *connector, +static u8 drm_mode_hdmi_vic(const struct drm_connector *connector, const struct drm_display_mode *mode) { bool has_hdmi_infoframe = connector ? @@ -5460,7 +5460,7 @@ static u8 drm_mode_hdmi_vic(struct drm_connector *connector, return drm_match_hdmi_mode(mode); } -static u8 drm_mode_cea_vic(struct drm_connector *connector, +static u8 drm_mode_cea_vic(const struct drm_connector *connector, const struct drm_display_mode *mode) { u8 vic; @@ -5498,7 +5498,7 @@ static u8 drm_mode_cea_vic(struct drm_connector *connector, */ int drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, - struct drm_connector *connector, + const struct drm_connector *connector, const struct drm_display_mode *mode) { enum hdmi_picture_aspect picture_aspect; @@ -5645,7 +5645,7 @@ EXPORT_SYMBOL(drm_hdmi_avi_infoframe_colorspace); */ void drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame, - struct drm_connector *connector, + const struct drm_connector *connector, const struct drm_display_mode *mode, enum hdmi_quantization_range rgb_quant_range) { @@ -5749,7 +5749,7 @@ s3d_structure_from_display_mode(const struct drm_display_mode *mode) */ int drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, - struct drm_connector *connector, + const struct drm_connector *connector, const struct drm_display_mode *mode) { /* diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 34b15e3d070c..43254319ab19 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -361,11 +361,11 @@ drm_load_edid_firmware(struct drm_connector *connector) int drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, - struct drm_connector *connector, + const struct drm_connector *connector, const struct drm_display_mode *mode); int drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, - struct drm_connector *connector, + const struct drm_connector *connector, const struct drm_display_mode *mode); void @@ -378,7 +378,7 @@ drm_hdmi_avi_infoframe_bars(struct hdmi_avi_infoframe *frame, void drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame, - struct drm_connector *connector, + const struct drm_connector *connector, const struct drm_display_mode *mode, enum hdmi_quantization_range rgb_quant_range); -- cgit v1.2.3 From 12c683e12cd8e2dcf7b7143bebceae484d17727a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:48 +0300 Subject: drm: bridge: Pass drm_display_info to drm_bridge_funcs .mode_valid() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When validating a mode, bridges may need to do so in the context of a display, as specified by drm_display_info. An example is the meson dw-hdmi bridge that needs to consider the YUV 4:2:0 output format to perform clock calculations. Bridges that need the display info currently retrieve it from the drm_connector created by the bridge. This gets in the way of moving connector creation out of bridge drivers. To make this possible, pass the drm_display_info to drm_bridge_funcs .mode_valid(). Changes to the bridge drivers have been performed with the following coccinelle semantic patch and have been compile-tested. @ rule1 @ identifier funcs; identifier fn; @@ struct drm_bridge_funcs funcs = { ..., .mode_valid = fn }; @ depends on rule1 @ identifier rule1.fn; identifier bridge; identifier mode; @@ enum drm_mode_status fn( struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode ) { ... } Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Reviewed-by: Boris Brezillon Reviewed-by: Guido Günther # for the nwl-dsi part: Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-11-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/analogix/analogix-anx6345.c | 1 + drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 1 + drivers/gpu/drm/bridge/cdns-dsi.c | 1 + drivers/gpu/drm/bridge/chrontel-ch7033.c | 1 + drivers/gpu/drm/bridge/nwl-dsi.c | 1 + drivers/gpu/drm/bridge/sii9234.c | 1 + drivers/gpu/drm/bridge/sil-sii8620.c | 1 + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 + drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 1 + drivers/gpu/drm/bridge/tc358767.c | 1 + drivers/gpu/drm/bridge/tc358768.c | 1 + drivers/gpu/drm/bridge/thc63lvd1024.c | 1 + drivers/gpu/drm/bridge/ti-tfp410.c | 1 + drivers/gpu/drm/drm_atomic_helper.c | 3 ++- drivers/gpu/drm/drm_bridge.c | 4 +++- drivers/gpu/drm/drm_probe_helper.c | 4 +++- drivers/gpu/drm/i2c/tda998x_drv.c | 1 + drivers/gpu/drm/omapdrm/dss/dpi.c | 1 + drivers/gpu/drm/omapdrm/dss/sdi.c | 1 + drivers/gpu/drm/omapdrm/dss/venc.c | 1 + include/drm/drm_bridge.h | 3 +++ 21 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c index 2bc6e4f85171..371f4a9f866d 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c @@ -585,6 +585,7 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge, static enum drm_mode_status anx6345_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { if (mode->flags & DRM_MODE_FLAG_INTERLACE) diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c index 0d5a5ad0c9ee..81debd02c169 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c @@ -944,6 +944,7 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge, static enum drm_mode_status anx78xx_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { if (mode->flags & DRM_MODE_FLAG_INTERLACE) diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c index 69c3892caee5..76373e31df92 100644 --- a/drivers/gpu/drm/bridge/cdns-dsi.c +++ b/drivers/gpu/drm/bridge/cdns-dsi.c @@ -663,6 +663,7 @@ static int cdns_dsi_bridge_attach(struct drm_bridge *bridge, static enum drm_mode_status cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); diff --git a/drivers/gpu/drm/bridge/chrontel-ch7033.c b/drivers/gpu/drm/bridge/chrontel-ch7033.c index f8675d82974b..486f405c2e16 100644 --- a/drivers/gpu/drm/bridge/chrontel-ch7033.c +++ b/drivers/gpu/drm/bridge/chrontel-ch7033.c @@ -317,6 +317,7 @@ static void ch7033_bridge_detach(struct drm_bridge *bridge) } static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { if (mode->clock > 165000) diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index b14d725bf609..77a79af70914 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -818,6 +818,7 @@ static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge, static enum drm_mode_status nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c index b1258f0ed205..15c98a7bd81c 100644 --- a/drivers/gpu/drm/bridge/sii9234.c +++ b/drivers/gpu/drm/bridge/sii9234.c @@ -873,6 +873,7 @@ static inline struct sii9234 *bridge_to_sii9234(struct drm_bridge *bridge) } static enum drm_mode_status sii9234_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { if (mode->clock > MHL1_MAX_CLK) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 92acd336aa89..7c0c93c7e61f 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -2244,6 +2244,7 @@ static int sii8620_is_packing_required(struct sii8620 *ctx, } static enum drm_mode_status sii8620_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct sii8620 *ctx = bridge_to_sii8620(bridge); diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 30681398cfb0..b535354150db 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2767,6 +2767,7 @@ static void dw_hdmi_bridge_detach(struct drm_bridge *bridge) static enum drm_mode_status dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct dw_hdmi *hdmi = bridge->driver_private; diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 5ef0f154aa7b..c223fb9a04cb 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -924,6 +924,7 @@ static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge) static enum drm_mode_status dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index e4c0ea03ae3a..c2777b226c75 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -1306,6 +1306,7 @@ static bool tc_bridge_mode_fixup(struct drm_bridge *bridge, } static enum drm_mode_status tc_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct tc_data *tc = bridge_to_tc(bridge); diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 6650fe4cfc20..4a463fadf743 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -529,6 +529,7 @@ static int tc358768_bridge_attach(struct drm_bridge *bridge, static enum drm_mode_status tc358768_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct tc358768_priv *priv = bridge_to_tc358768(bridge); diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c index 97d8129760e9..86b06975bfdd 100644 --- a/drivers/gpu/drm/bridge/thc63lvd1024.c +++ b/drivers/gpu/drm/bridge/thc63lvd1024.c @@ -51,6 +51,7 @@ static int thc63_attach(struct drm_bridge *bridge, } static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct thc63_dev *thc63 = to_thc63(bridge); diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c index 6467e6f2f1fa..ba3fa2a9b8a4 100644 --- a/drivers/gpu/drm/bridge/ti-tfp410.c +++ b/drivers/gpu/drm/bridge/ti-tfp410.c @@ -192,6 +192,7 @@ static void tfp410_disable(struct drm_bridge *bridge) } static enum drm_mode_status tfp410_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { if (mode->clock < 25000) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index a1898c58ae3c..f68c69a45752 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -506,7 +506,8 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector, } bridge = drm_bridge_chain_get_first_bridge(encoder); - ret = drm_bridge_chain_mode_valid(bridge, mode); + ret = drm_bridge_chain_mode_valid(bridge, &connector->display_info, + mode); if (ret != MODE_OK) { DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n"); return ret; diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index fe1e3460b486..64f0effb52ac 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -377,6 +377,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup); * drm_bridge_chain_mode_valid - validate the mode against all bridges in the * encoder chain. * @bridge: bridge control structure + * @info: display info against which the mode shall be validated * @mode: desired mode to be validated * * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder @@ -390,6 +391,7 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_fixup); */ enum drm_mode_status drm_bridge_chain_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct drm_encoder *encoder; @@ -404,7 +406,7 @@ drm_bridge_chain_mode_valid(struct drm_bridge *bridge, if (!bridge->funcs->mode_valid) continue; - ret = bridge->funcs->mode_valid(bridge, mode); + ret = bridge->funcs->mode_valid(bridge, info, mode); if (ret != MODE_OK) return ret; } diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 26e997f1524f..09e872e61315 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -114,7 +114,9 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode, } bridge = drm_bridge_chain_get_first_bridge(encoder); - ret = drm_bridge_chain_mode_valid(bridge, mode); + ret = drm_bridge_chain_mode_valid(bridge, + &connector->display_info, + mode); if (ret != MODE_OK) { /* There is also no point in continuing for crtc check * here. */ diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 9517f522dcb9..50fd119a5276 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1379,6 +1379,7 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge) } static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { /* TDA19988 dotclock can go up to 165MHz */ diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c index 5110acb0c6c1..1d2992daef40 100644 --- a/drivers/gpu/drm/omapdrm/dss/dpi.c +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c @@ -434,6 +434,7 @@ static int dpi_bridge_attach(struct drm_bridge *bridge, static enum drm_mode_status dpi_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct dpi_data *dpi = drm_bridge_to_dpi(bridge); diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c index 417a8740ad0a..033fd30074b0 100644 --- a/drivers/gpu/drm/omapdrm/dss/sdi.c +++ b/drivers/gpu/drm/omapdrm/dss/sdi.c @@ -140,6 +140,7 @@ static int sdi_bridge_attach(struct drm_bridge *bridge, static enum drm_mode_status sdi_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { struct sdi_device *sdi = drm_bridge_to_sdi(bridge); diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c index 9701843ccf09..4406ce2a08b4 100644 --- a/drivers/gpu/drm/omapdrm/dss/venc.c +++ b/drivers/gpu/drm/omapdrm/dss/venc.c @@ -548,6 +548,7 @@ static int venc_bridge_attach(struct drm_bridge *bridge, static enum drm_mode_status venc_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode) { switch (venc_get_videomode(mode)) { diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index ea2aa5ebae34..e3d7f36d8c39 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -35,6 +35,7 @@ struct drm_bridge; struct drm_bridge_timings; struct drm_connector; +struct drm_display_info; struct drm_panel; struct edid; struct i2c_adapter; @@ -112,6 +113,7 @@ struct drm_bridge_funcs { * drm_mode_status Enum */ enum drm_mode_status (*mode_valid)(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode); /** @@ -836,6 +838,7 @@ bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge, struct drm_display_mode *adjusted_mode); enum drm_mode_status drm_bridge_chain_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, const struct drm_display_mode *mode); void drm_bridge_chain_disable(struct drm_bridge *bridge); void drm_bridge_chain_post_disable(struct drm_bridge *bridge); -- cgit v1.2.3 From 96591a4b93fb8b335941783dd6e7ded9d6d49f09 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:49 +0300 Subject: drm: bridge: dw-hdmi: Pass private data pointer to .mode_valid() Platform glue drivers for dw_hdmi may need to access device-specific data from their .mode_valid() implementation. They currently have no clean way to do so, and one driver hacks around it by accessing the dev_private data of the drm_device retrieved from the connector. Add a priv_data void pointer to the dw_hdmi_plat_data structure, and pass it to the .mode_valid() function. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-12-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 6 ++++-- drivers/gpu/drm/imx/dw_hdmi-imx.c | 6 ++++-- drivers/gpu/drm/meson/meson_dw_hdmi.c | 3 ++- drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 3 ++- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 3 ++- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 6 ++++-- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 3 ++- include/drm/bridge/dw_hdmi.h | 14 ++++++++++++-- 8 files changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index b535354150db..2b3f203cf467 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2771,6 +2771,7 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_mode *mode) { struct dw_hdmi *hdmi = bridge->driver_private; + const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; struct drm_connector *connector = &hdmi->connector; enum drm_mode_status mode_status = MODE_OK; @@ -2778,8 +2779,9 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, if (mode->flags & DRM_MODE_FLAG_DBLCLK) return MODE_BAD; - if (hdmi->plat_data->mode_valid) - mode_status = hdmi->plat_data->mode_valid(connector, mode); + if (pdata->mode_valid) + mode_status = pdata->mode_valid(hdmi, pdata->priv_data, + connector, mode); return mode_status; } diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index ba4ca17fd4d8..95aed4666c95 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -145,7 +145,8 @@ static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = }; static enum drm_mode_status -imx6q_hdmi_mode_valid(struct drm_connector *con, +imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, + struct drm_connector *con, const struct drm_display_mode *mode) { if (mode->clock < 13500) @@ -158,7 +159,8 @@ imx6q_hdmi_mode_valid(struct drm_connector *con, } static enum drm_mode_status -imx6dl_hdmi_mode_valid(struct drm_connector *con, +imx6dl_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, + struct drm_connector *con, const struct drm_display_mode *mode) { if (mode->clock < 13500) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 5be963e9db05..5cc311c1b8e0 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -630,7 +630,8 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id) } static enum drm_mode_status -dw_hdmi_mode_valid(struct drm_connector *connector, +dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, + struct drm_connector *connector, const struct drm_display_mode *mode) { struct meson_drm *priv = connector->dev->dev_private; diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c index 452461dc96f2..4d837a4d302d 100644 --- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c +++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c @@ -38,7 +38,8 @@ static const struct rcar_hdmi_phy_params rcar_hdmi_phy_params[] = { }; static enum drm_mode_status -rcar_hdmi_mode_valid(struct drm_connector *connector, +rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, + struct drm_connector *connector, const struct drm_display_mode *mode) { /* diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 121aa8a63a76..d08f86783a28 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -220,7 +220,8 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) } static enum drm_mode_status -dw_hdmi_rockchip_mode_valid(struct drm_connector *connector, +dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data, + struct drm_connector *connector, const struct drm_display_mode *mode) { const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg; diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index 972682bb8000..0a3637442ba6 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -31,7 +31,8 @@ sun8i_dw_hdmi_encoder_helper_funcs = { }; static enum drm_mode_status -sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector, +sun8i_dw_hdmi_mode_valid_a83t(struct dw_hdmi *hdmi, void *data, + struct drm_connector *connector, const struct drm_display_mode *mode) { if (mode->clock > 297000) @@ -41,7 +42,8 @@ sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector, } static enum drm_mode_status -sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector, +sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data, + struct drm_connector *connector, const struct drm_display_mode *mode) { /* diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index 8e64945167e9..8587b8d2590e 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h @@ -176,7 +176,8 @@ struct sun8i_hdmi_phy { }; struct sun8i_dw_hdmi_quirks { - enum drm_mode_status (*mode_valid)(struct drm_connector *connector, + enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data, + struct drm_connector *connector, const struct drm_display_mode *mode); unsigned int set_rate : 1; unsigned int use_drm_infoframe : 1; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 0b34a12c4a1c..66a811f75b91 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -124,13 +124,23 @@ struct dw_hdmi_phy_ops { struct dw_hdmi_plat_data { struct regmap *regm; - enum drm_mode_status (*mode_valid)(struct drm_connector *connector, - const struct drm_display_mode *mode); + unsigned long input_bus_format; unsigned long input_bus_encoding; bool use_drm_infoframe; bool ycbcr_420_allowed; + /* + * Private data passed to all the .mode_valid() and .configure_phy() + * callback functions. + */ + void *priv_data; + + /* Platform-specific mode validation (optional). */ + enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data, + struct drm_connector *connector, + const struct drm_display_mode *mode); + /* Vendor PHY support */ const struct dw_hdmi_phy_ops *phy_ops; const char *phy_name; -- cgit v1.2.3 From 49da7e5d84e3b520355c0b6148d6dc9e5415a13e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:50 +0300 Subject: drm: bridge: dw-hdmi: Pass private data pointer to .configure_phy() The .configure_phy() operation takes a dw_hdmi_plat_data pointer as a context argument. This differs from .mode_valid() that takes a custom private context pointer, causing possible confusion. Make the dw_hdmi_plat_data operations more consistent by passing the private context pointer to .configure_phy() as well. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-13-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +- drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 3 +-- include/drm/bridge/dw_hdmi.h | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 2b3f203cf467..6edb60e6c784 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1514,7 +1514,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) /* Write to the PHY as configured by the platform */ if (pdata->configure_phy) - ret = pdata->configure_phy(hdmi, pdata, mpixelclock); + ret = pdata->configure_phy(hdmi, pdata->priv_data, mpixelclock); else ret = phy->configure(hdmi, pdata, mpixelclock); if (ret) { diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c index 4d837a4d302d..d0dffe55a7cb 100644 --- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c +++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c @@ -52,8 +52,7 @@ rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, return MODE_OK; } -static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi, - const struct dw_hdmi_plat_data *pdata, +static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi, void *data, unsigned long mpixelclock) { const struct rcar_hdmi_phy_params *params = rcar_hdmi_phy_params; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 66a811f75b91..09348c9cbd11 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -151,8 +151,7 @@ struct dw_hdmi_plat_data { const struct dw_hdmi_mpll_config *mpll_cfg; const struct dw_hdmi_curr_ctrl *cur_ctr; const struct dw_hdmi_phy_config *phy_config; - int (*configure_phy)(struct dw_hdmi *hdmi, - const struct dw_hdmi_plat_data *pdata, + int (*configure_phy)(struct dw_hdmi *hdmi, void *data, unsigned long mpixelclock); }; -- cgit v1.2.3 From 29fc89719d396e81176974ce37e0cc81e23869d8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:51 +0300 Subject: drm: bridge: dw-hdmi: Remove unused field from dw_hdmi_plat_data The input_bus_format field of struct dw_hdmi_plat_data is unused. Remove it. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-14-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 5 +---- include/drm/bridge/dw_hdmi.h | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 6edb60e6c784..adc5a95a06e9 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2137,10 +2137,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; - if (hdmi->plat_data->input_bus_format) - hdmi->hdmi_data.enc_in_bus_format = - hdmi->plat_data->input_bus_format; - else if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED) + if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED) hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24; /* TOFIX: Get input encoding from plat data or fallback to none */ diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 09348c9cbd11..5dfa9d83e2d3 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -125,7 +125,6 @@ struct dw_hdmi_phy_ops { struct dw_hdmi_plat_data { struct regmap *regm; - unsigned long input_bus_format; unsigned long input_bus_encoding; bool use_drm_infoframe; bool ycbcr_420_allowed; -- cgit v1.2.3 From 9bc78d6dc818701e47c5ebd0879877a512f039f0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:52 +0300 Subject: drm: meson: dw-hdmi: Use dw_hdmi context to replace hack The meson-dw-hdmi driver needs to access its own context from the .mode_valid() operation. It currently gets it from the dev_private field of the drm_device retrieved from the connector, which is a hack. Use the private data passed to the .mode_valid() operation instead. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-15-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 5cc311c1b8e0..34ba94922605 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -634,7 +634,8 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, struct drm_connector *connector, const struct drm_display_mode *mode) { - struct meson_drm *priv = connector->dev->dev_private; + struct meson_dw_hdmi *dw_hdmi = data; + struct meson_drm *priv = dw_hdmi->priv; bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported; unsigned int phy_freq; unsigned int vclk_freq; @@ -693,7 +694,7 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, if (mode->flags & DRM_MODE_FLAG_DBLCLK) venc_freq /= 2; - dev_dbg(connector->dev->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", + dev_dbg(dw_hdmi->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq); return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq); @@ -1068,6 +1069,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, /* Bridge / Connector */ + dw_plat_data->priv_data = meson_dw_hdmi; dw_plat_data->mode_valid = dw_hdmi_mode_valid; dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops; dw_plat_data->phy_name = "meson_dw_hdmi_phy"; -- cgit v1.2.3 From af05bba0fbe2c07fe500f697080d78d050be2fbf Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:53 +0300 Subject: drm: bridge: dw-hdmi: Pass drm_display_info to .mode_valid() Replace the drm_connector pointer passed to the .mode_valid() function with a const drm_display_info pointer, as that's all the function should need. Use the display info passed to the bridge .mode_valid() operation instead of retrieving it from the connector, to prepare for make connector creation optional. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-16-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 5 ++--- drivers/gpu/drm/imx/dw_hdmi-imx.c | 4 ++-- drivers/gpu/drm/meson/meson_dw_hdmi.c | 20 ++++++++++---------- drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 4 ++-- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 2 +- include/drm/bridge/dw_hdmi.h | 4 ++-- 8 files changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index adc5a95a06e9..23650e69604c 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2769,7 +2769,6 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, { struct dw_hdmi *hdmi = bridge->driver_private; const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; - struct drm_connector *connector = &hdmi->connector; enum drm_mode_status mode_status = MODE_OK; /* We don't support double-clocked modes */ @@ -2777,8 +2776,8 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, return MODE_BAD; if (pdata->mode_valid) - mode_status = pdata->mode_valid(hdmi, pdata->priv_data, - connector, mode); + mode_status = pdata->mode_valid(hdmi, pdata->priv_data, info, + mode); return mode_status; } diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index 95aed4666c95..2dc93fa6ecb6 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -146,7 +146,7 @@ static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = static enum drm_mode_status imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, - struct drm_connector *con, + const struct drm_display_info *info, const struct drm_display_mode *mode) { if (mode->clock < 13500) @@ -160,7 +160,7 @@ imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, static enum drm_mode_status imx6dl_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, - struct drm_connector *con, + const struct drm_display_info *info, const struct drm_display_mode *mode) { if (mode->clock < 13500) diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 34ba94922605..71d599970ec7 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -631,12 +631,12 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id) static enum drm_mode_status dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, - struct drm_connector *connector, + const struct drm_display_info *display_info, const struct drm_display_mode *mode) { struct meson_dw_hdmi *dw_hdmi = data; struct meson_drm *priv = dw_hdmi->priv; - bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported; + bool is_hdmi2_sink = display_info->hdmi.scdc.supported; unsigned int phy_freq; unsigned int vclk_freq; unsigned int venc_freq; @@ -647,10 +647,10 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); /* If sink does not support 540MHz, reject the non-420 HDMI2 modes */ - if (connector->display_info.max_tmds_clock && - mode->clock > connector->display_info.max_tmds_clock && - !drm_mode_is_420_only(&connector->display_info, mode) && - !drm_mode_is_420_also(&connector->display_info, mode)) + if (display_info->max_tmds_clock && + mode->clock > display_info->max_tmds_clock && + !drm_mode_is_420_only(display_info, mode) && + !drm_mode_is_420_also(display_info, mode)) return MODE_BAD; /* Check against non-VIC supported modes */ @@ -667,9 +667,9 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, vclk_freq = mode->clock; /* For 420, pixel clock is half unlike venc clock */ - if (drm_mode_is_420_only(&connector->display_info, mode) || + if (drm_mode_is_420_only(display_info, mode) || (!is_hdmi2_sink && - drm_mode_is_420_also(&connector->display_info, mode))) + drm_mode_is_420_also(display_info, mode))) vclk_freq /= 2; /* TMDS clock is pixel_clock * 10 */ @@ -684,9 +684,9 @@ dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, /* VENC double pixels for 1080i, 720p and YUV420 modes */ if (meson_venc_hdmi_venc_repeat(vic) || - drm_mode_is_420_only(&connector->display_info, mode) || + drm_mode_is_420_only(display_info, mode) || (!is_hdmi2_sink && - drm_mode_is_420_also(&connector->display_info, mode))) + drm_mode_is_420_also(display_info, mode))) venc_freq *= 2; vclk_freq = max(venc_freq, hdmi_freq); diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c index d0dffe55a7cb..7b8ec8310699 100644 --- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c +++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c @@ -39,7 +39,7 @@ static const struct rcar_hdmi_phy_params rcar_hdmi_phy_params[] = { static enum drm_mode_status rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, - struct drm_connector *connector, + const struct drm_display_info *info, const struct drm_display_mode *mode) { /* diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index d08f86783a28..d286751bb333 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -221,7 +221,7 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) static enum drm_mode_status dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data, - struct drm_connector *connector, + const struct drm_display_info *info, const struct drm_display_mode *mode) { const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg; diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index 0a3637442ba6..d4c08043dd81 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -32,7 +32,7 @@ sun8i_dw_hdmi_encoder_helper_funcs = { static enum drm_mode_status sun8i_dw_hdmi_mode_valid_a83t(struct dw_hdmi *hdmi, void *data, - struct drm_connector *connector, + const struct drm_display_info *info, const struct drm_display_mode *mode) { if (mode->clock > 297000) @@ -43,7 +43,7 @@ sun8i_dw_hdmi_mode_valid_a83t(struct dw_hdmi *hdmi, void *data, static enum drm_mode_status sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data, - struct drm_connector *connector, + const struct drm_display_info *info, const struct drm_display_mode *mode) { /* diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index 8587b8d2590e..d983746fa194 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h @@ -177,7 +177,7 @@ struct sun8i_hdmi_phy { struct sun8i_dw_hdmi_quirks { enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data, - struct drm_connector *connector, + const struct drm_display_info *info, const struct drm_display_mode *mode); unsigned int set_rate : 1; unsigned int use_drm_infoframe : 1; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 5dfa9d83e2d3..fec293b21c2e 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -8,7 +8,7 @@ #include -struct drm_connector; +struct drm_display_info; struct drm_display_mode; struct drm_encoder; struct dw_hdmi; @@ -137,7 +137,7 @@ struct dw_hdmi_plat_data { /* Platform-specific mode validation (optional). */ enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data, - struct drm_connector *connector, + const struct drm_display_info *info, const struct drm_display_mode *mode); /* Vendor PHY support */ -- cgit v1.2.3 From 35a395f1134bbbd2984dcca28c04f09fbbb8b0a4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:54 +0300 Subject: drm: bridge: dw-hdmi: Constify mode argument to dw_hdmi_phy_ops .init() The PHY .init() must not modify the mode it receives. Make the pointer const to enfore that. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-17-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 +- drivers/gpu/drm/meson/meson_dw_hdmi.c | 4 ++-- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 2 +- include/drm/bridge/dw_hdmi.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 23650e69604c..6e6a3d95e68e 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1531,7 +1531,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) } static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { int i, ret; diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 71d599970ec7..757c17fbb29f 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -297,7 +297,7 @@ static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi, /* Setup PHY bandwidth modes */ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { struct meson_drm *priv = dw_hdmi->priv; unsigned int pixel_clock = mode->clock; @@ -427,7 +427,7 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, } static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; struct meson_drm *priv = dw_hdmi->priv; diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index d286751bb333..10e210f6455d 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -312,7 +312,7 @@ static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_fun }; static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 43643ad31730..8e078cacf063 100644 --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c @@ -341,7 +341,7 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi, } static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data; u32 val = 0; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index fec293b21c2e..f930d218cc6b 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -114,7 +114,7 @@ struct dw_hdmi_phy_config { struct dw_hdmi_phy_ops { int (*init)(struct dw_hdmi *hdmi, void *data, - struct drm_display_mode *mode); + const struct drm_display_mode *mode); void (*disable)(struct dw_hdmi *hdmi, void *data); enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data); void (*update_hpd)(struct dw_hdmi *hdmi, void *data, -- cgit v1.2.3 From 9fbfa320b435e6f25499a63f7bb74b4fc5341b30 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:55 +0300 Subject: drm: bridge: dw-hdmi: Constify mode argument to internal functions Several internal functions take a drm_display_mode argument to configure the HDMI encoder or the HDMI PHY. They must not modify the mode, make the pointer const to enforce that. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-18-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 6e6a3d95e68e..5b5f07a23400 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1628,7 +1628,8 @@ static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi) HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1); } -static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) +static void hdmi_config_AVI(struct dw_hdmi *hdmi, + const struct drm_display_mode *mode) { struct hdmi_avi_infoframe frame; u8 val; @@ -1756,7 +1757,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) } static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { struct hdmi_vendor_infoframe frame; u8 buffer[10]; @@ -2112,7 +2113,8 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) HDMI_IH_MUTE_FC_STAT2); } -static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) +static int dw_hdmi_setup(struct dw_hdmi *hdmi, + const struct drm_display_mode *mode) { int ret; -- cgit v1.2.3 From 7be390d4c0a125266c558c30a3687d931c3b6101 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:56 +0300 Subject: drm: bridge: dw-hdmi: Pass drm_display_info to dw_hdmi_support_scdc() To prepare for making connector creation optional in the driver, pass the drm_display_info explicitly to dw_hdmi_support_scdc(). The pointer is passed to the callers where required, particularly to the dw_hdmi_phy_ops .init() function. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-19-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 32 +++++++++++++++++------------ drivers/gpu/drm/meson/meson_dw_hdmi.c | 3 ++- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 1 + drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 1 + include/drm/bridge/dw_hdmi.h | 4 +++- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 5b5f07a23400..a18794cce0d8 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1241,10 +1241,9 @@ void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write); /* Filter out invalid setups to avoid configuring SCDC and scrambling */ -static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi) +static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi, + const struct drm_display_info *display) { - struct drm_display_info *display = &hdmi->connector.display_info; - /* Completely disable SCDC support for older controllers */ if (hdmi->version < 0x200a) return false; @@ -1282,12 +1281,13 @@ static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi) * helper should called right before enabling the TMDS Clock and Data in * the PHY configuration callback. */ -void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi) +void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi, + const struct drm_display_info *display) { unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock; /* Control for TMDS Bit Period/TMDS Clock-Period Ratio */ - if (dw_hdmi_support_scdc(hdmi)) { + if (dw_hdmi_support_scdc(hdmi, display)) { if (mtmdsclock > HDMI14_MAX_TMDSCLK) drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 1); else @@ -1490,7 +1490,8 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, return 0; } -static int hdmi_phy_configure(struct dw_hdmi *hdmi) +static int hdmi_phy_configure(struct dw_hdmi *hdmi, + const struct drm_display_info *display) { const struct dw_hdmi_phy_data *phy = hdmi->phy.data; const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; @@ -1500,7 +1501,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) dw_hdmi_phy_power_off(hdmi); - dw_hdmi_set_high_tmds_clock_ratio(hdmi); + dw_hdmi_set_high_tmds_clock_ratio(hdmi, display); /* Leave low power consumption mode by asserting SVSRET. */ if (phy->has_svsret) @@ -1531,6 +1532,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) } static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, + const struct drm_display_info *display, const struct drm_display_mode *mode) { int i, ret; @@ -1540,7 +1542,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, dw_hdmi_phy_sel_data_en_pol(hdmi, 1); dw_hdmi_phy_sel_interface_control(hdmi, 0); - ret = hdmi_phy_configure(hdmi); + ret = hdmi_phy_configure(hdmi, display); if (ret) return ret; } @@ -1846,10 +1848,11 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi) } static void hdmi_av_composer(struct dw_hdmi *hdmi, + const struct drm_display_info *display, const struct drm_display_mode *mode) { u8 inv_val, bytes; - struct drm_hdmi_info *hdmi_info = &hdmi->connector.display_info.hdmi; + const struct drm_hdmi_info *hdmi_info = &display->hdmi; struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode; int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len; unsigned int vdisplay, hdisplay; @@ -1882,7 +1885,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, /* Set up HDMI_FC_INVIDCONF */ inv_val = (hdmi->hdmi_data.hdcp_enable || - (dw_hdmi_support_scdc(hdmi) && + (dw_hdmi_support_scdc(hdmi, display) && (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK || hdmi_info->scdc.scrambling.low_rates)) ? HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : @@ -1950,7 +1953,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, } /* Scrambling Control */ - if (dw_hdmi_support_scdc(hdmi)) { + if (dw_hdmi_support_scdc(hdmi, display)) { if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK || hdmi_info->scdc.scrambling.low_rates) { /* @@ -2116,6 +2119,7 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) static int dw_hdmi_setup(struct dw_hdmi *hdmi, const struct drm_display_mode *mode) { + struct drm_connector *connector = &hdmi->connector; int ret; hdmi_disable_overflow_interrupts(hdmi); @@ -2161,10 +2165,12 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, hdmi->hdmi_data.video_mode.mdataenablepolarity = true; /* HDMI Initialization Step B.1 */ - hdmi_av_composer(hdmi, mode); + hdmi_av_composer(hdmi, &connector->display_info, mode); /* HDMI Initializateion Step B.2 */ - ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode); + ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, + &connector->display_info, + &hdmi->previous_mode); if (ret) return ret; hdmi->phy.enabled = true; diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 757c17fbb29f..15e62f327894 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -427,6 +427,7 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, } static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, + const struct drm_display_info *display, const struct drm_display_mode *mode) { struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; @@ -496,7 +497,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, /* Disable clock, fifo, fifo_wr */ regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0); - dw_hdmi_set_high_tmds_clock_ratio(hdmi); + dw_hdmi_set_high_tmds_clock_ratio(hdmi, display); msleep(100); diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 10e210f6455d..23de359a1dec 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -312,6 +312,7 @@ static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_fun }; static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, + const struct drm_display_info *display, const struct drm_display_mode *mode) { struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 8e078cacf063..156d00e5165b 100644 --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c @@ -341,6 +341,7 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi, } static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data, + const struct drm_display_info *display, const struct drm_display_mode *mode) { struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index f930d218cc6b..ea34ca146b82 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -114,6 +114,7 @@ struct dw_hdmi_phy_config { struct dw_hdmi_phy_ops { int (*init)(struct dw_hdmi *hdmi, void *data, + const struct drm_display_info *display, const struct drm_display_mode *mode); void (*disable)(struct dw_hdmi *hdmi, void *data); enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data); @@ -174,7 +175,8 @@ void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8 *channel_status); void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca); void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); -void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi); +void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi, + const struct drm_display_info *display); /* PHY configuration */ void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address); -- cgit v1.2.3 From 3f588fda4b80dbd7dafa08b0e16fd72a42676e3c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:57 +0300 Subject: drm: bridge: dw-hdmi: Split connector creation to a separate function Isolate all the code related to connector creation to a new dw_hdmi_connector_create() function, to prepare for making connector creation optional. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-20-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 107 +++++++++++++++++------------- 1 file changed, 62 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index a18794cce0d8..35d38b644912 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2317,6 +2317,10 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi) hdmi->rxsense); } +/* ----------------------------------------------------------------------------- + * DRM Connector Operations + */ + static enum drm_connector_status dw_hdmi_connector_detect(struct drm_connector *connector, bool force) { @@ -2438,6 +2442,59 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = .atomic_check = dw_hdmi_connector_atomic_check, }; +static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) +{ + struct drm_connector *connector = &hdmi->connector; + struct cec_connector_info conn_info; + struct cec_notifier *notifier; + + if (hdmi->version >= 0x200a) + connector->ycbcr_420_allowed = + hdmi->plat_data->ycbcr_420_allowed; + else + connector->ycbcr_420_allowed = false; + + connector->interlace_allowed = 1; + connector->polled = DRM_CONNECTOR_POLL_HPD; + + drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs); + + drm_connector_init_with_ddc(hdmi->bridge.dev, connector, + &dw_hdmi_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA, + hdmi->ddc); + + /* + * drm_connector_attach_max_bpc_property() requires the + * connector to have a state. + */ + drm_atomic_helper_connector_reset(connector); + + drm_connector_attach_max_bpc_property(connector, 8, 16); + + if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe) + drm_object_attach_property(&connector->base, + connector->dev->mode_config.hdr_output_metadata_property, 0); + + drm_connector_attach_encoder(connector, hdmi->bridge.encoder); + + cec_fill_conn_info_from_drm(&conn_info, connector); + + notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info); + if (!notifier) + return -ENOMEM; + + mutex_lock(&hdmi->cec_notifier_mutex); + hdmi->cec_notifier = notifier; + mutex_unlock(&hdmi->cec_notifier_mutex); + + return 0; +} + +/* ----------------------------------------------------------------------------- + * DRM Bridge Operations + */ + /* * Possible output formats : * - MEDIA_BUS_FMT_UYYVYY16_0_5X48, @@ -2713,51 +2770,13 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { struct dw_hdmi *hdmi = bridge->driver_private; - struct drm_encoder *encoder = bridge->encoder; - struct drm_connector *connector = &hdmi->connector; - struct cec_connector_info conn_info; - struct cec_notifier *notifier; if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { DRM_ERROR("Fix bridge driver to make connector optional!"); return -EINVAL; } - connector->interlace_allowed = 1; - connector->polled = DRM_CONNECTOR_POLL_HPD; - - drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs); - - drm_connector_init_with_ddc(bridge->dev, connector, - &dw_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA, - hdmi->ddc); - - /* - * drm_connector_attach_max_bpc_property() requires the - * connector to have a state. - */ - drm_atomic_helper_connector_reset(connector); - - drm_connector_attach_max_bpc_property(connector, 8, 16); - - if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe) - drm_object_attach_property(&connector->base, - connector->dev->mode_config.hdr_output_metadata_property, 0); - - drm_connector_attach_encoder(connector, encoder); - - cec_fill_conn_info_from_drm(&conn_info, connector); - - notifier = cec_notifier_conn_register(hdmi->dev, NULL, &conn_info); - if (!notifier) - return -ENOMEM; - - mutex_lock(&hdmi->cec_notifier_mutex); - hdmi->cec_notifier = notifier; - mutex_unlock(&hdmi->cec_notifier_mutex); - - return 0; + return dw_hdmi_connector_create(hdmi); } static void dw_hdmi_bridge_detach(struct drm_bridge *bridge) @@ -2841,6 +2860,10 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { .mode_valid = dw_hdmi_bridge_mode_valid, }; +/* ----------------------------------------------------------------------------- + * IRQ Handling + */ + static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi) { struct dw_hdmi_i2c *i2c = hdmi->i2c; @@ -3303,12 +3326,6 @@ __dw_hdmi_probe(struct platform_device *pdev, hdmi->bridge.of_node = pdev->dev.of_node; #endif - if (hdmi->version >= 0x200a) - hdmi->connector.ycbcr_420_allowed = - hdmi->plat_data->ycbcr_420_allowed; - else - hdmi->connector.ycbcr_420_allowed = false; - memset(&pdevinfo, 0, sizeof(pdevinfo)); pdevinfo.parent = dev; pdevinfo.id = PLATFORM_DEVID_AUTO; -- cgit v1.2.3 From ca7b6b7176ffea4d07afbd98ede7a94fb0f68fa1 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:58 +0300 Subject: drm: bridge: dw-hdmi: Store current connector in struct dw_hdmi Store the connector that the bridge is currently wired to in the dw_hdmi structure. This is currently identical to the connector field, but will differ once the driver supports disabling connector creation. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-21-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 35d38b644912..16bffedb4715 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -181,6 +181,7 @@ struct dw_hdmi { struct mutex mutex; /* for state below and previous_mode */ enum drm_connector_force force; /* mutex-protected force state */ + struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */ bool disabled; /* DRM has disabled our bridge */ bool bridge_is_on; /* indicates the bridge is on */ bool rxsense; /* rxsense state */ @@ -2823,23 +2824,32 @@ static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, mutex_unlock(&hdmi->mutex); } -static void dw_hdmi_bridge_disable(struct drm_bridge *bridge) +static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_state) { struct dw_hdmi *hdmi = bridge->driver_private; mutex_lock(&hdmi->mutex); hdmi->disabled = true; + hdmi->curr_conn = NULL; dw_hdmi_update_power(hdmi); dw_hdmi_update_phy_mask(hdmi); mutex_unlock(&hdmi->mutex); } -static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) +static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_state) { struct dw_hdmi *hdmi = bridge->driver_private; + struct drm_atomic_state *state = old_state->base.state; + struct drm_connector *connector; + + connector = drm_atomic_get_new_connector_for_encoder(state, + bridge->encoder); mutex_lock(&hdmi->mutex); hdmi->disabled = false; + hdmi->curr_conn = connector; dw_hdmi_update_power(hdmi); dw_hdmi_update_phy_mask(hdmi); mutex_unlock(&hdmi->mutex); @@ -2854,8 +2864,8 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { .atomic_check = dw_hdmi_bridge_atomic_check, .atomic_get_output_bus_fmts = dw_hdmi_bridge_atomic_get_output_bus_fmts, .atomic_get_input_bus_fmts = dw_hdmi_bridge_atomic_get_input_bus_fmts, - .enable = dw_hdmi_bridge_enable, - .disable = dw_hdmi_bridge_disable, + .atomic_enable = dw_hdmi_bridge_atomic_enable, + .atomic_disable = dw_hdmi_bridge_atomic_disable, .mode_set = dw_hdmi_bridge_mode_set, .mode_valid = dw_hdmi_bridge_mode_valid, }; -- cgit v1.2.3 From 81980037fb275d9db1bbb0239682d707e8dd62a0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:14:59 +0300 Subject: drm: bridge: dw-hdmi: Pass drm_connector to internal functions as needed To prepare for making connector creation optional in the driver, pass the drm_connector explicitly to the internal functions that require it. The functions that still access the connector from the dw_hdmi structure are dw_hdmi_connector_create() and __dw_hdmi_probe(). The former access is expected, as that's where the internal connector is created. The latter will be addressed separately. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-22-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 16bffedb4715..b69c14b9de62 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1632,18 +1632,17 @@ static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi) } static void hdmi_config_AVI(struct dw_hdmi *hdmi, + const struct drm_connector *connector, const struct drm_display_mode *mode) { struct hdmi_avi_infoframe frame; u8 val; /* Initialise info frame from DRM mode */ - drm_hdmi_avi_infoframe_from_display_mode(&frame, - &hdmi->connector, mode); + drm_hdmi_avi_infoframe_from_display_mode(&frame, connector, mode); if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { - drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector, - mode, + drm_hdmi_avi_infoframe_quant_range(&frame, connector, mode, hdmi->hdmi_data.rgb_limited_range ? HDMI_QUANTIZATION_RANGE_LIMITED : HDMI_QUANTIZATION_RANGE_FULL); @@ -1760,14 +1759,14 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, } static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, + const struct drm_connector *connector, const struct drm_display_mode *mode) { struct hdmi_vendor_infoframe frame; u8 buffer[10]; ssize_t err; - err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, - &hdmi->connector, + err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, connector, mode); if (err < 0) /* @@ -1813,9 +1812,10 @@ static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, HDMI_FC_DATAUTO0_VSD_MASK); } -static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi) +static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi, + const struct drm_connector *connector) { - const struct drm_connector_state *conn_state = hdmi->connector.state; + const struct drm_connector_state *conn_state = connector->state; struct hdmi_drm_infoframe frame; u8 buffer[30]; ssize_t err; @@ -2118,9 +2118,9 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) } static int dw_hdmi_setup(struct dw_hdmi *hdmi, + const struct drm_connector *connector, const struct drm_display_mode *mode) { - struct drm_connector *connector = &hdmi->connector; int ret; hdmi_disable_overflow_interrupts(hdmi); @@ -2192,9 +2192,9 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__); /* HDMI Initialization Step F - Configure AVI InfoFrame */ - hdmi_config_AVI(hdmi, mode); - hdmi_config_vendor_specific_infoframe(hdmi, mode); - hdmi_config_drm_infoframe(hdmi); + hdmi_config_AVI(hdmi, connector, mode); + hdmi_config_vendor_specific_infoframe(hdmi, connector, mode); + hdmi_config_drm_infoframe(hdmi, connector); } else { dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); } @@ -2263,7 +2263,12 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi) static void dw_hdmi_poweron(struct dw_hdmi *hdmi) { hdmi->bridge_is_on = true; - dw_hdmi_setup(hdmi, &hdmi->previous_mode); + + /* + * The curr_conn field is guaranteed to be valid here, as this function + * is only be called when !hdmi->disabled. + */ + dw_hdmi_setup(hdmi, hdmi->curr_conn, &hdmi->previous_mode); } static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) -- cgit v1.2.3 From ec971aaa6775cff555b4f58777ceab1d9a8370e0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 26 May 2020 04:15:00 +0300 Subject: drm: bridge: dw-hdmi: Make connector creation optional Implement the drm_bridge_funcs .detect() and .get_edid() operations, and call drm_bridge_hpd_notify() notify to report HPD. This provides the necessary API to support disabling connector creation, do so by accepting DRM_BRIDGE_ATTACH_NO_CONNECTOR in dw_hdmi_bridge_attach(). Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200526011505.31884-23-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 104 +++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index b69c14b9de62..6148a022569a 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2323,15 +2323,8 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi) hdmi->rxsense); } -/* ----------------------------------------------------------------------------- - * DRM Connector Operations - */ - -static enum drm_connector_status -dw_hdmi_connector_detect(struct drm_connector *connector, bool force) +static enum drm_connector_status dw_hdmi_detect(struct dw_hdmi *hdmi) { - struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, - connector); enum drm_connector_status result; mutex_lock(&hdmi->mutex); @@ -2354,31 +2347,57 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) return result; } -static int dw_hdmi_connector_get_modes(struct drm_connector *connector) +static struct edid *dw_hdmi_get_edid(struct dw_hdmi *hdmi, + struct drm_connector *connector) { - struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, - connector); struct edid *edid; - int ret = 0; if (!hdmi->ddc) - return 0; + return NULL; edid = drm_get_edid(connector, hdmi->ddc); - if (edid) { - dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", - edid->width_cm, edid->height_cm); - - hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); - hdmi->sink_has_audio = drm_detect_monitor_audio(edid); - drm_connector_update_edid_property(connector, edid); - cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); - ret = drm_add_edid_modes(connector, edid); - kfree(edid); - } else { + if (!edid) { dev_dbg(hdmi->dev, "failed to get edid\n"); + return NULL; } + dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", + edid->width_cm, edid->height_cm); + + hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); + hdmi->sink_has_audio = drm_detect_monitor_audio(edid); + + return edid; +} + +/* ----------------------------------------------------------------------------- + * DRM Connector Operations + */ + +static enum drm_connector_status +dw_hdmi_connector_detect(struct drm_connector *connector, bool force) +{ + struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, + connector); + return dw_hdmi_detect(hdmi); +} + +static int dw_hdmi_connector_get_modes(struct drm_connector *connector) +{ + struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, + connector); + struct edid *edid; + int ret; + + edid = dw_hdmi_get_edid(hdmi, connector); + if (!edid) + return 0; + + drm_connector_update_edid_property(connector, edid); + cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); + ret = drm_add_edid_modes(connector, edid); + kfree(edid); + return ret; } @@ -2777,10 +2796,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge, { struct dw_hdmi *hdmi = bridge->driver_private; - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { - DRM_ERROR("Fix bridge driver to make connector optional!"); - return -EINVAL; - } + if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) + return 0; return dw_hdmi_connector_create(hdmi); } @@ -2860,6 +2877,21 @@ static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge, mutex_unlock(&hdmi->mutex); } +static enum drm_connector_status dw_hdmi_bridge_detect(struct drm_bridge *bridge) +{ + struct dw_hdmi *hdmi = bridge->driver_private; + + return dw_hdmi_detect(hdmi); +} + +static struct edid *dw_hdmi_bridge_get_edid(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + struct dw_hdmi *hdmi = bridge->driver_private; + + return dw_hdmi_get_edid(hdmi, connector); +} + static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, @@ -2873,6 +2905,8 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { .atomic_disable = dw_hdmi_bridge_atomic_disable, .mode_set = dw_hdmi_bridge_mode_set, .mode_valid = dw_hdmi_bridge_mode_valid, + .detect = dw_hdmi_bridge_detect, + .get_edid = dw_hdmi_bridge_get_edid, }; /* ----------------------------------------------------------------------------- @@ -2988,10 +3022,18 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) } if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { + enum drm_connector_status status = phy_int_pol & HDMI_PHY_HPD + ? connector_status_connected + : connector_status_disconnected; + dev_dbg(hdmi->dev, "EVENT=%s\n", - phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout"); - if (hdmi->bridge.dev) + status == connector_status_connected ? + "plugin" : "plugout"); + + if (hdmi->bridge.dev) { drm_helper_hpd_irq_event(hdmi->bridge.dev); + drm_bridge_hpd_notify(&hdmi->bridge, status); + } } hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); @@ -3337,6 +3379,8 @@ __dw_hdmi_probe(struct platform_device *pdev, hdmi->bridge.driver_private = hdmi; hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; + hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID + | DRM_BRIDGE_OP_HPD; #ifdef CONFIG_OF hdmi->bridge.of_node = pdev->dev.of_node; #endif -- cgit v1.2.3 From e8411b7ede3bd59f45a7ad997536d235e9c71c36 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 12 Jun 2020 18:00:56 +0200 Subject: drm/tiny/repaper: Drop edp->enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same patch as the mipi-dbi one, atomic tracks this for us already, we just have to check the right thing. Reviewed-by: Noralf Trønnes Reviewed-by: Emil Velikov Signed-off-by: Daniel Vetter Cc: "Noralf Trønnes" Link: https://patchwork.freedesktop.org/patch/msgid/20200612160056.2082681-8-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tiny/repaper.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c index 08164e2a2d13..2e01cf0a9876 100644 --- a/drivers/gpu/drm/tiny/repaper.c +++ b/drivers/gpu/drm/tiny/repaper.c @@ -88,7 +88,6 @@ struct repaper_epd { u8 *line_buffer; void *current_frame; - bool enabled; bool cleared; bool partial; }; @@ -538,9 +537,6 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb) int idx, ret = 0; u8 *buf = NULL; - if (!epd->enabled) - return 0; - if (!drm_dev_enter(fb->dev, &idx)) return -ENODEV; @@ -786,7 +782,6 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, */ repaper_write_val(spi, 0x02, 0x04); - epd->enabled = true; epd->partial = false; out_exit: drm_dev_exit(idx); @@ -805,13 +800,8 @@ static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe) * unplug. */ - if (!epd->enabled) - return; - DRM_DEBUG_DRIVER("\n"); - epd->enabled = false; - /* Nothing frame */ for (line = 0; line < epd->height; line++) repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL, @@ -859,6 +849,9 @@ static void repaper_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *state = pipe->plane.state; struct drm_rect rect; + if (!pipe->crtc.state->active) + return; + if (drm_atomic_helper_damage_merged(old_state, state, &rect)) repaper_fb_dirty(state->fb); } -- cgit v1.2.3 From 7e06886bbfca73717e45a0f20cdb4053793c191b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 12 Jun 2020 18:00:55 +0200 Subject: drm/mipi-dbi: Remove ->enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The atomic helpers try really hard to not lose track of things, duplicating enabled tracking in the driver is at best confusing. Double-enabling or disabling is a bug in atomic helpers. In the fb_dirty function we can just assume that the fb always exists, simple display pipe helpers guarantee that the crtc is only enabled together with the output, so we always have a primary plane around. Now in the update function we need to be a notch more careful, since that can also get called when the crtc is off. And we don't want to upload frames when that's the case, so filter that out too. Reviewed-by: Noralf Trønnes Acked-by: David Lechner Reviewed-by: Emil Velikov Signed-off-by: Daniel Vetter Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Cc: David Lechner Link: https://patchwork.freedesktop.org/patch/msgid/20200612160056.2082681-7-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_mipi_dbi.c | 16 ++++++---------- drivers/gpu/drm/tiny/ili9225.c | 12 +++--------- drivers/gpu/drm/tiny/st7586.c | 11 +++-------- include/drm/drm_mipi_dbi.h | 5 ----- 4 files changed, 12 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index fd8d672972a9..79532b9a324a 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -268,7 +268,7 @@ static void mipi_dbi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect) bool full; void *tr; - if (!dbidev->enabled) + if (WARN_ON(!fb)) return; if (!drm_dev_enter(fb->dev, &idx)) @@ -314,6 +314,9 @@ void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *state = pipe->plane.state; struct drm_rect rect; + if (!pipe->crtc.state->active) + return; + if (drm_atomic_helper_damage_merged(old_state, state, &rect)) mipi_dbi_fb_dirty(state->fb, &rect); } @@ -325,9 +328,8 @@ EXPORT_SYMBOL(mipi_dbi_pipe_update); * @crtc_state: CRTC state * @plane_state: Plane state * - * This function sets &mipi_dbi->enabled, flushes the whole framebuffer and - * enables the backlight. Drivers can use this in their - * &drm_simple_display_pipe_funcs->enable callback. + * Flushes the whole framebuffer and enables the backlight. Drivers can use this + * in their &drm_simple_display_pipe_funcs->enable callback. * * Note: Drivers which don't use mipi_dbi_pipe_update() because they have custom * framebuffer flushing, can't use this function since they both use the same @@ -349,7 +351,6 @@ void mipi_dbi_enable_flush(struct mipi_dbi_dev *dbidev, if (!drm_dev_enter(&dbidev->drm, &idx)) return; - dbidev->enabled = true; mipi_dbi_fb_dirty(fb, &rect); backlight_enable(dbidev->backlight); @@ -390,13 +391,8 @@ void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe) { struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); - if (!dbidev->enabled) - return; - DRM_DEBUG_KMS("\n"); - dbidev->enabled = false; - if (dbidev->backlight) backlight_disable(dbidev->backlight); else diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c index 16400064320f..97a77262d791 100644 --- a/drivers/gpu/drm/tiny/ili9225.c +++ b/drivers/gpu/drm/tiny/ili9225.c @@ -89,9 +89,6 @@ static void ili9225_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect) bool full; void *tr; - if (!dbidev->enabled) - return; - if (!drm_dev_enter(fb->dev, &idx)) return; @@ -167,6 +164,9 @@ static void ili9225_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *state = pipe->plane.state; struct drm_rect rect; + if (!pipe->crtc.state->active) + return; + if (drm_atomic_helper_damage_merged(old_state, state, &rect)) ili9225_fb_dirty(state->fb, &rect); } @@ -275,7 +275,6 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe, ili9225_command(dbi, ILI9225_DISPLAY_CONTROL_1, 0x1017); - dbidev->enabled = true; ili9225_fb_dirty(fb, &rect); out_exit: drm_dev_exit(idx); @@ -295,16 +294,11 @@ static void ili9225_pipe_disable(struct drm_simple_display_pipe *pipe) * unplug. */ - if (!dbidev->enabled) - return; - ili9225_command(dbi, ILI9225_DISPLAY_CONTROL_1, 0x0000); msleep(50); ili9225_command(dbi, ILI9225_POWER_CONTROL_2, 0x0007); msleep(50); ili9225_command(dbi, ILI9225_POWER_CONTROL_1, 0x0a02); - - dbidev->enabled = false; } static int ili9225_dbi_command(struct mipi_dbi *dbi, u8 *cmd, u8 *par, diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c index 1311e5df8721..d05de03891f8 100644 --- a/drivers/gpu/drm/tiny/st7586.c +++ b/drivers/gpu/drm/tiny/st7586.c @@ -118,9 +118,6 @@ static void st7586_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect) struct mipi_dbi *dbi = &dbidev->dbi; int start, end, idx, ret = 0; - if (!dbidev->enabled) - return; - if (!drm_dev_enter(fb->dev, &idx)) return; @@ -161,6 +158,9 @@ static void st7586_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *state = pipe->plane.state; struct drm_rect rect; + if (!pipe->crtc.state->active) + return; + if (drm_atomic_helper_damage_merged(old_state, state, &rect)) st7586_fb_dirty(state->fb, &rect); } @@ -237,7 +237,6 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe, msleep(100); - dbidev->enabled = true; st7586_fb_dirty(fb, &rect); mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON); @@ -258,11 +257,7 @@ static void st7586_pipe_disable(struct drm_simple_display_pipe *pipe) DRM_DEBUG_KMS("\n"); - if (!dbidev->enabled) - return; - mipi_dbi_command(&dbidev->dbi, MIPI_DCS_SET_DISPLAY_OFF); - dbidev->enabled = false; } static const u32 st7586_formats[] = { diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h index 4d0e49c0ed2c..c2827ceaba0d 100644 --- a/include/drm/drm_mipi_dbi.h +++ b/include/drm/drm_mipi_dbi.h @@ -94,11 +94,6 @@ struct mipi_dbi_dev { */ struct drm_display_mode mode; - /** - * @enabled: Pipeline is enabled - */ - bool enabled; - /** * @tx_buf: Buffer used for transfer (copy clip rect area) */ -- cgit v1.2.3 From 102514ec73ed54b2681ff225e78e965e4fbe43ef Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 12 Jun 2020 09:05:35 +0200 Subject: dma-buf: minor doc touch-ups Just some tiny edits: - fix link to struct dma_fence - give slightly more meaningful title - the polling here is about implicit fences, explicit fences (in sync_file or drm_syncobj) also have their own polling v2: I misplaced the .rst include change corresponding to this patch. Reviewed-by: Thomas Hellstrom Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20200612070535.1778368-1-daniel.vetter@ffwll.ch --- Documentation/driver-api/dma-buf.rst | 6 +++--- drivers/dma-buf/dma-buf.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst index 63dec76d1d8d..7fb7b661febd 100644 --- a/Documentation/driver-api/dma-buf.rst +++ b/Documentation/driver-api/dma-buf.rst @@ -100,11 +100,11 @@ CPU Access to DMA Buffer Objects .. kernel-doc:: drivers/dma-buf/dma-buf.c :doc: cpu access -Fence Poll Support -~~~~~~~~~~~~~~~~~~ +Implicit Fence Poll Support +~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. kernel-doc:: drivers/dma-buf/dma-buf.c - :doc: fence polling + :doc: implicit fence polling Kernel Functions and Structures Reference ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 570c923023e6..7ca24080fea0 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -161,11 +161,11 @@ static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence) } /** - * DOC: fence polling + * DOC: implicit fence polling * * To support cross-device and cross-driver synchronization of buffer access - * implicit fences (represented internally in the kernel with &struct fence) can - * be attached to a &dma_buf. The glue for that and a few related things are + * implicit fences (represented internally in the kernel with &struct dma_fence) + * can be attached to a &dma_buf. The glue for that and a few related things are * provided in the &dma_resv structure. * * Userspace can query the state of these implicitly tracked fences using poll() -- cgit v1.2.3 From ebf93015097367d4de77deea5d4d9b657dbf7a49 Mon Sep 17 00:00:00 2001 From: Angelo Ribeiro Date: Fri, 3 Apr 2020 15:30:36 +0200 Subject: drm/bridge: dw-mipi-dsi.c: remove unused header file dw-mipi-dsi does not use any definition from drm_probe_helper. Coverity output: Event unnecessary_header: Including .../include/drm/drm_probe_helper.h does not provide any needed symbols. Reviewed-by: Yannick Fertre Cc: Gustavo Pimentel Cc: Joao Pinto Cc: Jose Abreu Signed-off-by: Angelo Ribeiro Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/171ff1fb3918664a570dc8f2f34b446612505f76.1585832665.git.angelo.ribeiro@synopsys.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index c223fb9a04cb..d580b2aa4ce9 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -27,7 +27,6 @@ #include #include #include -#include #define HWVER_131 0x31333100 /* IP version 1.31 */ -- cgit v1.2.3 From b1a8ef952a25a926869deca08b74874ecfadf7ad Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 24 Jun 2020 20:26:41 +0200 Subject: drm/amdgpu: move ttm bo->offset to amdgpu_bo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GPU address should belong to driver not in memory management. This patch moves ttm bo.offset and gpu_offset calculation to amdgpu driver. Signed-off-by: Nirmoy Das Acked-by: Huang Rui Reviewed-by: Christian König Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/372930/ --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 23 ++++++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 30 ++++++++++++++++++++++------- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c | 4 ++-- 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index c687f5415b3f..a27b6a692119 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -918,7 +918,8 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, bo->pin_count++; if (max_offset != 0) { - u64 domain_start = bo->tbo.bdev->man[mem_type].gpu_offset; + u64 domain_start = amdgpu_ttm_domain_start(adev, + mem_type); WARN_ON_ONCE(max_offset < (amdgpu_bo_gpu_offset(bo) - domain_start)); } @@ -1484,7 +1485,25 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM && !(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)); - return amdgpu_gmc_sign_extend(bo->tbo.offset); + return amdgpu_bo_gpu_offset_no_check(bo); +} + +/** + * amdgpu_bo_gpu_offset_no_check - return GPU offset of bo + * @bo: amdgpu object for which we query the offset + * + * Returns: + * current GPU offset of the object without raising warnings. + */ +u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo) +{ + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); + uint64_t offset; + + offset = (bo->tbo.mem.start << PAGE_SHIFT) + + amdgpu_ttm_domain_start(adev, bo->tbo.mem.mem_type); + + return amdgpu_gmc_sign_extend(offset); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 5e39ecd8cc28..32edd35d2ccf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -282,6 +282,7 @@ int amdgpu_bo_sync_wait_resv(struct amdgpu_device *adev, struct dma_resv *resv, bool intr); int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr); u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo); +u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo); int amdgpu_bo_validate(struct amdgpu_bo *bo); int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow, struct dma_fence **fence); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 6309ff72bd78..c2e13e1ec53e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -96,7 +96,6 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, case TTM_PL_TT: /* GTT memory */ man->func = &amdgpu_gtt_mgr_func; - man->gpu_offset = adev->gmc.gart_start; man->available_caching = TTM_PL_MASK_CACHING; man->default_caching = TTM_PL_FLAG_CACHED; man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA; @@ -104,7 +103,6 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, case TTM_PL_VRAM: /* "On-card" video ram */ man->func = &amdgpu_vram_mgr_func; - man->gpu_offset = adev->gmc.vram_start; man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE; man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; @@ -115,7 +113,6 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, case AMDGPU_PL_OA: /* On-chip GDS memory*/ man->func = &ttm_bo_manager_func; - man->gpu_offset = 0; man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_CMA; man->available_caching = TTM_PL_FLAG_UNCACHED; man->default_caching = TTM_PL_FLAG_UNCACHED; @@ -263,7 +260,8 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, if (mm_node->start != AMDGPU_BO_INVALID_OFFSET) { addr = mm_node->start << PAGE_SHIFT; - addr += bo->bdev->man[mem->mem_type].gpu_offset; + addr += amdgpu_ttm_domain_start(amdgpu_ttm_adev(bo->bdev), + mem->mem_type); } return addr; } @@ -750,6 +748,27 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo, (offset >> PAGE_SHIFT); } +/** + * amdgpu_ttm_domain_start - Returns GPU start address + * @adev: amdgpu device object + * @type: type of the memory + * + * Returns: + * GPU start address of a memory domain + */ + +uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type) +{ + switch (type) { + case TTM_PL_TT: + return adev->gmc.gart_start; + case TTM_PL_VRAM: + return adev->gmc.vram_start; + } + + return 0; +} + /* * TTM backend functions. */ @@ -1163,9 +1182,6 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) bo->mem = tmp; } - bo->offset = (bo->mem.start << PAGE_SHIFT) + - bo->bdev->man[bo->mem.mem_type].gpu_offset; - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index 6b22dc41ef13..b6086ab21069 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -112,6 +112,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo, int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma); int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo); int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo); +uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type); #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR) int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c index cf96c335b258..2a7a6f62d627 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c @@ -141,7 +141,7 @@ static void amdgpu_vm_sdma_copy_ptes(struct amdgpu_vm_update_params *p, src += p->num_dw_left * 4; - pe += amdgpu_gmc_sign_extend(bo->tbo.offset); + pe += amdgpu_bo_gpu_offset_no_check(bo); trace_amdgpu_vm_copy_ptes(pe, src, count, p->direct); amdgpu_vm_copy_pte(p->adev, ib, pe, src, count); @@ -168,7 +168,7 @@ static void amdgpu_vm_sdma_set_ptes(struct amdgpu_vm_update_params *p, { struct amdgpu_ib *ib = p->job->ibs; - pe += amdgpu_gmc_sign_extend(bo->tbo.offset); + pe += amdgpu_bo_gpu_offset_no_check(bo); trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->direct); if (count < 3) { amdgpu_vm_write_pte(p->adev, ib, pe, addr | flags, -- cgit v1.2.3 From a0e4a29857b1acca6a4e724a42b9fdb76ae2d560 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 24 Jun 2020 20:26:42 +0200 Subject: drm/radeon: don't use ttm bo->offset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calculate GPU offset in radeon_bo_gpu_offset without depending on bo->offset. Signed-off-by: Nirmoy Das Reviewed-and-tested-by: Christian König Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/372935/ --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_object.h | 16 +++++++++++++++- drivers/gpu/drm/radeon/radeon_ttm.c | 4 +--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 30e32adc1fc6..b7c3fb2bfb54 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -2828,6 +2828,7 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size extern void radeon_program_register_sequence(struct radeon_device *rdev, const u32 *registers, const u32 array_size); +struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev); /* * vm diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index d23f2ed4126e..60275b822f79 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -90,7 +90,21 @@ static inline void radeon_bo_unreserve(struct radeon_bo *bo) */ static inline u64 radeon_bo_gpu_offset(struct radeon_bo *bo) { - return bo->tbo.offset; + struct radeon_device *rdev; + u64 start = 0; + + rdev = radeon_get_rdev(bo->tbo.bdev); + + switch (bo->tbo.mem.mem_type) { + case TTM_PL_TT: + start = rdev->mc.gtt_start; + break; + case TTM_PL_VRAM: + start = rdev->mc.vram_start; + break; + } + + return (bo->tbo.mem.start << PAGE_SHIFT) + start; } static inline unsigned long radeon_bo_size(struct radeon_bo *bo) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 5d50c9edbe80..357e8e98cca9 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -56,7 +56,7 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev); static void radeon_ttm_debugfs_fini(struct radeon_device *rdev); -static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) +struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) { struct radeon_mman *mman; struct radeon_device *rdev; @@ -82,7 +82,6 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, break; case TTM_PL_TT: man->func = &ttm_bo_manager_func; - man->gpu_offset = rdev->mc.gtt_start; man->available_caching = TTM_PL_MASK_CACHING; man->default_caching = TTM_PL_FLAG_CACHED; man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA; @@ -104,7 +103,6 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, case TTM_PL_VRAM: /* "On-card" video ram */ man->func = &ttm_bo_manager_func; - man->gpu_offset = rdev->mc.vram_start; man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE; man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; -- cgit v1.2.3 From 8ef963ba2d568fa72429afb9b077507fcdf1daab Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 24 Jun 2020 20:26:45 +0200 Subject: drm/qxl: don't use ttm bo->offset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch removes slot->gpu_offset which is not required as VRAM and PRIV slot are in separate PCI bar. This patch also removes unused qxl_bo_gpu_offset() Signed-off-by: Nirmoy Das Acked-by: Christian König Acked-by: Gerd Hoffmann Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/372934/ --- drivers/gpu/drm/qxl/qxl_drv.h | 6 ++---- drivers/gpu/drm/qxl/qxl_kms.c | 5 ++--- drivers/gpu/drm/qxl/qxl_object.h | 5 ----- drivers/gpu/drm/qxl/qxl_ttm.c | 9 --------- 4 files changed, 4 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 31e35f787df2..9691449aefdb 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -134,7 +134,6 @@ struct qxl_memslot { uint64_t start_phys_addr; uint64_t size; uint64_t high_bits; - uint64_t gpu_offset; }; enum { @@ -307,10 +306,9 @@ qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo, (bo->tbo.mem.mem_type == TTM_PL_VRAM) ? &qdev->main_slot : &qdev->surfaces_slot; - WARN_ON_ONCE((bo->tbo.offset & slot->gpu_offset) != slot->gpu_offset); + /* TODO - need to hold one of the locks to read bo->tbo.mem.start */ - /* TODO - need to hold one of the locks to read tbo.offset */ - return slot->high_bits | (bo->tbo.offset - slot->gpu_offset + offset); + return slot->high_bits | ((bo->tbo.mem.start << PAGE_SHIFT) + offset); } /* qxl_display.c */ diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index a6d873052cd4..dc5b3850a4d4 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -87,11 +87,10 @@ static void setup_slot(struct qxl_device *qdev, high_bits <<= (64 - (qdev->rom->slot_gen_bits + qdev->rom->slot_id_bits)); slot->high_bits = high_bits; - DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx, gpu_offset 0x%lx\n", + DRM_INFO("slot %d (%s): base 0x%08lx, size 0x%08lx\n", slot->index, slot->name, (unsigned long)slot->start_phys_addr, - (unsigned long)slot->size, - (unsigned long)slot->gpu_offset); + (unsigned long)slot->size); } void qxl_reinit_memslots(struct qxl_device *qdev) diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h index 8ae54ba7857c..21fa81048f4f 100644 --- a/drivers/gpu/drm/qxl/qxl_object.h +++ b/drivers/gpu/drm/qxl/qxl_object.h @@ -48,11 +48,6 @@ static inline void qxl_bo_unreserve(struct qxl_bo *bo) ttm_bo_unreserve(&bo->tbo); } -static inline u64 qxl_bo_gpu_offset(struct qxl_bo *bo) -{ - return bo->tbo.offset; -} - static inline unsigned long qxl_bo_size(struct qxl_bo *bo) { return bo->tbo.num_pages << PAGE_SHIFT; diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index f09a712b1ed2..52eaa2d22745 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -51,11 +51,6 @@ static struct qxl_device *qxl_get_qdev(struct ttm_bo_device *bdev) static int qxl_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, struct ttm_mem_type_manager *man) { - struct qxl_device *qdev = qxl_get_qdev(bdev); - unsigned int gpu_offset_shift = - 64 - (qdev->rom->slot_gen_bits + qdev->rom->slot_id_bits + 8); - struct qxl_memslot *slot; - switch (type) { case TTM_PL_SYSTEM: /* System memory */ @@ -66,11 +61,7 @@ static int qxl_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, case TTM_PL_VRAM: case TTM_PL_PRIV: /* "On-card" video ram */ - slot = (type == TTM_PL_VRAM) ? - &qdev->main_slot : &qdev->surfaces_slot; - slot->gpu_offset = (uint64_t)type << gpu_offset_shift; man->func = &ttm_bo_manager_func; - man->gpu_offset = slot->gpu_offset; man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE; man->available_caching = TTM_PL_MASK_CACHING; -- cgit v1.2.3 From 46642a7d4d80588c1f50d06885386f0c2e00fe36 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 24 Jun 2020 20:26:46 +0200 Subject: drm/vram-helper: don't use ttm bo->offset v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calculate GEM VRAM bo's offset within vram-helper without depending on bo->offset. Signed-off-by: Nirmoy Das Reviewed-by: Daniel Vetter Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/372938/ --- drivers/gpu/drm/drm_gem_vram_helper.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 0023ce1d2cf7..ad096600d89f 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -281,6 +281,15 @@ u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo) } EXPORT_SYMBOL(drm_gem_vram_mmap_offset); +static u64 drm_gem_vram_pg_offset(struct drm_gem_vram_object *gbo) +{ + /* Keep TTM behavior for now, remove when drivers are audited */ + if (WARN_ON_ONCE(!gbo->bo.mem.mm_node)) + return 0; + + return gbo->bo.mem.start; +} + /** * drm_gem_vram_offset() - \ Returns a GEM VRAM object's offset in video memory @@ -297,7 +306,7 @@ s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo) { if (WARN_ON_ONCE(!gbo->pin_count)) return (s64)-ENODEV; - return gbo->bo.offset; + return drm_gem_vram_pg_offset(gbo) << PAGE_SHIFT; } EXPORT_SYMBOL(drm_gem_vram_offset); -- cgit v1.2.3 From 6b86a1224af8b369d34a41b0954d9eeabd6f35ef Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 24 Jun 2020 20:26:47 +0200 Subject: drm/bochs: use drm_gem_vram_offset to get bo offset v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch over to GEM VRAM's implementation to retrieve bo->offset. Signed-off-by: Nirmoy Das Reviewed-by: Daniel Vetter Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/372931/ --- drivers/gpu/drm/bochs/bochs_kms.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 05d8373888e8..853081d186d5 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -29,16 +29,21 @@ static void bochs_plane_update(struct bochs_device *bochs, struct drm_plane_state *state) { struct drm_gem_vram_object *gbo; + s64 gpu_addr; if (!state->fb || !bochs->stride) return; gbo = drm_gem_vram_of_gem(state->fb->obj[0]); + gpu_addr = drm_gem_vram_offset(gbo); + if (WARN_ON_ONCE(gpu_addr < 0)) + return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */ + bochs_hw_setbase(bochs, state->crtc_x, state->crtc_y, state->fb->pitches[0], - state->fb->offsets[0] + gbo->bo.offset); + state->fb->offsets[0] + gpu_addr); bochs_hw_setformat(bochs, state->fb->format); } -- cgit v1.2.3 From 41752663b410c6265e24ff0570350b0b05ecdafe Mon Sep 17 00:00:00 2001 From: Bhanuprakash Modem Date: Mon, 22 Jun 2020 19:55:18 +0530 Subject: drm/debug: Expose connector VRR monitor range via debugfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Why] It's useful to know the min and max vrr range for IGT testing. [How] Expose the min and max vfreq for the connector via a debugfs file on the connector, "vrr_range". Example usage: cat /sys/kernel/debug/dri/0/DP-1/vrr_range v2: * Fix the typo in max_vfreq (Manasi) * Change the name of node to i915_vrr_info so we can add other vrr info for more debug info (Manasi) * Change the VRR capable to display Yes or No (Manasi) * Fix indentation checkpatch errors (Manasi) v3: * Remove the unnecessary debug print (Manasi) v4: * Rebase v5: * Rename to vrr_range to match AMD debugfs v6: * Rebase (manasi) v7: * Fix cmpilation due to rebase v8: * Move debugfs node creation logic to DRM (Emil) * Remove AMD specific logic (Emil) v9: * Separate patch for removal of AMD specific logic (Manasi) Signed-off-by: Bhanuprakash Modem Signed-off-by: Manasi Navare Cc: Jani Nikula Cc: Ville Syrjälä Cc: Harry Wentland CC: Emil Velikov Reviewed-by: Manasi Navare Signed-off-by: Manasi Navare Link: https://patchwork.freedesktop.org/patch/msgid/20200622142519.16214-3-bhanuprakash.modem@intel.com --- drivers/gpu/drm/drm_debugfs.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index bfe4602f206b..3d7182001004 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -376,6 +376,24 @@ static ssize_t edid_write(struct file *file, const char __user *ubuf, return (ret) ? ret : len; } +/* + * Returns the min and max vrr vfreq through the connector's debugfs file. + * Example usage: cat /sys/kernel/debug/dri/0/DP-1/vrr_range + */ +static int vrr_range_show(struct seq_file *m, void *data) +{ + struct drm_connector *connector = m->private; + + if (connector->status != connector_status_connected) + return -ENODEV; + + seq_printf(m, "Min: %u\n", (u8)connector->display_info.monitor_range.min_vfreq); + seq_printf(m, "Max: %u\n", (u8)connector->display_info.monitor_range.max_vfreq); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(vrr_range); + static const struct file_operations drm_edid_fops = { .owner = THIS_MODULE, .open = edid_open, @@ -413,6 +431,10 @@ void drm_debugfs_connector_add(struct drm_connector *connector) /* edid */ debugfs_create_file("edid_override", S_IRUGO | S_IWUSR, root, connector, &drm_edid_fops); + + /* vrr range */ + debugfs_create_file("vrr_range", S_IRUGO, root, connector, + &vrr_range_fops); } void drm_debugfs_connector_remove(struct drm_connector *connector) -- cgit v1.2.3