From patchwork Fri Mar 5 12:43:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dafna Hirschfeld X-Patchwork-Id: 12118427 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E07F8C433DB for ; Fri, 5 Mar 2021 12:54:39 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A48E564F5F for ; Fri, 5 Mar 2021 12:54:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A48E564F5F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=collabora.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B4B136EB78; Fri, 5 Mar 2021 12:54:35 +0000 (UTC) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by gabe.freedesktop.org (Postfix) with ESMTPS id C297A6EB6C for ; Fri, 5 Mar 2021 12:43:59 +0000 (UTC) Received: from guri.fritz.box (p200300c7cf38380008df3f9b2ff1d151.dip0.t-ipconnect.de [IPv6:2003:c7:cf38:3800:8df:3f9b:2ff1:d151]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: dafna) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 040811F46A73; Fri, 5 Mar 2021 12:43:57 +0000 (GMT) From: Dafna Hirschfeld To: devicetree@vger.kernel.org, dri-devel@lists.freedesktop.org Subject: [PATCH v5 1/2] dt-bindings: usb: add analogix,anx7688.yaml Date: Fri, 5 Mar 2021 13:43:50 +0100 Message-Id: <20210305124351.15079-2-dafna.hirschfeld@collabora.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210305124351.15079-1-dafna.hirschfeld@collabora.com> References: <20210305124351.15079-1-dafna.hirschfeld@collabora.com> X-Mailman-Approved-At: Fri, 05 Mar 2021 12:54:32 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: chunkuang.hu@kernel.org, jernej.skrabec@siol.net, drinkcat@chromium.org, dafna.hirschfeld@collabora.com, jonas@kwiboo.se, airlied@linux.ie, dafna3@gmail.com, narmstrong@baylibre.com, a.hajda@samsung.com, robh+dt@kernel.org, Laurent.pinchart@ideasonboard.com, hsinyi@chromium.org, enric.balletbo@collabora.com, kernel@collabora.com MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" ANX7688 is a USB Type-C port controller with a MUX. It converts HDMI 2.0 to DisplayPort 1.3 Ultra-HDi (4096x2160p60). The integrated crosspoint switch (the MUX) supports USB 3.1 data transfer along with the DisplayPort Alternate Mode signaling over USB Type-C. Additionally, an on-chip microcontroller (OCM) is available to manage the signal switching, Channel Configuration (CC) detection, USB Power Delivery (USB-PD), Vendor Defined Message (VDM) protocol support and other functions as defined in the USB TypeC and USB Power Delivery specifications. ANX7688 is found on Acer Chromebook R13 (elm) and on Pine64 PinePhone. Signed-off-by: Dafna Hirschfeld Reviewed-by: Laurent Pinchart --- .../bindings/usb/analogix,anx7688.yaml | 177 ++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/analogix,anx7688.yaml diff --git a/Documentation/devicetree/bindings/usb/analogix,anx7688.yaml b/Documentation/devicetree/bindings/usb/analogix,anx7688.yaml new file mode 100644 index 000000000000..6c4dd6b4b28b --- /dev/null +++ b/Documentation/devicetree/bindings/usb/analogix,anx7688.yaml @@ -0,0 +1,177 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/analogix,anx7688.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analogix ANX7688 Type-C Port Controller with HDMI to DP conversion + +maintainers: + - Nicolas Boichat + - Enric Balletbo i Serra + +description: | + ANX7688 is a USB Type-C port controller with a MUX. It converts HDMI 2.0 to + DisplayPort 1.3 Ultra-HDi (4096x2160p60). + The integrated crosspoint switch (the MUX) supports USB 3.1 data transfer along with + the DisplayPort Alternate Mode signaling over USB Type-C. Additionally, + an on-chip microcontroller (OCM) is available to manage the signal switching, + Channel Configuration (CC) detection, USB Power Delivery (USB-PD), Vendor + Defined Message (VDM) protocol support and other functions as defined in the + USB TypeC and USB Power Delivery specifications. + + +properties: + compatible: + const: analogix,anx7688 + + reg: + maxItems: 1 + + avdd33-supply: + description: 3.3V Analog core supply voltage. + + dvdd18-supply: + description: 1.8V Digital I/O supply voltage. + + avdd18-supply: + description: 1.8V Analog core power supply voltage. + + avdd10-supply: + description: 1.0V Analog core power supply voltage. + + dvdd10-supply: + description: 1.0V Digital core supply voltage. + + hdmi5v-supply: + description: 5V power supply for the HDMI. + + hdmi_vt-supply: + description: Termination voltage for HDMI input. + + clocks: + description: The input clock specifier. + maxItems: 1 + + clock-names: + items: + - const: xtal + + hpd-gpios: + description: | + In USB Type-C applications, DP_HPD has no use. In standard DisplayPort + applications, DP_HPD is used as DP hot-plug. + maxItems: 1 + + enable-gpios: + description: Chip power down control. No internal pull-down or pull-up resistor. + maxItems: 1 + + reset-gpios: + description: Reset input signal. Active low. + maxItems: 1 + + vbus-det-gpios: + description: | + An input gpio for VBUS detection and high voltage detection, + external resistance divide VBUS voltage to 1/8. + maxItems: 1 + + interrupts: + description: | + The interrupt notifies 4 possible events - TCPC ALERT int, PD int, DP int, HDMI int. + maxItems: 1 + + cabledet-gpios: + description: An output gpio, indicates by the device that a cable is plugged. + maxItems: 1 + + vbus-ctrl-gpios: + description: + External VBUS power path. Enable VBUS source and disable VBUS sink or vice versa. + maxItems: 1 + + vconn-en1-gpios: + description: Controls the VCONN switch on the CC1 pin. + maxItems: 1 + + vconn-en2-gpios: + description: Controls the VCONN switch on the CC2 pin. + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: Video port for HDMI input. + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: USB port for the USB3 input. + + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: USB Type-c connector, see connector/usb-connector.yaml. + + required: + - port@0 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + #include + + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + anx7688: anx7688@2c { + compatible = "analogix,anx7688"; + reg = <0x2c>; + avdd33-supply = <®_dcdc1>; + dvdd18-supply = <®_ldo_io1>; + avdd18-supply = <®_ldo_io1>; + avdd10-supply = <®_anx1v0>; + dvdd10-supply = <®_anx1v0>; + hdmi_vt-supply = <®_dldo1>; + enable-gpios = <&pio 3 10 GPIO_ACTIVE_LOW>; /* PD10 */ + reset-gpios = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */ + interrupt-parent = <&r_pio>; + interrupts = <0 11 IRQ_TYPE_EDGE_FALLING>; /* PL11 */ + cabledet-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + vconn-en1-gpios = <&pio 3 9 GPIO_ACTIVE_LOW>; /* PD9 */ + vconn-en2-gpios = <&pio 3 9 GPIO_ACTIVE_LOW>; /* PD9 */ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + anx7688_in0: endpoint { + remote-endpoint = <&hdmi0_out>; + }; + }; + + port@1 { + reg = <1>; + anx7688_in1: endpoint { + remote-endpoint = <&usbdrd_phy_ss>; + }; + }; + port@2 { + reg = <2>; + anx7688_out: endpoint { + remote-endpoint = <&typec_connector>; + }; + }; + }; + }; + }; From patchwork Fri Mar 5 12:43:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dafna Hirschfeld X-Patchwork-Id: 12118423 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4DFF9C433E0 for ; Fri, 5 Mar 2021 12:54:33 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E740D60233 for ; Fri, 5 Mar 2021 12:54:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E740D60233 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=collabora.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 373FD6EB3B; Fri, 5 Mar 2021 12:54:32 +0000 (UTC) Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by gabe.freedesktop.org (Postfix) with ESMTPS id 543346EB6C for ; Fri, 5 Mar 2021 12:44:00 +0000 (UTC) Received: from guri.fritz.box (p200300c7cf38380008df3f9b2ff1d151.dip0.t-ipconnect.de [IPv6:2003:c7:cf38:3800:8df:3f9b:2ff1:d151]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: dafna) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 9049A1F46A74; Fri, 5 Mar 2021 12:43:58 +0000 (GMT) From: Dafna Hirschfeld To: devicetree@vger.kernel.org, dri-devel@lists.freedesktop.org Subject: [PATCH v5 2/2] drm/bridge: anx7688: Add ANX7688 bridge driver support Date: Fri, 5 Mar 2021 13:43:51 +0100 Message-Id: <20210305124351.15079-3-dafna.hirschfeld@collabora.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210305124351.15079-1-dafna.hirschfeld@collabora.com> References: <20210305124351.15079-1-dafna.hirschfeld@collabora.com> X-Mailman-Approved-At: Fri, 05 Mar 2021 12:54:32 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: chunkuang.hu@kernel.org, jernej.skrabec@siol.net, drinkcat@chromium.org, dafna.hirschfeld@collabora.com, jonas@kwiboo.se, airlied@linux.ie, dafna3@gmail.com, narmstrong@baylibre.com, a.hajda@samsung.com, robh+dt@kernel.org, Laurent.pinchart@ideasonboard.com, hsinyi@chromium.org, enric.balletbo@collabora.com, kernel@collabora.com MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Enric Balletbo i Serra This driver adds support for the ANX7688 HDMI to DP converter block of the ANX7688 device. For our use case, the only reason the Linux kernel driver is necessary is to reject resolutions that require more bandwidth than what is available on the DP side. DP bandwidth and lane count are reported by the bridge via 2 registers and, as far as we know, only chips that have a firmware version greater than 0.85 support these two registers. Signed-off-by: Nicolas Boichat Signed-off-by: Hsin-Yi Wang [The driver is OF only so should depends on CONFIG_OF] Reported-by: kbuild test robot Signed-off-by: Enric Balletbo i Serra [convert the driver to be a i2c driver] Signed-off-by: Dafna Hirschfeld Reviewed-by: Laurent Pinchart --- drivers/gpu/drm/bridge/analogix/Kconfig | 11 ++ drivers/gpu/drm/bridge/analogix/Makefile | 1 + .../drm/bridge/analogix/analogix-anx7688.c | 186 ++++++++++++++++++ 3 files changed, 198 insertions(+) create mode 100644 drivers/gpu/drm/bridge/analogix/analogix-anx7688.c diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig index 024ea2a570e7..323327aabc38 100644 --- a/drivers/gpu/drm/bridge/analogix/Kconfig +++ b/drivers/gpu/drm/bridge/analogix/Kconfig @@ -11,6 +11,17 @@ config DRM_ANALOGIX_ANX6345 ANX6345 transforms the LVTTL RGB output of an application processor to eDP or DisplayPort. +config DRM_ANALOGIX_ANX7688 + tristate "Analogix ANX7688 bridge" + depends on OF + select DRM_KMS_HELPER + select REGMAP_I2C + help + ANX7688 is an ultra-low power 4K Ultra-HD (4096x2160p60) + mobile HD transmitter designed for portable + devices. The ANX7688 converts HDMI 2.0 to + DisplayPort 1.3 Ultra-HD. + config DRM_ANALOGIX_ANX78XX tristate "Analogix ANX78XX bridge" select DRM_ANALOGIX_DP diff --git a/drivers/gpu/drm/bridge/analogix/Makefile b/drivers/gpu/drm/bridge/analogix/Makefile index 44da392bb9f9..8f2272b8b732 100644 --- a/drivers/gpu/drm/bridge/analogix/Makefile +++ b/drivers/gpu/drm/bridge/analogix/Makefile @@ -2,5 +2,6 @@ analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o analogix-i2c-dptx.o obj-$(CONFIG_DRM_ANALOGIX_ANX6345) += analogix-anx6345.o obj-$(CONFIG_DRM_ANALOGIX_ANX7625) += anx7625.o +obj-$(CONFIG_DRM_ANALOGIX_ANX7688) += analogix-anx7688.o obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx7688.c b/drivers/gpu/drm/bridge/analogix/analogix-anx7688.c new file mode 100644 index 000000000000..85a4b1a23035 --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx7688.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * ANX7688 HDMI->DP bridge driver + * + * Copyright 2020 Google LLC + */ + +#include +#include +#include +#include +#include +#include + +/* Register addresses */ +#define ANX7688_VENDOR_ID_REG 0x00 +#define ANX7688_DEVICE_ID_REG 0x02 + +#define ANX7688_FW_VERSION_REG 0x80 + +#define ANX7688_DP_BANDWIDTH_REG 0x85 +#define ANX7688_DP_LANE_COUNT_REG 0x86 + +#define ANX7688_VENDOR_ID 0x1f29 +#define ANX7688_DEVICE_ID 0x7688 + +/* First supported firmware version (0.85) */ +#define ANX7688_MINIMUM_FW_VERSION 0x0085 + +static const struct regmap_config anx7688_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +struct anx7688 { + struct i2c_client *client; + struct regmap *regmap; + struct drm_bridge bridge; + bool filter; +}; + +static inline struct anx7688 * +bridge_to_anx7688(struct drm_bridge *bridge) +{ + return container_of(bridge, struct anx7688, bridge); +} + +static bool anx7688_bridge_mode_fixup(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct anx7688 *anx = bridge_to_anx7688(bridge); + int totalbw, requiredbw; + u8 dpbw, lanecount; + u8 regs[2]; + int ret; + + if (!anx->filter) + return true; + + /* Read both regs 0x85 (bandwidth) and 0x86 (lane count). */ + ret = regmap_bulk_read(anx->regmap, ANX7688_DP_BANDWIDTH_REG, regs, 2); + if (ret < 0) { + DRM_ERROR("Failed to read bandwidth/lane count\n"); + return false; + } + dpbw = regs[0]; + lanecount = regs[1]; + + /* Maximum 0x19 bandwidth (6.75 Gbps Turbo mode), 2 lanes */ + if (dpbw > 0x19 || lanecount > 2) { + DRM_ERROR("Invalid bandwidth/lane count (%02x/%d)\n", dpbw, + lanecount); + return false; + } + + /* Compute available bandwidth (kHz) */ + totalbw = dpbw * lanecount * 270000 * 8 / 10; + + /* Required bandwidth (8 bpc, kHz) */ + requiredbw = mode->clock * 8 * 3; + + DRM_DEBUG_KMS("DP bandwidth: %d kHz (%02x/%d); mode requires %d Khz\n", + totalbw, dpbw, lanecount, requiredbw); + + if (totalbw == 0) { + DRM_ERROR("Bandwidth/lane count are 0, not rejecting modes\n"); + return true; + } + + return totalbw >= requiredbw; +} + +static const struct drm_bridge_funcs anx7688_bridge_funcs = { + .mode_fixup = anx7688_bridge_mode_fixup, +}; + +static int anx7688_bridge_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct anx7688 *anx7688; + u16 vendor, device, fw_version; + u8 buffer[4]; + int ret; + + anx7688 = devm_kzalloc(dev, sizeof(*anx7688), GFP_KERNEL); + if (!anx7688) + return -ENOMEM; + + anx7688->client = client; + i2c_set_clientdata(client, anx7688); + + anx7688->regmap = devm_regmap_init_i2c(client, &anx7688_regmap_config); + + /* Read both vendor and device id (4 bytes). */ + ret = regmap_bulk_read(anx7688->regmap, ANX7688_VENDOR_ID_REG, + buffer, 4); + if (ret) { + dev_err(dev, "Failed to read chip vendor/device id\n"); + return ret; + } + + vendor = (u16)buffer[1] << 8 | buffer[0]; + device = (u16)buffer[3] << 8 | buffer[2]; + if (vendor != ANX7688_VENDOR_ID || device != ANX7688_DEVICE_ID) { + dev_err(dev, "Invalid vendor/device id %04x/%04x\n", + vendor, device); + return -ENODEV; + } + + ret = regmap_bulk_read(anx7688->regmap, ANX7688_FW_VERSION_REG, + buffer, 2); + if (ret) { + dev_err(&client->dev, "Failed to read firmware version\n"); + return ret; + } + + fw_version = (u16)buffer[0] << 8 | buffer[1]; + dev_info(dev, "ANX7688 firmware version 0x%04x\n", fw_version); + + anx7688->bridge.of_node = dev->of_node; + + /* FW version >= 0.85 supports bandwidth/lane count registers */ + if (fw_version >= ANX7688_MINIMUM_FW_VERSION) + anx7688->filter = true; + else + /* Warn, but not fail, for backwards compatibility */ + DRM_WARN("Old ANX7688 FW version (0x%04x), not filtering\n", + fw_version); + + anx7688->bridge.funcs = &anx7688_bridge_funcs; + drm_bridge_add(&anx7688->bridge); + + return 0; +} + +static int anx7688_bridge_remove(struct i2c_client *client) +{ + struct anx7688 *anx7688 = i2c_get_clientdata(client); + + drm_bridge_remove(&anx7688->bridge); + + return 0; +} + +static const struct of_device_id anx7688_bridge_match_table[] = { + { .compatible = "analogix,anx7688", }, + { } +}; +MODULE_DEVICE_TABLE(of, anx7688_bridge_match_table); + +static struct i2c_driver anx7688_bridge_driver = { + .probe_new = anx7688_bridge_probe, + .remove = anx7688_bridge_remove, + .driver = { + .name = "anx7688-bridge", + .of_match_table = anx7688_bridge_match_table, + }, +}; + +module_i2c_driver(anx7688_bridge_driver); + +MODULE_DESCRIPTION("ANX7688 HDMI->DP bridge driver"); +MODULE_AUTHOR("Nicolas Boichat "); +MODULE_AUTHOR("Enric Balletbo i Serra "); +MODULE_LICENSE("GPL");