From nobody Tue Feb 10 00:02:40 2026 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6DBDB1B4F0A for ; Wed, 16 Apr 2025 00:02:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744761744; cv=none; b=DzuVn9WAd1qLY4wOohw+ULmETs9VrP5fML6ke2ol8eXuBT//GuZJfZAirxQOI/pl9C5ORxAsSySzG9xhxbQtADwjvh8Ft5CE7/v4hHMGUzQISXHoj7q33iXvbP3fbLKpwo6qQUZ8rHNl6h0LncMEEKJakzeeWvY4boGylpkKOcQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744761744; c=relaxed/simple; bh=zOmVc3lsujHVGR9M+6Irw8HkDbw5tSV2x/aMh4olbVE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=p4Z83Y8s+VpqDBS7tpkDAwx+dVvBOcuyEPsK7GyP93yTPdfPt8HDWsFOF/wBU07X3GQzDSTpaWTA6ZZ3jT1KN+11Z7vjMAv5dicI/AQEi6u42rqfw60xcOS3NEd8tXcjCukjJmTR9o4/CbXzXVvSVaQGr6WWVEFKOfQ3wljT6K8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=HnKg+mkB; arc=none smtp.client-ip=209.85.214.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="HnKg+mkB" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-224100e9a5cso70615705ad.2 for ; Tue, 15 Apr 2025 17:02:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1744761742; x=1745366542; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=HHYpHK7kt8aJgnApA+GCQEa2iHMXOWfKlfQqVLhW5Rk=; b=HnKg+mkBbHrgIIyQFIbRnLvSVHEDaLRtzQQ0c1D9HTvhmM/YesNo4HqUnTZt5yIBgO AE9Na1KLyVyZ7gXvF/5gPubHHd/cktGbeGIzEL3D9hxMrhjLWg5Ffq2/nilux6/jhC/L romY3FzDK3qkNhqgG6zYBQ5+2GKvvoqhAucB0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744761742; x=1745366542; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=HHYpHK7kt8aJgnApA+GCQEa2iHMXOWfKlfQqVLhW5Rk=; b=N7VYKb6Si5IDZL6cwYwRVaKL3vD2hmhm1hoDBQnrxYLlhhaHUzpn8e0aeFMgMF8wDD rWnV9uCJqdjQdd2UiLs3Ucvzfjd3N9FtylMmpooxyi7J+yYDMwOz4XrHsmA5tn7LdvXc 3a9zJ76QmvZ+hxEt2jUt8H2C/NO2J7i0B6Fw8etf0coeamzPxWxkasQiuZrYmMKgvElt nTQYrdZCK4joBTVoZAS5eavtKqNQoKT7wlKtE8kLsfBUCpD6rCQ96I8Y4SlJXxTzMekg YoI8CuUpvg5L65x08kgSPvVd55oniwpq6RxahJ6ZtRc9t+wZmHz91fhC39JjBvPkgVWv adrg== X-Gm-Message-State: AOJu0YzAEDvuyxEBsRLDN8l/lKolquE6Uu4uc+MkZkXWvszfvsjXaa70 DT8eaQL+Gmd5uKWFZYW13KHj+teCoB8t+LaeiqcVnyhHQ3Z8rGd1niJKNZv+Id6XRz9ZMCSQYBw = X-Gm-Gg: ASbGncsieSf52xfyPUBJJoJeQQRW5PGTqkYCx/xj4xEmISGvZMx76948+oPTEb7XSnA 68dU8htcFDggmwXDQJbPsJ5aAbmnIQIbkX3tvpO7LVijY0GDuAKnRF90GoSXjqJmXW8iJugprlx 1yzX9lQsuOyYf6L89saLFfqgePja0VNh0ZHh9NjKU7i9l3joxna8XNBcM9vjDM52jm5c7Rxp4sh Ebsr80bzr/MgJvanOhP2QF/1clN2XGn8dtqUuS+5D8Iy3k+fbKVS4BX2fVnd1lzDeIGSIj3JZy6 VvEj4I1pImzLC7FdTphr9xxy7SRR7/CM8ohHIIfqraoi98ixziuh/Zh9sY//rtIEOsaO5UPOtX9 GAw== X-Google-Smtp-Source: AGHT+IEiQFpTS4vI0noyDuSs6VYTT9MkaGL0pVH3GJ7yVUmMdtuB7YMvp/PXxT4BTHtGtAfI5QsF6w== X-Received: by 2002:a17:902:a5c7:b0:223:5525:6239 with SMTP id d9443c01a7336-22c31ace733mr15386845ad.38.1744761741951; Tue, 15 Apr 2025 17:02:21 -0700 (PDT) Received: from localhost (199.24.125.34.bc.googleusercontent.com. [34.125.24.199]) by smtp.gmail.com with UTF8SMTPSA id d9443c01a7336-22c33f1d091sm1324475ad.61.2025.04.15.17.02.20 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 15 Apr 2025 17:02:21 -0700 (PDT) From: Stephen Boyd To: Tzung-Bi Shih Cc: linux-kernel@vger.kernel.org, patches@lists.linux.dev, Bjorn Andersson , Konrad Dybcio , devicetree@vger.kernel.org, Dmitry Baryshkov , Krzysztof Kozlowski , Rob Herring , linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Conor Dooley , Benson Leung , chrome-platform@lists.linux.dev, Pin-yen Lin , Abhishek Pandit-Subedi , =?UTF-8?q?=C5=81ukasz=20Bartosik?= , Jameson Thies , Andrei Kuchynski Subject: [PATCH 6/7] platform/chrome: cros_ec_typec: Add support for DP altmode via drm_bridge Date: Tue, 15 Apr 2025 17:02:06 -0700 Message-ID: <20250416000208.3568635-7-swboyd@chromium.org> X-Mailer: git-send-email 2.49.0.604.gff1f9ca942-goog In-Reply-To: <20250416000208.3568635-1-swboyd@chromium.org> References: <20250416000208.3568635-1-swboyd@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable On Trogdor platforms, the USB DP altmode is entered and exited by the EC depending on if DP altmode is possible and if HPD is asserted for a port. Trogdor has two USB-C connectors but the AP only supports one DP controller, so the first USB-C connector to assert HPD "wins". The DP controller on the AP is fixed to output two lanes DP that goes to an analog mux that steers the DP lanes to one of the two USB-C connectors. The HPD state in the DP altmode is "captured" by the EC and redriven from a GPIO on the EC to the AP's GPIO that is muxed to the DisplayPort controller inside the AP SoC. This allows both HPD high/low and HPD IRQ to be signaled from the EC as well as making DP altmode possible on either USB-C connector except at the same time. Add a drm_bridge to the ChromeOS EC driver to represent this analog mux on Trogdor and teach the kernel that DP altmode is using this DP controller on the AP. When the DT node has a graph binding, we assume that we're muxing DP to one of many USB-C connectors and we terminate the bridge chain here. In almost all cases we want this bridge to be the one that signals HPD because the EC is the one managing HPD and redriving the GPIO, except for in the case that the DP altmode driver is enabled in which case HPD will be signaled with drm_bridge_connector_oob_hotplug_event(). Unfortunately Trogdor EC firmwares have a bug where HPD state isn't discoverable properly, so we skip signaling HPD in that case if the "no-hpd" property exists in the node. Cc: Benson Leung Cc: Tzung-Bi Shih Cc: Cc: Pin-yen Lin Cc: Abhishek Pandit-Subedi Cc: =C5=81ukasz Bartosik Cc: Jameson Thies Cc: Andrei Kuchynski Signed-off-by: Stephen Boyd --- drivers/platform/chrome/Kconfig | 1 + drivers/platform/chrome/cros_ec_typec.c | 50 +++++++++++++++++++++++++ drivers/platform/chrome/cros_ec_typec.h | 7 ++++ 3 files changed, 58 insertions(+) diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kcon= fig index 1b2f2bd09662..0ed8637b8853 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig @@ -247,6 +247,7 @@ config CROS_EC_TYPEC depends on MFD_CROS_EC_DEV && TYPEC depends on CROS_USBPD_NOTIFY depends on USB_ROLE_SWITCH + depends on DRM_BRIDGE default MFD_CROS_EC_DEV select CROS_EC_TYPEC_ALTMODES if TYPEC_DP_ALTMODE select CROS_EC_TYPEC_ALTMODES if TYPEC_TBT_ALTMODE diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chr= ome/cros_ec_typec.c index 2cbe29f08064..27324cf0c0c6 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,8 @@ #include #include =20 +#include + #include "cros_ec_typec.h" #include "cros_typec_vdm.h" #include "cros_typec_altmode.h" @@ -337,6 +340,9 @@ static int cros_typec_init_ports(struct cros_typec_data= *typec) u32 port_num =3D 0; =20 nports =3D device_get_child_node_count(dev); + /* Don't count any 'ports' child node */ + if (of_graph_is_present(dev->of_node)) + nports--; if (nports =3D=3D 0) { dev_err(dev, "No port entries found.\n"); return -ENODEV; @@ -350,6 +356,10 @@ static int cros_typec_init_ports(struct cros_typec_dat= a *typec) /* DT uses "reg" to specify port number. */ port_prop =3D dev->of_node ? "reg" : "port-number"; device_for_each_child_node(dev, fwnode) { + /* An OF graph isn't a connector */ + if (fwnode_name_eq(fwnode, "ports")) + continue; + if (fwnode_property_read_u32(fwnode, port_prop, &port_num)) { ret =3D -EINVAL; dev_err(dev, "No port-number for port, aborting.\n"); @@ -417,6 +427,42 @@ static int cros_typec_init_ports(struct cros_typec_dat= a *typec) return ret; } =20 +static int cros_typec_dp_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL; +} + +static const struct drm_bridge_funcs cros_typec_dp_bridge_funcs =3D { + .attach =3D cros_typec_dp_bridge_attach, +}; + +static int cros_typec_init_dp_bridge(struct cros_typec_data *typec) +{ + struct device *dev =3D typec->dev; + struct cros_typec_dp_bridge *dp_bridge; + struct drm_bridge *bridge; + struct device_node *np =3D dev->of_node; + + /* Not capable of DP altmode switching. Ignore. */ + if (!of_graph_is_present(np)) + return 0; + + dp_bridge =3D devm_kzalloc(dev, sizeof(*dp_bridge), GFP_KERNEL); + if (!dp_bridge) + return -ENOMEM; + typec->dp_bridge =3D dp_bridge; + + bridge =3D &dp_bridge->bridge; + bridge->funcs =3D &cros_typec_dp_bridge_funcs; + bridge->of_node =3D np; + bridge->type =3D DRM_MODE_CONNECTOR_DisplayPort; + if (!device_property_read_bool(dev, "no-hpd")) + bridge->ops |=3D DRM_BRIDGE_OP_HPD; + + return devm_drm_bridge_add(dev, bridge); +} + static int cros_typec_usb_safe_state(struct cros_typec_port *port) { int ret; @@ -1276,6 +1322,10 @@ static int cros_typec_probe(struct platform_device *= pdev) typec->num_ports =3D EC_USB_PD_MAX_PORTS; } =20 + ret =3D cros_typec_init_dp_bridge(typec); + if (ret < 0) + return ret; + ret =3D cros_typec_init_ports(typec); if (ret < 0) return ret; diff --git a/drivers/platform/chrome/cros_ec_typec.h b/drivers/platform/chr= ome/cros_ec_typec.h index 9fd5342bb0ad..090f8f5c0492 100644 --- a/drivers/platform/chrome/cros_ec_typec.h +++ b/drivers/platform/chrome/cros_ec_typec.h @@ -14,6 +14,8 @@ #include #include =20 +#include + /* Supported alt modes. */ enum { CROS_EC_ALTMODE_DP =3D 0, @@ -35,6 +37,7 @@ struct cros_typec_data { unsigned int pd_ctrl_ver; /* Array of ports, indexed by port number. */ struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS]; + struct cros_typec_dp_bridge *dp_bridge; struct notifier_block nb; struct work_struct port_work; bool typec_cmd_supported; @@ -83,4 +86,8 @@ struct cros_typec_port { struct cros_typec_data *typec_data; }; =20 +struct cros_typec_dp_bridge { + struct drm_bridge bridge; +}; + #endif /* __CROS_EC_TYPEC__ */ --=20 https://chromeos.dev