From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7B5835E94F; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; cv=none; b=hB0V1Ij0a7hgdEDzocKpTTM6RgO79ao7GWagLHOcPVV7t9cRYu7N0rThtuQtCESm2dveAA3bWPJM56Y2hPsa6TW1x+ME8xw1VkXuC8M/QkNJT5J0bStBP69verDq2rQ9TcLI3JpXSLKrzmBaaa05+3dw1yoNQ9WOAEyqTiRhx8k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; c=relaxed/simple; bh=DTWuRGoGwBcM1jGnxAkzk6R1cL0Y4ZnoYiAhUMuNaHk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NT+2zAJz1OqVlsWqnIm6n2GHfZkp6Qqkg1yq5iC/BpG34BMFbr1OvnO+btfHcYpSkzy/9SVjf8L8Cwcx1yYgf/7jOWb+Fjec/yhAXHtxEX/dwI8SKbS6OZqCPk4YCFOuCU3kw4ankXfJ661S/LokitNmfsOCinMgEs+dDCWveUE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QZTWGnBu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QZTWGnBu" Received: by smtp.kernel.org (Postfix) with ESMTPS id 46EB3C2BCB8; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=DTWuRGoGwBcM1jGnxAkzk6R1cL0Y4ZnoYiAhUMuNaHk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=QZTWGnBuEKsEkvFlW7AdIR1z6spjpuihDfH16nnxKgUfN/CTdnQd8hjTfjnE1JSef 1O9MDQ0T4119Ngp/TeTbXQZzY4xoyL9tSwXfUh6ZkO+yRWfcucBuqNA2c+f9H14gJ3 uFy+UV1C6lR4eQmK7GxU6aY5vCC0bfY1/tDEkArGhweM1DxyCiw0SjJf7VJhDA+rJZ Gi+DnxyzQCedCxagVJCYFPOuTM8ucqh7m0ech5KrAxa29xONP4FJ4LG/PioqBdxOch XlBcHFl9h3dhODsPLAdODH3ryVMFFP2sRVkSE7FssqZF2CdW4jX/JYd8SC/0WBIOwT 6w0Uc9jLZQ42g== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2690FC79F8C; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:24 +0200 Subject: [PATCH v2 01/22] usb: typec: Add alternate mode state notifiers 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-1-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5945; i=sven@kernel.org; h=from:subject:message-id; bh=DTWuRGoGwBcM1jGnxAkzk6R1cL0Y4ZnoYiAhUMuNaHk=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTTvX7XKrMNssNHvL2jO9X7SW17ybzmu/rSdt7XXjp 5a2l/MvdJSyMIhxMciKKbJs329v+uThG8Glmy69h5nDygQyhIGLUwAmcqmU4X/Am4pD875f0N64 ZlZmYdsk2+plr0UqeKYErJ7Gn3ll0dEbjAyTt2Rd8LgRrvGW7fi5N6rOU+6lu/qxXL0ZtfaaU/d l4/N8AA== X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 The Apple Silicon USB4/Thunderbolt driver needs to be made aware of cable details and whenever USB4 or Thunderbolt is entered. The cable details are already available as part of the typec subsystem but there is no way to get a notification on typec_altmode_update_active() so far. Add a blocking notifier chain to each alternate mode and call it whenever the mode is activated or deactivated right next to the already existing sysfs and kobject_uevent notifications. Replay activations when a notifier is registered. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/usb/typec/bus.h | 6 +++++ drivers/usb/typec/class.c | 59 +++++++++++++++++++++++++++++++++++++++++++= ++++ include/linux/usb/typec.h | 16 +++++++++++++ 3 files changed, 81 insertions(+) diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h index 7df5deb1dd3a..4dc60c48c91e 100644 --- a/drivers/usb/typec/bus.h +++ b/drivers/usb/typec/bus.h @@ -3,6 +3,8 @@ #ifndef __USB_TYPEC_ALTMODE_H__ #define __USB_TYPEC_ALTMODE_H__ =20 +#include +#include #include =20 struct typec_mux; @@ -23,6 +25,10 @@ struct altmode { =20 struct altmode *partner; struct altmode *plug[2]; + + /* Serializes active state changes and notifier registration. */ + struct mutex state_lock; + struct blocking_notifier_head state_notifier; }; =20 #define to_altmode(d) container_of(d, struct altmode, adev) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 54c7810b563b..5808a3ef0d6c 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -299,8 +299,11 @@ static void typec_altmode_put_partner(struct altmode *= altmode) */ void typec_altmode_update_active(struct typec_altmode *adev, bool active) { + struct altmode *alt =3D to_altmode(adev); char dir[6]; =20 + guard(mutex)(&alt->state_lock); + if (adev->active =3D=3D active) return; =20 @@ -312,6 +315,10 @@ void typec_altmode_update_active(struct typec_altmode = *adev, bool active) } =20 adev->active =3D active; + blocking_notifier_call_chain(&alt->state_notifier, + active ? TYPEC_ALTMODE_ENTERED : + TYPEC_ALTMODE_EXITED, + adev); snprintf(dir, sizeof(dir), "mode%d", adev->mode); sysfs_notify(&adev->dev.kobj, dir, "active"); sysfs_notify(&adev->dev.kobj, NULL, "active"); @@ -319,6 +326,56 @@ void typec_altmode_update_active(struct typec_altmode = *adev, bool active) } EXPORT_SYMBOL_GPL(typec_altmode_update_active); =20 +/** + * typec_altmode_register_notifier - Register an alternate mode state noti= fier + * @adev: Handle to the alternate mode + * @nb: Notifier block + * + * The notifier is called synchronously when the mode represented by @adev= is + * entered or exited. If @adev is already active %TYPEC_ALTMODE_ENTERED wi= ll be + * emitted before this function returns. Callbacks must not update the sta= te of + * @adev or register or unregister another notifier for @adev. They must a= lso + * handle failures locally and return %NOTIFY_OK or %NOTIFY_DONE so that o= ther + * subscribers also receive the event. Callback return values do not affec= t the + * active state or the result of notifier registration. + * + * Return: 0 on success or a negative error code on failure. + */ +int typec_altmode_register_notifier(struct typec_altmode *adev, + struct notifier_block *nb) +{ + struct altmode *alt =3D to_altmode(adev); + int ret; + + guard(mutex)(&alt->state_lock); + ret =3D blocking_notifier_chain_register(&alt->state_notifier, nb); + if (!ret && adev->active) + nb->notifier_call(nb, TYPEC_ALTMODE_ENTERED, adev); + + return ret; +} +EXPORT_SYMBOL_GPL(typec_altmode_register_notifier); + +/** + * typec_altmode_unregister_notifier - Unregister an alternate mode notifi= er + * @adev: Handle to the alternate mode + * @nb: Notifier block + * + * Return: 0 on success or a negative error code on failure. + */ +int typec_altmode_unregister_notifier(struct typec_altmode *adev, + struct notifier_block *nb) +{ + struct altmode *alt =3D to_altmode(adev); + int ret; + + guard(mutex)(&alt->state_lock); + ret =3D blocking_notifier_chain_unregister(&alt->state_notifier, nb); + + return ret; +} +EXPORT_SYMBOL_GPL(typec_altmode_unregister_notifier); + /** * typec_altmode2port - Alternate Mode to USB Type-C port * @alt: The Alternate Mode @@ -658,6 +715,8 @@ typec_register_altmode(struct device *parent, alt->adev.mode_selection =3D desc->mode_selection; alt->roles =3D desc->roles; alt->id =3D id; + mutex_init(&alt->state_lock); + BLOCKING_INIT_NOTIFIER_HEAD(&alt->state_notifier); =20 alt->attrs[0] =3D &dev_attr_vdo.attr; alt->attrs[1] =3D &dev_attr_description.attr; diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 10a783b738ef..914a6f0844c5 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -19,6 +19,7 @@ struct typec_plug; struct typec_port; struct typec_altmode_ops; struct typec_cable_ops; +struct notifier_block; =20 struct bus_type; struct fwnode_handle; @@ -184,6 +185,21 @@ struct typec_port *typec_altmode2port(struct typec_alt= mode *alt); =20 void typec_altmode_update_active(struct typec_altmode *alt, bool active); =20 +/** + * enum typec_altmode_event - USB Type-C alternate mode state event + * @TYPEC_ALTMODE_ENTERED: The alternate mode has been entered + * @TYPEC_ALTMODE_EXITED: The alternate mode has been exited + */ +enum typec_altmode_event { + TYPEC_ALTMODE_ENTERED, + TYPEC_ALTMODE_EXITED, +}; + +int typec_altmode_register_notifier(struct typec_altmode *alt, + struct notifier_block *nb); +int typec_altmode_unregister_notifier(struct typec_altmode *alt, + struct notifier_block *nb); + void typec_altmode_set_ops(struct typec_altmode *alt, const struct typec_altmode_ops *ops); =20 --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7ADE35DA7B; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; cv=none; b=AVP87GBY6AC3KQwQInjVj1xkx+4p8o5wx7+qU5AYerLgBc26HaD1LYeRVNwxOWlX2UF2puXrsZcXyf+zXdxlT1+aBpG4jYmmCzhAwJJAxsiiQWtVyn0kaJYTI4lSofy1hXJfYRJptPbfoWOVckA1f0VrHkYjls0Jv5TSFTfQPus= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; c=relaxed/simple; bh=B/qrsmu6dNMa0mdZN1vjAuTnmbaVMn70eJ9KkkRXhqY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HMOqE00tAfEmDOOPZWM9rSbwuu0vR9j1wNJMgjY3W62smvdHeeR1DIF3h9z3MvrzWG03nEiyrlcOpfAcpOpEucJc4kfs/FUrU7l+bbDDli/W726afUxI+bYLascJd/XAPkKVE8/9CGtE1xZaCFH+M2EaLCHIrUEqnSXk2Ch6p0A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BuV0AhVf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BuV0AhVf" Received: by smtp.kernel.org (Postfix) with ESMTPS id 5651FC2BCFB; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=B/qrsmu6dNMa0mdZN1vjAuTnmbaVMn70eJ9KkkRXhqY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BuV0AhVfxDCqgMEjIL1+hXZt+q4BdGDzcfw0MQcZ6PVoP8pfjr1ZEq8TCDQNBjcwX qNXswGQugH7WLW5VbxtwLFGpFOs8ECoCpIFj8qI1Ga7oG7vUwd/qrA3STf80j4vtG2 6pomQGcXsTMFQ6/D8Fs4xky9OAt+Dhs4LruvmpOTZ1H/AKuSdKOM6tKRStOCkemkAy KY82nOTtZ/sqy1o+pmflsBwzyWqaPq/9MNW0N/RCY8UMg1H3CBM1Qy2Z4IEgnVEJvm wPPXbg7ATT3itIYOwa+vs+sCAjtHnh91pPt1ZgJgqGhBnshCMrFEVwBMo4gwdj+PMp WG52o0gvRT/xQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39558C79FA1; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:25 +0200 Subject: [PATCH v2 02/22] usb: typec: Represent USB4 on the Type-C bus 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-2-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=19872; i=sven@kernel.org; h=from:subject:message-id; bh=B/qrsmu6dNMa0mdZN1vjAuTnmbaVMn70eJ9KkkRXhqY=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTbvqZtzc8CWfma/2wAUH49yL0Uc2Xl68UCuft8Nim tEb11TNjlIWBjEuBlkxRZbt++1Nnzx8I7h006X3MHNYmUCGMHBxCsBEFroy/BUXePGzeeevB5nL 1AQ0OkP2Hn1w4A/fkzfiuVuimFbl33vLyLA5kp1hLj/DWrWt82r2StaZBvy5vlrw5GGGEuYoack mDm4A X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 USB4 technically isn't alternate mode and entered using the EUDO and has no SVID or Discover Modes Response. We can still represent it like an altmode on the Type-C bus though by adding a mode kind. Exclude the USB4 modes from any SVID-specific operations and driver binding, but allow consumers to observe their state through notifications. Like for other altmodes, expose the USB4 mode to sysfs: Add a mode_kind to be able to differentiate and then expose the EUDO, make the USB4 active state read-only since we only represent firmware-negotiated USB4 modes and omit anything that only applies to SVID-specific altmodes. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- Hope it's fine to add you as the contact for the sysfs documentation, happy to add myself otherwise though. --- Documentation/ABI/testing/sysfs-bus-typec | 36 ++++++++++++++ drivers/usb/typec/bus.c | 67 ++++++++++++++++++++----- drivers/usb/typec/class.c | 83 +++++++++++++++++++++++++++= ---- drivers/usb/typec/mode_selection.c | 6 ++- include/linux/usb/typec.h | 20 +++++++- include/linux/usb/typec_altmode.h | 10 +++- 6 files changed, 193 insertions(+), 29 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-typec b/Documentation/ABI/= testing/sysfs-bus-typec index 205d9c91e2e1..524bbcbadf64 100644 --- a/Documentation/ABI/testing/sysfs-bus-typec +++ b/Documentation/ABI/testing/sysfs-bus-typec @@ -12,6 +12,35 @@ Description: =20 Valid values are boolean. =20 + For USB4 mode devices this attribute is read-only. On a port it + indicates whether USB4 support is enabled; on a partner it reports + whether USB4 is active. USB4 entry and exit are controlled by the + port controller. Partner state changes notify this attribute and + generate KOBJ_CHANGE uevents. + +What: /sys/bus/typec/devices/.../mode_kind +Date: September 2026 +Contact: Heikki Krogerus +Description: + Read-only protocol kind represented by this mode device: + "altmode" for an SVID-specific alternate mode, or "usb4" for + USB4 negotiated using Enter_USB. + + USB4 devices do not expose svid, mode, vdo, or priority + attributes, or the legacy modeN attribute group. USB4 partner + uevents contain MODE_KIND=3Dusb4 instead of SVID, MODE, and + MODALIAS variables. + +What: /sys/bus/typec/devices/.../eudo +Date: September 2026 +Contact: Heikki Krogerus +Description: + Read-only Enter_USB Data Object (EUDO), formatted as + 0x followed by eight hexadecimal digits. Present only on USB4 + partner mode devices, not on ports or SVID-specific alternate + modes. USB4 cable information is encoded in the EUDO; there are + no USB4 cable plug mode devices. + What: /sys/bus/typec/devices/.../description Date: July 2018 Contact: Heikki Krogerus @@ -36,6 +65,8 @@ Description: the mode index is not assigned, identifying the alternate mode must be done with either mode VDO or the description. =20 + This attribute is not present on USB4 mode devices. + What: /sys/bus/typec/devices/.../svid Date: July 2018 Contact: Heikki Krogerus @@ -43,9 +74,14 @@ Description: The Standard or Vendor ID (SVID) assigned by USB-IF for this alternate mode. =20 + This attribute is not present on USB4 mode devices. + What: /sys/bus/typec/devices/.../vdo Date: July 2018 Contact: Heikki Krogerus Description: Shows the VDO in hexadecimal returned by Discover Modes command for this mode. + + This attribute is not present on USB4 mode devices. USB4 partner + mode devices expose the EUDO in the eudo attribute. diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c index e84b134a3381..8e6d7769fac3 100644 --- a/drivers/usb/typec/bus.c +++ b/drivers/usb/typec/bus.c @@ -93,6 +93,8 @@ int typec_altmode_notify(struct typec_altmode *adev, =20 if (!adev) return 0; + if (adev->mode_kind !=3D TYPEC_MODE_KIND_ALTMODE) + return -EOPNOTSUPP; =20 altmode =3D to_altmode(adev); =20 @@ -125,12 +127,19 @@ EXPORT_SYMBOL_GPL(typec_altmode_notify); */ int typec_altmode_enter(struct typec_altmode *adev, u32 *vdo) { - struct altmode *partner =3D to_altmode(adev)->partner; - struct typec_altmode *pdev =3D &partner->adev; + struct typec_altmode *pdev; + struct altmode *partner; int ret; =20 - if (!adev || adev->active) + if (!adev) return 0; + if (adev->mode_kind !=3D TYPEC_MODE_KIND_ALTMODE) + return -EOPNOTSUPP; + if (adev->active) + return 0; + + partner =3D to_altmode(adev)->partner; + pdev =3D &partner->adev; =20 if (!pdev->ops || !pdev->ops->enter) return -EOPNOTSUPP; @@ -156,12 +165,19 @@ EXPORT_SYMBOL_GPL(typec_altmode_enter); */ int typec_altmode_exit(struct typec_altmode *adev) { - struct altmode *partner =3D to_altmode(adev)->partner; - struct typec_altmode *pdev =3D &partner->adev; + struct typec_altmode *pdev; + struct altmode *partner; int ret; =20 - if (!adev || !adev->active) + if (!adev) return 0; + if (adev->mode_kind !=3D TYPEC_MODE_KIND_ALTMODE) + return -EOPNOTSUPP; + if (!adev->active) + return 0; + + partner =3D to_altmode(adev)->partner; + pdev =3D &partner->adev; =20 if (!pdev->ops || !pdev->ops->exit) return -EOPNOTSUPP; @@ -185,8 +201,13 @@ EXPORT_SYMBOL_GPL(typec_altmode_exit); */ int typec_altmode_attention(struct typec_altmode *adev, u32 vdo) { - struct altmode *partner =3D to_altmode(adev)->partner; struct typec_altmode *pdev; + struct altmode *partner; + + if (adev->mode_kind !=3D TYPEC_MODE_KIND_ALTMODE) + return -EOPNOTSUPP; + + partner =3D to_altmode(adev)->partner; =20 if (!partner) return -ENODEV; @@ -219,6 +240,8 @@ int typec_altmode_vdm(struct typec_altmode *adev, =20 if (!adev) return 0; + if (adev->mode_kind !=3D TYPEC_MODE_KIND_ALTMODE) + return -EOPNOTSUPP; =20 altmode =3D to_altmode(adev); =20 @@ -258,12 +281,17 @@ EXPORT_SYMBOL_GPL(typec_altmode_get_partner); */ int typec_cable_altmode_enter(struct typec_altmode *adev, enum typec_plug_= index sop, u32 *vdo) { - struct altmode *partner =3D to_altmode(adev)->partner; struct typec_altmode *pdev; + struct altmode *partner; =20 - if (!adev || adev->active) + if (!adev) + return 0; + if (adev->mode_kind !=3D TYPEC_MODE_KIND_ALTMODE) + return -EOPNOTSUPP; + if (adev->active) return 0; =20 + partner =3D to_altmode(adev)->partner; if (!partner) return -ENODEV; =20 @@ -288,12 +316,17 @@ EXPORT_SYMBOL_GPL(typec_cable_altmode_enter); */ int typec_cable_altmode_exit(struct typec_altmode *adev, enum typec_plug_i= ndex sop) { - struct altmode *partner =3D to_altmode(adev)->partner; struct typec_altmode *pdev; + struct altmode *partner; =20 - if (!adev || !adev->active) + if (!adev) + return 0; + if (adev->mode_kind !=3D TYPEC_MODE_KIND_ALTMODE) + return -EOPNOTSUPP; + if (!adev->active) return 0; =20 + partner =3D to_altmode(adev)->partner; if (!partner) return -ENODEV; =20 @@ -326,6 +359,8 @@ int typec_cable_altmode_vdm(struct typec_altmode *adev,= enum typec_plug_index so =20 if (!adev) return 0; + if (adev->mode_kind !=3D TYPEC_MODE_KIND_ALTMODE) + return -EOPNOTSUPP; =20 altmode =3D to_altmode(adev); =20 @@ -422,7 +457,8 @@ struct typec_altmode *typec_match_altmode(struct typec_= altmode **altmodes, for (i =3D 0; i < n; i++) { if (!altmodes[i]) break; - if (altmodes[i]->svid =3D=3D svid && altmodes[i]->mode =3D=3D mode) + if (altmodes[i]->mode_kind =3D=3D TYPEC_MODE_KIND_ALTMODE && + altmodes[i]->svid =3D=3D svid && altmodes[i]->mode =3D=3D mode) return altmodes[i]; } =20 @@ -472,6 +508,10 @@ static int typec_match(struct device *dev, const struc= t device_driver *driver) if (!is_typec_partner_altmode(dev)) return 0; =20 + /* USB4 mode devices report firmware state through notifiers only. */ + if (altmode->mode_kind !=3D TYPEC_MODE_KIND_ALTMODE) + return 0; + for (id =3D drv->id_table; id->svid; id++) if (id->svid =3D=3D altmode->svid) return 1; @@ -485,6 +525,9 @@ static int typec_uevent(const struct device *dev, struc= t kobj_uevent_env *env) if (!is_typec_partner_altmode(dev)) return 0; =20 + if (altmode->mode_kind =3D=3D TYPEC_MODE_KIND_USB4) + return add_uevent_var(env, "MODE_KIND=3Dusb4"); + if (add_uevent_var(env, "SVID=3D%04X", altmode->svid)) return -ENOMEM; =20 diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 5808a3ef0d6c..869d6857c0dc 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -233,23 +233,24 @@ static const char * const usb_modes[] =3D { static int altmode_match(struct device *dev, const void *data) { struct typec_altmode *adev =3D to_typec_altmode(dev); - const struct typec_device_id *id =3D data; + const struct typec_altmode *match =3D data; =20 if (!is_typec_port_altmode(dev)) return 0; =20 - return (adev->svid =3D=3D id->svid); + if (adev->mode_kind !=3D match->mode_kind) + return 0; + return adev->mode_kind =3D=3D TYPEC_MODE_KIND_USB4 || adev->svid =3D=3D m= atch->svid; } =20 static void typec_altmode_set_partner(struct altmode *altmode) { struct typec_altmode *adev =3D &altmode->adev; - struct typec_device_id id =3D { adev->svid }; struct typec_port *port =3D typec_altmode2port(adev); struct altmode *partner; struct device *dev; =20 - dev =3D device_find_child(&port->dev, &id, altmode_match); + dev =3D device_find_child(&port->dev, adev, altmode_match); if (!dev) return; =20 @@ -296,6 +297,8 @@ static void typec_altmode_put_partner(struct altmode *a= ltmode) * * If a partner or cable plug executes Enter/Exit Mode command successfull= y, the * drivers use this routine to report the updated state of the mode. + * For USB4 partner modes, drivers use this routine to report entry through + * Enter_USB and exit from USB4. */ void typec_altmode_update_active(struct typec_altmode *adev, bool active) { @@ -319,8 +322,10 @@ void typec_altmode_update_active(struct typec_altmode = *adev, bool active) active ? TYPEC_ALTMODE_ENTERED : TYPEC_ALTMODE_EXITED, adev); - snprintf(dir, sizeof(dir), "mode%d", adev->mode); - sysfs_notify(&adev->dev.kobj, dir, "active"); + if (adev->mode_kind =3D=3D TYPEC_MODE_KIND_ALTMODE) { + snprintf(dir, sizeof(dir), "mode%d", adev->mode); + sysfs_notify(&adev->dev.kobj, dir, "active"); + } sysfs_notify(&adev->dev.kobj, NULL, "active"); kobject_uevent(&adev->dev.kobj, KOBJ_CHANGE); } @@ -502,13 +507,30 @@ svid_show(struct device *dev, struct device_attribute= *attr, char *buf) } static DEVICE_ATTR_RO(svid); =20 +static ssize_t mode_kind_show(struct device *dev, struct device_attribute = *attr, + char *buf) +{ + struct typec_altmode *adev =3D to_typec_altmode(dev); + + return sysfs_emit(buf, "%s\n", + adev->mode_kind =3D=3D TYPEC_MODE_KIND_USB4 ? "usb4" : "altmode"); +} +static DEVICE_ATTR_RO(mode_kind); + +static ssize_t eudo_show(struct device *dev, struct device_attribute *attr= , char *buf) +{ + return sysfs_emit(buf, "0x%08x\n", to_typec_altmode(dev)->eudo); +} +static DEVICE_ATTR_RO(eudo); + static int increment_duplicated_priority(struct device *dev, void *data) { if (is_typec_port_altmode(dev)) { struct typec_altmode **alt_target =3D (struct typec_altmode **)data; struct typec_altmode *alt =3D to_typec_altmode(dev); =20 - if (alt !=3D *alt_target && alt->priority =3D=3D (*alt_target)->priority= ) { + if (alt->mode_kind =3D=3D TYPEC_MODE_KIND_ALTMODE && + alt !=3D *alt_target && alt->priority =3D=3D (*alt_target)->priority= ) { alt->priority++; *alt_target =3D alt; return 1; @@ -523,7 +545,8 @@ static int find_duplicated_priority(struct device *dev,= void *data) struct typec_altmode **alt_target =3D (struct typec_altmode **)data; struct typec_altmode *alt =3D to_typec_altmode(dev); =20 - if (alt !=3D *alt_target && alt->priority =3D=3D (*alt_target)->priority) + if (alt->mode_kind =3D=3D TYPEC_MODE_KIND_ALTMODE && + alt !=3D *alt_target && alt->priority =3D=3D (*alt_target)->priority) return 1; } return 0; @@ -579,6 +602,8 @@ static ssize_t priority_show(struct device *dev, static DEVICE_ATTR_RW(priority); =20 static struct attribute *typec_altmode_attrs[] =3D { + &dev_attr_mode_kind.attr, + &dev_attr_eudo.attr, &dev_attr_active.attr, &dev_attr_mode.attr, &dev_attr_svid.attr, @@ -593,6 +618,18 @@ static umode_t typec_altmode_attr_is_visible(struct ko= bject *kobj, struct typec_altmode *adev =3D to_typec_altmode(kobj_to_dev(kobj)); struct typec_port *port =3D typec_altmode2port(adev); =20 + if (adev->mode_kind =3D=3D TYPEC_MODE_KIND_USB4) { + if (attr =3D=3D &dev_attr_svid.attr || attr =3D=3D &dev_attr_mode.attr || + attr =3D=3D &dev_attr_vdo.attr || attr =3D=3D &dev_attr_priority.att= r) + return 0; + if (attr =3D=3D &dev_attr_eudo.attr && !is_typec_partner(adev->dev.paren= t)) + return 0; + if (attr =3D=3D &dev_attr_active.attr) + return 0444; + } else if (attr =3D=3D &dev_attr_eudo.attr) { + return 0; + } + if (attr =3D=3D &dev_attr_active.attr) { if (!is_typec_port(adev->dev.parent)) { if (!port->mode_control || !adev->ops || !adev->ops->activate) @@ -698,20 +735,33 @@ typec_register_altmode(struct device *parent, const struct typec_altmode_desc *desc, const struct device_type *type) { - unsigned int id =3D altmode_id_get(parent); bool is_port =3D is_typec_port(parent); struct altmode *alt; + unsigned int id; int ret; =20 + if (desc->mode_kind !=3D TYPEC_MODE_KIND_ALTMODE && + desc->mode_kind !=3D TYPEC_MODE_KIND_USB4) + return ERR_PTR(-EINVAL); + if (desc->mode_kind =3D=3D TYPEC_MODE_KIND_USB4 && + (desc->svid || desc->mode || is_typec_plug(parent))) + return ERR_PTR(-EINVAL); + + id =3D altmode_id_get(parent); + alt =3D kzalloc_obj(*alt); if (!alt) { altmode_id_remove(parent, id); return ERR_PTR(-ENOMEM); } =20 + alt->adev.mode_kind =3D desc->mode_kind; alt->adev.svid =3D desc->svid; alt->adev.mode =3D desc->mode; - alt->adev.vdo =3D desc->vdo; + if (desc->mode_kind =3D=3D TYPEC_MODE_KIND_USB4) + alt->adev.eudo =3D desc->eudo; + else + alt->adev.vdo =3D desc->vdo; alt->adev.mode_selection =3D desc->mode_selection; alt->roles =3D desc->roles; alt->id =3D id; @@ -730,7 +780,8 @@ typec_register_altmode(struct device *parent, sprintf(alt->group_name, "mode%d", desc->mode); alt->group.name =3D alt->group_name; alt->group.attrs =3D alt->attrs; - alt->groups[0] =3D &alt->group; + if (desc->mode_kind =3D=3D TYPEC_MODE_KIND_ALTMODE) + alt->groups[0] =3D &alt->group; =20 alt->adev.dev.parent =3D parent; alt->adev.dev.groups =3D alt->groups; @@ -1110,6 +1161,10 @@ EXPORT_SYMBOL_GPL(typec_partner_set_num_altmodes); * SVID listed in response to Discover Modes command need to be listed in = an * array in @desc. * + * For USB4, set @desc->mode_kind to %TYPEC_MODE_KIND_USB4 and @desc->eudo= to the + * EUDO and leave SVID and mode zero. USB4 devices expose firmware state + * through notifications and do not bind alternate-mode drivers. + * * Returns handle to the alternate mode on success or ERR_PTR on failure. */ struct typec_altmode * @@ -2698,6 +2753,9 @@ EXPORT_SYMBOL_GPL(typec_get_fw_cap); * This routine is used to register an alternate mode that @port is capabl= e of * supporting. * + * For USB4, set @desc->mode_kind to %TYPEC_MODE_KIND_USB4 and leave SVID = and + * mode zero. Register it before the USB4 partner mode, which carries the = EUDO. + * * Returns handle to the alternate mode on success or ERR_PTR on failure. */ struct typec_altmode * @@ -2727,6 +2785,9 @@ typec_port_register_altmode(struct typec_port *port, to_altmode(adev)->mux =3D mux; to_altmode(adev)->retimer =3D retimer; =20 + if (adev->mode_kind =3D=3D TYPEC_MODE_KIND_USB4) + return adev; + ret =3D typec_mode_set_priority(adev, 0); if (ret) { typec_unregister_altmode(adev); diff --git a/drivers/usb/typec/mode_selection.c b/drivers/usb/typec/mode_se= lection.c index cd376f67e445..5e378deed5c2 100644 --- a/drivers/usb/typec/mode_selection.c +++ b/drivers/usb/typec/mode_selection.c @@ -66,7 +66,8 @@ static int activate_altmode(struct device *dev, void *dat= a) struct typec_altmode *alt =3D to_typec_altmode(dev); struct mode_order *order =3D (struct mode_order *)data; =20 - if (order->svid =3D=3D alt->svid) { + if (alt->mode_kind =3D=3D TYPEC_MODE_KIND_ALTMODE && + order->svid =3D=3D alt->svid) { if (alt->ops && alt->ops->activate) order->result =3D alt->ops->activate(alt, order->enter); else @@ -215,7 +216,8 @@ static int altmode_add_to_list(struct device *dev, void= *data) const struct typec_altmode *pdev =3D typec_altmode_get_partner(altmode); struct mode_state *ms; =20 - if (pdev && altmode->ops && altmode->ops->activate) { + if (altmode->mode_kind =3D=3D TYPEC_MODE_KIND_ALTMODE && + pdev && altmode->ops && altmode->ops->activate) { ms =3D kzalloc_obj(*ms); if (!ms) return -ENOMEM; diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 914a6f0844c5..add2c1368774 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -138,11 +138,23 @@ struct usb_pd_identity { int typec_partner_set_identity(struct typec_partner *partner); int typec_cable_set_identity(struct typec_cable *cable); =20 +/** + * enum typec_mode_kind - Protocol represented by a Type-C mode device + * @TYPEC_MODE_KIND_ALTMODE: SVID-specific alternate mode (the default) + * @TYPEC_MODE_KIND_USB4: USB4, negotiated using Enter_USB + */ +enum typec_mode_kind { + TYPEC_MODE_KIND_ALTMODE, + TYPEC_MODE_KIND_USB4, +}; + /* * struct typec_altmode_desc - USB Type-C Alternate Mode Descriptor * @svid: Standard or Vendor ID * @mode: Index of the Mode - * @vdo: VDO returned by Discover Modes USB PD command + * @vdo: Discover Modes VDO for SVID-specific alternate modes + * @eudo: Enter_USB Data Object for USB4 partner modes + * @mode_kind: Protocol kind; SVID and mode are unused for USB4 * @roles: Only for ports. DRP if the mode is available in both roles * @inactive: Only for ports. Make this port inactive (default is active). * @@ -152,11 +164,15 @@ int typec_cable_set_identity(struct typec_cable *cabl= e); struct typec_altmode_desc { u16 svid; u8 mode; - u32 vdo; + union { + u32 vdo; + u32 eudo; + }; /* Only used with ports */ enum typec_port_data roles; bool inactive; bool mode_selection; + enum typec_mode_kind mode_kind; }; =20 void typec_partner_set_pd_revision(struct typec_partner *partner, u16 pd_r= evision); diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_al= tmode.h index ef21ead551be..8d31e35e9320 100644 --- a/include/linux/usb/typec_altmode.h +++ b/include/linux/usb/typec_altmode.h @@ -24,7 +24,9 @@ struct typec_altmode_ops; * @dev: Driver model's view of this device * @svid: Standard or Vendor ID (SVID) of the alternate mode * @mode: Index of the Mode - * @vdo: VDO returned by Discover Modes USB PD command + * @vdo: Discover Modes VDO for SVID-specific alternate modes + * @eudo: Enter_USB Data Object for USB4 partner modes + * @mode_kind: Protocol kind; SVID and mode are unused for USB4 * @active: Tells has the mode been entered or not * @priority: Priority used by the automatic alternate mode selection proc= ess * @mode_selection: Whether entry to this alternate mode is managed by the @@ -37,7 +39,11 @@ struct typec_altmode { struct device dev; u16 svid; int mode; - u32 vdo; + union { + u32 vdo; + u32 eudo; + }; + enum typec_mode_kind mode_kind; unsigned int active:1; u8 priority; bool mode_selection; --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7A4831960B; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; cv=none; b=cJ11QaNJ51YBpuOubaYGyKE8Mr2zaSYc/N9OlxB7uVriAD/WLSU7tYQqydPiWbkpxuuY9myp/mOkESRgCsUFd9YumX7XF3uDlILAJxokevHbZoRFWzYA34Z3dFhE+Lc6tfw9SeZj6ii6/luEJ/K+/Hwg79NhuZiFqe6/n7WHPSI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; c=relaxed/simple; bh=HIg42Vsn0TNmV8kxJI54k7Wj89qIig0luyI+sG+agh8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jWg/MCaSuyz7Eb5/nh4SI99QLPFR/hMg3cv1B+gq/jcipzIOzmSQ2MHIbDBF0Yh6fgRqHXZh4kKDy6za/jtOtO1giH55jLMvFTr5yTUZTJXC4j1DvTqTgUbboJoAYi15FEIeLYCi74isR5jLEuK2E8qD7GKGh1aRmOnuhiSNGEM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JGiHzvVX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JGiHzvVX" Received: by smtp.kernel.org (Postfix) with ESMTPS id 62656C2BD04; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=HIg42Vsn0TNmV8kxJI54k7Wj89qIig0luyI+sG+agh8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JGiHzvVXZFi6R/WMjPm8By+ZLAS4DPhew68YEq0MAk2LAirDho3iepimJXWhURxA3 V62qZKppExPfR94QRzkGjK5YAa13dJ4IwNlvXrpZYlkWKC8S85Qyz4V5XD4kDKBvFn 8wvE8j3bnIIbjsveD+j4PaS2Ac8hRW8xwYxJ5GoE403cq9nlNBGJ+CH970PIlH94U0 0VprXoskBxjcGporkvMKTlBDgWMzbDI6fTNGEiZ/GRMKoVDK68/LsIfFxjlC+jG0Cd YF2huZEMN9EkluMUAExncm8c+blPkrXOcb42FMdibaivvzYGFqBgjPakH0o2UnWwUO myy/bVSrugypA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B241C79FA0; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:26 +0200 Subject: [PATCH v2 03/22] usb: typec: tipd: Register a USB4 port mode for CD321x 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-3-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2166; i=sven@kernel.org; h=from:subject:message-id; bh=HIg42Vsn0TNmV8kxJI54k7Wj89qIig0luyI+sG+agh8=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTbuX8HqzOHkmRlrHf5xS6rrOkaVksumZtuvWVtFin a+YGVw7SlkYxLgYZMUUWbbvtzd98vCN4NJNl97DzGFlAhnCwMUpABOx/c/wv3D+xkWzTmcX3Pkh YyHK7rVyCa+sQ3wqd9B7DmHh1MUWyxn+50apskv23p+/UJX9WOr+ggPHQkxWhbjsW2N49LqybqM lNwA= X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 Register a USB4 mode next to the DP and Thunderbolt alternate modes so that negotiated USB4 partner modes can be linked to the port. Identify it using TYPEC_MODE_KIND_USB4 without an SVID or mode index. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/usb/typec/tipd/core.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index f76f563dc42b..8c7f93d4270e 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -211,6 +211,7 @@ struct cd321x { =20 struct typec_altmode *port_altmode_dp; struct typec_altmode *port_altmode_tbt; + struct typec_altmode *port_altmode_usb4; =20 struct typec_mux *mux; struct typec_mux_state state; @@ -1312,6 +1313,18 @@ static int cd321x_register_port_altmodes(struct cd32= 1x *cd321x) } cd321x->port_altmode_tbt =3D amode; =20 + memset(&desc, 0, sizeof(desc)); + desc.mode_kind =3D TYPEC_MODE_KIND_USB4; + amode =3D typec_port_register_altmode(cd321x->tps.port, &desc); + if (IS_ERR(amode)) { + typec_unregister_altmode(cd321x->port_altmode_dp); + typec_unregister_altmode(cd321x->port_altmode_tbt); + cd321x->port_altmode_dp =3D NULL; + cd321x->port_altmode_tbt =3D NULL; + return PTR_ERR(amode); + } + cd321x->port_altmode_usb4 =3D amode; + return 0; } =20 @@ -1347,8 +1360,10 @@ cd321x_register_port(struct tps6598x *tps, struct fw= node_handle *fwnode) err_unregister_altmodes: typec_unregister_altmode(cd321x->port_altmode_dp); typec_unregister_altmode(cd321x->port_altmode_tbt); + typec_unregister_altmode(cd321x->port_altmode_usb4); cd321x->port_altmode_dp =3D NULL; cd321x->port_altmode_tbt =3D NULL; + cd321x->port_altmode_usb4 =3D NULL; err_unregister_port: typec_unregister_port(tps->port); return ret; @@ -1371,6 +1386,8 @@ cd321x_unregister_port(struct tps6598x *tps) cd321x->port_altmode_dp =3D NULL; typec_unregister_altmode(cd321x->port_altmode_tbt); cd321x->port_altmode_tbt =3D NULL; + typec_unregister_altmode(cd321x->port_altmode_usb4); + cd321x->port_altmode_usb4 =3D NULL; typec_unregister_port(tps->port); } =20 --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B9718363C63; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; cv=none; b=fWE+2LfQ3nD1Jn9dNggro/FyLsHx7o4///SPsHs++6UIFmWn5l2fCNas75INtZ8gWdpnD7BsYlHIxhBXAHJ1cgEgaHhfrF0xf5kVCIolpFlcTPJ/9KHR6mIG/ZzAA6vcxZMZM3YS+Z6AKw7k/Ey/WgJnpn5V8aBxeyO0C9vXhHc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; c=relaxed/simple; bh=B634TnNykRGoLyUS0h7xbpVjfO6WrqvJEEZ0/eEafiM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TjM6ECKy7O8eDMUvzaZhZuQT3iZflOcTjFNsD7phN0N/D0QUL7baIhu3rMUnW66U6PhXgdnheBXAmEKo/XTBAWEmv8bP0iFN4k8SBR8PhdujqpSHsF0UU8C2QuPVc91M0+Pwrqo77xm6X+sbLTEa6yUQeIeXahLHkXVYWYCtDbU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JX2SobR0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JX2SobR0" Received: by smtp.kernel.org (Postfix) with ESMTPS id 73BC6C2BD01; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=B634TnNykRGoLyUS0h7xbpVjfO6WrqvJEEZ0/eEafiM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JX2SobR0UyxYTtL/4Tru+EoJ5ES2JmqKmrObml57fGSrtWpgeerdNqdrJJ/hWgqrG e8wt0iknJx0XKKgT4S8TBG1qkJBF+XWvfbn+0r+9wZ0mVswkR27PcmzT8bfXdurUiw JDviAArnSKM3tcgc7OIQ/js7g0UaUAiIUG17T2v2rgqDoDIIdJQFEYK9K0nx+rjGeD Ikx1UlqeLw0y9uybjLPxxo9weQFlCYacs0K6V1czKjz4VGgutfHk0S35eI9VbLcmXD R+ysreJs0dpnphNLukGtAKOy1Obcp1VcFnCfiX1HjON8TkUWNzK+t93IWnF5tMqH7t CCxv+B/unSwJA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D532C79FA3; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:27 +0200 Subject: [PATCH v2 04/22] usb: typec: tipd: Publish CD321x partner alternate modes 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-4-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=12306; i=sven@kernel.org; h=from:subject:message-id; bh=B634TnNykRGoLyUS0h7xbpVjfO6WrqvJEEZ0/eEafiM=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTXviH/5qfx0zcX1//lzFxWr8/ee1bqd/7Cw8u9xue cHz5e6rOkpZGMS4GGTFFFm277c3ffLwjeDSTZfew8xhZQIZwsDFKQATCXjByPD34s3TlyuOxh1k knoff/z71SPmhckX95qnf5bN8H1btmcuw/+090+zcvaayKq8WeSncnVq4tb7ixhOHfTgmMPwtIn 7PiM7AA== X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 Register Thunderbolt partner and cable modes once their VDOs are available and USB4 as a partner mode once firmware has negotiated it, with the EUDO stored in its eudo field. The CD321X firmware still controls mode selection and entry itself. This just makes the negotiated modes available to consumers on the Type-C bus. Mark them active after the Type-C mux has been configured and deactivate them before the mux is switched back to its safe state to make sure any consuming driver is initialized and shut down in the correct order. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/usb/typec/tipd/core.c | 224 ++++++++++++++++++++++++++++++++++++++= +--- 1 file changed, 209 insertions(+), 15 deletions(-) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index 8c7f93d4270e..218b52b07b5a 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -213,6 +213,12 @@ struct cd321x { struct typec_altmode *port_altmode_tbt; struct typec_altmode *port_altmode_usb4; =20 + struct typec_cable *cable; + struct typec_plug *plug; + struct typec_altmode *plug_altmode_tbt; + struct typec_altmode *partner_altmode_tbt; + struct typec_altmode *partner_altmode_usb4; + struct typec_mux *mux; struct typec_mux_state state; =20 @@ -674,13 +680,156 @@ static void tps6598x_handle_plug_event(struct tps659= 8x *tps, u32 status) } } =20 +static void cd321x_unregister_tbt_altmodes(struct cd321x *cd321x) +{ + if (cd321x->partner_altmode_tbt && cd321x->partner_altmode_tbt->active) + typec_altmode_update_active(cd321x->partner_altmode_tbt, false); + if (cd321x->plug_altmode_tbt && cd321x->plug_altmode_tbt->active) + typec_altmode_update_active(cd321x->plug_altmode_tbt, false); + + typec_unregister_altmode(cd321x->partner_altmode_tbt); + cd321x->partner_altmode_tbt =3D NULL; + typec_unregister_altmode(cd321x->plug_altmode_tbt); + cd321x->plug_altmode_tbt =3D NULL; + typec_unregister_plug(cd321x->plug); + cd321x->plug =3D NULL; + typec_unregister_cable(cd321x->cable); + cd321x->cable =3D NULL; +} + +static void cd321x_unregister_usb4_altmode(struct cd321x *cd321x) +{ + if (cd321x->partner_altmode_usb4 && cd321x->partner_altmode_usb4->active) + typec_altmode_update_active(cd321x->partner_altmode_usb4, false); + + typec_unregister_altmode(cd321x->partner_altmode_usb4); + cd321x->partner_altmode_usb4 =3D NULL; +} + +static void cd321x_unregister_partner_altmodes(struct cd321x *cd321x) +{ + cd321x_unregister_tbt_altmodes(cd321x); + cd321x_unregister_usb4_altmode(cd321x); +} + +static void cd321x_deactivate_altmodes(struct cd321x *cd321x) +{ + if (cd321x->partner_altmode_tbt && cd321x->partner_altmode_tbt->active) + typec_altmode_update_active(cd321x->partner_altmode_tbt, false); + if (cd321x->plug_altmode_tbt && cd321x->plug_altmode_tbt->active) + typec_altmode_update_active(cd321x->plug_altmode_tbt, false); + if (cd321x->partner_altmode_usb4 && cd321x->partner_altmode_usb4->active) + typec_altmode_update_active(cd321x->partner_altmode_usb4, false); +} + +static int cd321x_register_tbt_altmodes(struct cd321x *cd321x, + struct typec_thunderbolt_data *tbt_data, + u32 data_status) +{ + struct typec_cable_desc cable_desc =3D { + .type =3D USB_PLUG_TYPE_C, + .active =3D !!(data_status & TPS_DATA_STATUS_ACTIVE_CABLE), + }; + struct typec_plug_desc plug_desc =3D { + .index =3D TYPEC_PLUG_SOP_P, + }; + struct typec_altmode_desc desc =3D { + .svid =3D USB_TYPEC_TBT_SID, + .mode =3D TYPEC_ANY_MODE, + .mode_selection =3D true, + }; + int ret; + + if (cd321x->partner_altmode_tbt && cd321x->plug_altmode_tbt && + cd321x->partner_altmode_tbt->vdo =3D=3D tbt_data->device_mode && + cd321x->plug_altmode_tbt->vdo =3D=3D tbt_data->cable_mode) + return 0; + + cd321x_unregister_tbt_altmodes(cd321x); + + cd321x->cable =3D typec_register_cable(cd321x->tps.port, &cable_desc); + if (IS_ERR(cd321x->cable)) { + ret =3D PTR_ERR(cd321x->cable); + cd321x->cable =3D NULL; + return ret; + } + + cd321x->plug =3D typec_register_plug(cd321x->cable, &plug_desc); + if (IS_ERR(cd321x->plug)) { + ret =3D PTR_ERR(cd321x->plug); + cd321x->plug =3D NULL; + goto err_unregister; + } + + desc.vdo =3D tbt_data->cable_mode; + cd321x->plug_altmode_tbt =3D typec_plug_register_altmode(cd321x->plug, &d= esc); + if (IS_ERR(cd321x->plug_altmode_tbt)) { + ret =3D PTR_ERR(cd321x->plug_altmode_tbt); + cd321x->plug_altmode_tbt =3D NULL; + goto err_unregister; + } + + desc.vdo =3D tbt_data->device_mode; + cd321x->partner_altmode_tbt =3D + typec_partner_register_altmode(cd321x->tps.partner, &desc); + if (IS_ERR(cd321x->partner_altmode_tbt)) { + ret =3D PTR_ERR(cd321x->partner_altmode_tbt); + cd321x->partner_altmode_tbt =3D NULL; + goto err_unregister; + } + + return 0; + +err_unregister: + cd321x_unregister_tbt_altmodes(cd321x); + return ret; +} + +static int cd321x_register_usb4_altmode(struct cd321x *cd321x, u32 eudo) +{ + struct typec_altmode_desc desc =3D { + .mode_kind =3D TYPEC_MODE_KIND_USB4, + .eudo =3D eudo, + .mode_selection =3D true, + }; + int ret; + + if (cd321x->partner_altmode_usb4 && + cd321x->partner_altmode_usb4->eudo =3D=3D eudo) + return 0; + + cd321x_unregister_usb4_altmode(cd321x); + cd321x->partner_altmode_usb4 =3D + typec_partner_register_altmode(cd321x->tps.partner, &desc); + if (IS_ERR(cd321x->partner_altmode_usb4)) { + ret =3D PTR_ERR(cd321x->partner_altmode_usb4); + cd321x->partner_altmode_usb4 =3D NULL; + return ret; + } + + return 0; +} + static void cd321x_typec_update_mode(struct tps6598x *tps, struct cd321x_s= tatus *st) { struct cd321x *cd321x =3D container_of(tps, struct cd321x, tps); + int ret; + + if ((st->data_status & TPS_DATA_STATUS_DATA_CONNECTION) && + !(st->data_status & CD321X_DATA_STATUS_USB4_CONNECTION)) { + if (st->data_status & TPS_DATA_STATUS_USB3_CONNECTION) + typec_partner_set_usb_mode(tps->partner, USB_MODE_USB3); + else if (st->data_status & TPS_DATA_STATUS_USB2_CONNECTION) + typec_partner_set_usb_mode(tps->partner, USB_MODE_USB2); + } =20 if (!(st->data_status & TPS_DATA_STATUS_DATA_CONNECTION)) { - if (cd321x->state.mode =3D=3D TYPEC_STATE_SAFE) + if (cd321x->state.mode =3D=3D TYPEC_STATE_SAFE && + (!cd321x->partner_altmode_tbt || !cd321x->partner_altmode_tbt->activ= e) && + (!cd321x->partner_altmode_usb4 || !cd321x->partner_altmode_usb4->act= ive)) return; + + cd321x_deactivate_altmodes(cd321x); cd321x->state.alt =3D NULL; cd321x->state.mode =3D TYPEC_STATE_SAFE; cd321x->state.data =3D NULL; @@ -718,6 +867,7 @@ static void cd321x_typec_update_mode(struct tps6598x *t= ps, struct cd321x_status return; } =20 + cd321x_deactivate_altmodes(cd321x); dp_data.status =3D le32_to_cpu(st->dp_sid_status.status_rx); dp_data.conf =3D le32_to_cpu(st->dp_sid_status.configure); cd321x->state.alt =3D cd321x->port_altmode_dp; @@ -728,7 +878,8 @@ static void cd321x_typec_update_mode(struct tps6598x *t= ps, struct cd321x_status struct typec_thunderbolt_data tbt_data; =20 if (cd321x->state.alt =3D=3D cd321x->port_altmode_tbt && - cd321x->state.mode =3D=3D TYPEC_TBT_MODE) + cd321x->state.mode =3D=3D TYPEC_TBT_MODE && + cd321x->partner_altmode_tbt && cd321x->partner_altmode_tbt->active) return; =20 tbt_data.cable_mode =3D TBT_MODE | @@ -744,27 +895,54 @@ static void cd321x_typec_update_mode(struct tps6598x = *tps, struct cd321x_status (u32)le16_to_cpu(st->intel_vid_status.device_mode) << 16; tbt_data.enter_vdo =3D (u32)le16_to_cpu(st->intel_vid_status.enter_vdo) << 16; + + ret =3D cd321x_register_tbt_altmodes(cd321x, &tbt_data, st->data_status); + if (ret) { + dev_err(tps->dev, "failed to register Thunderbolt altmodes: %d\n", ret); + return; + } + + cd321x_deactivate_altmodes(cd321x); cd321x->state.alt =3D cd321x->port_altmode_tbt; cd321x->state.mode =3D TYPEC_TBT_MODE; cd321x->state.data =3D &tbt_data; - typec_mux_set(cd321x->mux, &cd321x->state); + ret =3D typec_mux_set(cd321x->mux, &cd321x->state); + if (!ret) { + typec_altmode_update_active(cd321x->plug_altmode_tbt, true); + typec_altmode_update_active(cd321x->partner_altmode_tbt, true); + } } else if (st->data_status & CD321X_DATA_STATUS_USB4_CONNECTION) { struct enter_usb_data eusb_data; =20 - if (cd321x->state.alt =3D=3D NULL && cd321x->state.mode =3D=3D TYPEC_MOD= E_USB4) + if (!cd321x->state.alt && + cd321x->state.mode =3D=3D TYPEC_MODE_USB4 && + cd321x->partner_altmode_usb4 && cd321x->partner_altmode_usb4->active) return; =20 eusb_data.eudo =3D le32_to_cpu(st->usb4_status.eudo); eusb_data.active_link_training =3D !!(st->data_status & TPS_DATA_STATUS_ACTIVE_LINK_TRAIN); =20 + ret =3D cd321x_register_usb4_altmode(cd321x, eusb_data.eudo); + if (ret) { + dev_err(tps->dev, "failed to register USB4 altmode: %d\n", ret); + return; + } + + cd321x_deactivate_altmodes(cd321x); cd321x->state.alt =3D NULL; cd321x->state.data =3D &eusb_data; cd321x->state.mode =3D TYPEC_MODE_USB4; - typec_mux_set(cd321x->mux, &cd321x->state); + ret =3D typec_mux_set(cd321x->mux, &cd321x->state); + if (!ret) { + typec_partner_set_usb_mode(tps->partner, USB_MODE_USB4); + typec_altmode_update_active(cd321x->partner_altmode_usb4, true); + } } else { if (cd321x->state.alt =3D=3D NULL && cd321x->state.mode =3D=3D TYPEC_STA= TE_USB) return; + + cd321x_deactivate_altmodes(cd321x); cd321x->state.alt =3D NULL; cd321x->state.mode =3D TYPEC_STATE_USB; cd321x->state.data =3D NULL; @@ -819,24 +997,30 @@ static void cd321x_update_work(struct work_struct *wo= rk) &cd321x->cur_partner_identity, sizeof(struct usb_pd_identity)))); =20 /* If we are switching from an active role, transition to USB_ROLE_NONE f= irst */ - if (old_role !=3D USB_ROLE_NONE && (new_role !=3D old_role || was_disconn= ected)) + if (old_role !=3D USB_ROLE_NONE && + (new_role !=3D old_role || partner_changed || was_disconnected)) usb_role_switch_set_role(tps->role_sw, USB_ROLE_NONE); =20 - /* Process partner disconnection or change */ - if (!new_connected || partner_changed) { - if (!IS_ERR(tps->partner)) - typec_unregister_partner(tps->partner); - tps->partner =3D NULL; - } - - /* If there was a disconnection, set PHY to off */ - if (!new_connected || was_disconnected) { + /* + * Also deactivate any altmodes and switch to SAFE_STATE if there was an + * active connection. + */ + if (!new_connected || partner_changed || was_disconnected) { + cd321x_deactivate_altmodes(cd321x); cd321x->state.alt =3D NULL; cd321x->state.mode =3D TYPEC_STATE_SAFE; cd321x->state.data =3D NULL; typec_set_mode(tps->port, TYPEC_STATE_SAFE); } =20 + /* Process partner disconnection or change after all child modes exited. = */ + if (!new_connected || partner_changed) { + cd321x_unregister_partner_altmodes(cd321x); + if (!IS_ERR(tps->partner)) + typec_unregister_partner(tps->partner); + tps->partner =3D NULL; + } + /* Update Type-C properties */ typec_set_pwr_opmode(tps->port, pwr_opmode); typec_set_pwr_role(tps->port, TPS_STATUS_TO_TYPEC_PORTROLE(st.status)); @@ -863,6 +1047,7 @@ static void cd321x_update_work(struct work_struct *wor= k) tps->partner =3D typec_register_partner(tps->port, &desc); if (IS_ERR(tps->partner)) { dev_warn(tps->dev, "%s: failed to register partner\n", __func__); + tps->partner =3D NULL; return; } =20 @@ -1380,6 +1565,7 @@ cd321x_unregister_port(struct tps6598x *tps) { struct cd321x *cd321x =3D container_of(tps, struct cd321x, tps); =20 + cd321x_unregister_partner_altmodes(cd321x); typec_mux_put(cd321x->mux); cd321x->mux =3D NULL; typec_unregister_altmode(cd321x->port_altmode_dp); @@ -1802,6 +1988,14 @@ static void cd321x_remove(struct tps6598x *tps) struct cd321x *cd321x =3D container_of(tps, struct cd321x, tps); =20 cancel_delayed_work_sync(&cd321x->update_work); + + guard(mutex)(&tps->lock); + cd321x_deactivate_altmodes(cd321x); + cd321x->state.alt =3D NULL; + cd321x->state.mode =3D TYPEC_STATE_SAFE; + cd321x->state.data =3D NULL; + typec_set_mode(tps->port, TYPEC_STATE_SAFE); + cd321x_unregister_partner_altmodes(cd321x); } =20 static int tps6598x_probe(struct i2c_client *client) --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA1413C278A; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; cv=none; b=L3/n1f1/qDKRe7Ei5jST2RFvaj2ltFs06Fd6bcM9kAVTMuFCgmjc7l7k8MXBIMnZOgPGwt5Uvan9MMSOMVOYJ6Bjx4/OOZy2uhhWxH1l17ULj6sxqBeBuXI+LAfmjF3Ms4tnWBWKPTfNdBbTWcGRafj0AernJIHTI7FBDRU+g2o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; c=relaxed/simple; bh=OGa+jLNJ4hWT7lKrvc/XuPpp7Ju8W8MN1qobEWF2G78=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=buVffFhwB458CVqvuSh1JUx9hCs54E0L9h9xipgsg6VEk3E7RtAEvq96VTgYHsGhlDb0GnEJIMJjxKhcHPT65tURnDWrjnrmXcaIvMCsC8EhL7v2Q5mvRrdSgT6t/n0Vtdlm4Q0RiS83r3DRwZ/S5GCePFx31dEYkpGByUrKjdc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nQG4c/fY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nQG4c/fY" Received: by smtp.kernel.org (Postfix) with ESMTPS id 85B23C4AF14; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=OGa+jLNJ4hWT7lKrvc/XuPpp7Ju8W8MN1qobEWF2G78=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=nQG4c/fYpbokm8d5GtPuCTxiPYn44rmqCqiQumj7SaNj1008ZUv/qmZdrHe6rncNl Si3k+YJDXKxwHRPr7KGjr0SUk14dJ7zkBxMtpioX4Xou5YeHYFXArusTW96PB2Kwfm qNr6pkOu45DEvagVhtGr6gBEGHYv+iM1p15j4LJERa2KoOzf6lwa6YYd4N8jAma8NS 5COBKZcojWBtPeXgtIF9sKY+nKBfb7SFwfztzQyJmCEyFyxqvyr+599lnPfqaFkj1x xM6pmVHg5OY5SUu2htHHPx7v4f31Qm5ntGmWfwyi0cKrXvLTbnyK+PGuRfYRFNDXe0 7UwEcd80EeTYA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 703BBC79F85; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:28 +0200 Subject: [PATCH v2 05/22] dt-bindings: thunderbolt: Add Apple USB4/Thunderbolt NHI 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-5-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter , Joshua Peisach X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6446; i=sven@kernel.org; h=from:subject:message-id; bh=OGa+jLNJ4hWT7lKrvc/XuPpp7Ju8W8MN1qobEWF2G78=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTXuius73Ti9o1kmfGKh4nHGV6qld0ZZcVUs+vfNyu /PTLTSxo5SFQYyLQVZMkWX7fnvTJw/fCC7ddOk9zBxWJpAhDFycAjCRU+8Y/vBclJ7zQOXHytev FTgElCRcVxhWXfx4rf/wFL2MSneh2ToM/z2ES7zbTBoK9r5eKVU2P0GF97D4pd9N6zf8NS+sWPQ /iBUA X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 The Native Host Interface (NHI) provides the TX and RX rings used by the software connection manager on Apple Silicon SoCs. The NHI is part of the ACIO host router and is exposed to the main SoC bus while the ACIO co-processor is running. T6000 and T6020 use one DART stream for the TX and RX control rings and one shared by all other rings, which are used for XDomain connections. This likely improves the isolation of those host-to-host connections. The M3 generation uses a slightly insane set of 24 IOMMU entries. These are probably one DART stream for each TX and RX ring. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach Reviewed-by: Rob Herring (Arm) --- .../bindings/thunderbolt/apple,t8103-usb4-nhi.yaml | 151 +++++++++++++++++= ++++ MAINTAINERS | 2 + 2 files changed, 153 insertions(+) diff --git a/Documentation/devicetree/bindings/thunderbolt/apple,t8103-usb4= -nhi.yaml b/Documentation/devicetree/bindings/thunderbolt/apple,t8103-usb4-= nhi.yaml new file mode 100644 index 000000000000..a80c8db3ef51 --- /dev/null +++ b/Documentation/devicetree/bindings/thunderbolt/apple,t8103-usb4-nhi.ya= ml @@ -0,0 +1,151 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thunderbolt/apple,t8103-usb4-nhi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple Silicon USB4/Thunderbolt Native Host Interface (NHI) + +maintainers: + - Sven Peter + +description: | + On Apple Silicon SoCs the Native Host Interface (NHI) is part of the ACIO + host router. It provides the transmit and receive rings used by the soft= ware + connection manager. + + The ACIO co-processor exposes its registers to the main SoC bus while it= is + running. The NHI is therefore represented as a child of the ACIO node. + +properties: + compatible: + oneOf: + - const: apple,t8103-usb4-nhi + - items: + - enum: + - apple,t6000-usb4-nhi + - apple,t6020-usb4-nhi + - apple,t6030-usb4-nhi + - apple,t6031-usb4-nhi + - apple,t8112-usb4-nhi + - apple,t8122-usb4-nhi + - const: apple,t8103-usb4-nhi + + reg: + items: + - description: NHI registers with the transmit and receive rings + - description: + Protocol Defined Field (PDF) bitmasks selecting which frames are + accepted by each receive ring + + reg-names: + items: + - const: nhi + - const: pdf + + interrupts: + description: + One interrupt for each of the 12 transmit rings followed by one for = each + of the 12 receive rings. + maxItems: 24 + + interrupt-names: + items: + - const: txring0 + - const: txring1 + - const: txring2 + - const: txring3 + - const: txring4 + - const: txring5 + - const: txring6 + - const: txring7 + - const: txring8 + - const: txring9 + - const: txring10 + - const: txring11 + - const: rxring0 + - const: rxring1 + - const: rxring2 + - const: rxring3 + - const: rxring4 + - const: rxring5 + - const: rxring6 + - const: rxring7 + - const: rxring8 + - const: rxring9 + - const: rxring10 + - const: rxring11 + + iommus: + minItems: 1 + maxItems: 24 + description: | + T8103 and T8112 use a single IOMMU for all DMA transactions. + + T6000 and T6020 use two IOMMUs: The first is used for transmit ring 0 + and receive ring 0 which carry control traffic. The second is shared= by + all other rings which are only used for XDomain connections to other + hosts. + + T6030, T6031 and T8122 use 24 IOMMUs. These are most likely one DART + stream for each of the 12 transmit and 12 receive rings. + + apple,thunderbolt-drom: + $ref: /schemas/types.yaml#/definitions/uint8-array + description: + DROM of the host router built by the bootloader from Apple's Device = Tree. + + apple,tunable-nhi: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + items: + items: + - description: Register offset + - description: Mask of bits to clear + - description: Bits to set + description: | + List of (register offset, mask, value) tuples copied from Apple's De= vice + Tree, converted by the bootloader and used to configure the NHI after + the co-processor has booted. + +required: + - compatible + - reg + - reg-names + - interrupts + - interrupt-names + - iommus + - apple,thunderbolt-drom + +allOf: + - if: + properties: + compatible: + contains: + enum: + - apple,t6030-usb4-nhi + - apple,t6031-usb4-nhi + - apple,t8122-usb4-nhi + then: + properties: + iommus: + minItems: 24 + maxItems: 24 + else: + if: + properties: + compatible: + contains: + enum: + - apple,t6000-usb4-nhi + - apple,t6020-usb4-nhi + then: + properties: + iommus: + minItems: 2 + maxItems: 2 + else: + properties: + iommus: + maxItems: 1 + +additionalProperties: false diff --git a/MAINTAINERS b/MAINTAINERS index 096fe7535c02..a9d2e2a914c2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2659,6 +2659,7 @@ F: Documentation/devicetree/bindings/rtc/apple,smc-rt= c.yaml F: Documentation/devicetree/bindings/soc/apple/apple,t6000-pmgr-misc.yaml F: Documentation/devicetree/bindings/spi/apple,spi.yaml F: Documentation/devicetree/bindings/spmi/apple,spmi.yaml +F: Documentation/devicetree/bindings/thunderbolt/apple,t8103-usb4-nhi.yaml F: Documentation/devicetree/bindings/usb/apple,dwc3.yaml F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml F: Documentation/hwmon/macsmc-hwmon.rst @@ -27217,6 +27218,7 @@ L: linux-usb@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.g= it F: Documentation/admin-guide/thunderbolt.rst +F: Documentation/devicetree/bindings/thunderbolt/ F: drivers/thunderbolt/ F: include/linux/thunderbolt.h =20 --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB98E3C4B93; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; cv=none; b=azxVbgxGMxX3kim0EReuFvljVFuKZ1pqsUgJVHrvCOhXhzUoWNOgRLqy/V83nj7pvM6Q9OumXql8UiqusJCrLAYlzDxTKDhUsnJlpE1UDBC/dl+dRWIbNGHO6vvoA2fq+YaFNQcYd1JL/Xu0BsUBf1D4Pq5Nxir33y/AZItarg8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; c=relaxed/simple; bh=Lrw4AjJ97p2myBlJOEqJM3QBI7DYQbZi5S0l017NVLM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bWv1pE5EPwMCUM0jAkVLWplUU8l8ys60AG8YVcHv+m4JqH2XDDb2KKEMu8osVkZbefx9jNNdITjfeTLDCSyoun4Kh/ek5kz0lIja32p2mWsA17YMwsmLcAULWT/mma/GQBrTUX+fgqqOiAHuaorwJBp7bFT+7tQKSLuZ3adu11o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=B676NGc/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="B676NGc/" Received: by smtp.kernel.org (Postfix) with ESMTPS id 9507FC32781; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=Lrw4AjJ97p2myBlJOEqJM3QBI7DYQbZi5S0l017NVLM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=B676NGc/3yk3/GO43PXmKq5N2RlKlj7n4G9LmGll0WmYj+a2m+/RfHplkON+mEq9w /9jNusV+Yz0Xn7hq2pomcPxZVYouEr5rUCueTSK0k4Ls+zFoWhcDa8lRAaRblGqZau c0gi3aP6MD9D/pvwCqCbmTamQwl6HBDhkiBz/YMAPyDjQVtSVfpkQus3Ghh0nD5aVp fJeWMH8zRdRDBAPwP4UduIdlEXtIJdEWq5iB1Q7o8/Ud16d1L1k3koPsMU0Cp0At0u 7vNkmUdgOzDo8TKOn+5MlEReSidb8kla3V8W0LzRrUTewSobYMm2V1qOJH2kRr+loh uD7Y6CEZTBP/g== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 82426C79F8C; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:29 +0200 Subject: [PATCH v2 06/22] dt-bindings: thunderbolt: Add Apple USB4/Thunderbolt ACIO block 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-6-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=9043; i=sven@kernel.org; h=from:subject:message-id; bh=Lrw4AjJ97p2myBlJOEqJM3QBI7DYQbZi5S0l017NVLM=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTXttWH5+EHMIZJlVcvJ8lVbye1auNz52yX+2ld6zm Mb8+0NmRykLgxgXg6yYIsv2/famTx6+EVy66dJ7mDmsTCBDGLg4BWAikgUM/z13brGW3GcdkpBx T8bb+nJFfbf7noJ1xYUz+MO8c8t2aTP8D85x7T457cGM/dHVG3pMDtvd2hHV7rtTIjg/b6XY2wn /WQE= X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 Each Type-C port with USB4/Thunderbolt support on Apple Silicon SoCs comes with block called ACIO ("Apple Converged I/O"). It contains a Cortex-M3 co-processor, the hardware blocks implementing the USB4 host router, the Native Host Interface (NHI) and a DART IOMMU. The co-processor exposes the NHI and its DART to the main SoC bus while it is running. ACIO can only be powered on after the Type-C PHY has been switched to USB4/Thunderbolt mode. The Type-C PD controller publishes the negotiated mode and cable information through the Type-C class. ACIO finds the corresponding Type-C port through the OF graph connection. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach Reviewed-by: Rob Herring (Arm) --- .../thunderbolt/apple,t8103-usb4-acio.yaml | 213 +++++++++++++++++= ++++ MAINTAINERS | 1 + 2 files changed, 214 insertions(+) diff --git a/Documentation/devicetree/bindings/thunderbolt/apple,t8103-usb4= -acio.yaml b/Documentation/devicetree/bindings/thunderbolt/apple,t8103-usb4= -acio.yaml new file mode 100644 index 000000000000..5bfe7a66923e --- /dev/null +++ b/Documentation/devicetree/bindings/thunderbolt/apple,t8103-usb4-acio.y= aml @@ -0,0 +1,213 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thunderbolt/apple,t8103-usb4-acio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple Silicon USB4/Thunderbolt Host Router (ACIO) + +maintainers: + - Sven Peter + +description: | + Each Type-C port with USB4/Thunderbolt support on Apple Silicon SoCs has= a + host router complex called ACIO (Apple Converged I/O). It contains a + Cortex-M3 co-processor, the hardware blocks implementing the USB4 router + and its PCIe, USB3 and DisplayPort adapters. + + The co-processor exposes the Native Host Interface (NHI) and its DART IO= MMU + to the main SoC bus once it is running. They are therefore represented as + child nodes. All child registers are located in a single 16 MiB MMIO win= dow + and use addresses relative to this window. + + ACIO can only be powered on after the Type-C PHY has been switched to + USB4/Thunderbolt mode. Before the connection to the remote device can be + established the Type-C PD controller has to publish the negotiated mode = and + cable information through the Type-C class. ACIO finds the corresponding + Type-C port through the OF graph connection. + +properties: + compatible: + oneOf: + - const: apple,t8103-usb4-acio + - items: + - enum: + - apple,t6000-usb4-acio + - apple,t6020-usb4-acio + - apple,t6030-usb4-acio + - apple,t6031-usb4-acio + - apple,t8112-usb4-acio + - apple,t8122-usb4-acio + - const: apple,t8103-usb4-acio + + reg: + items: + - description: Root complex and co-processor control registers + - description: SRAM used for communication with the co-processor + + reg-names: + items: + - const: rc + - const: sram + + mboxes: + maxItems: 1 + description: Mailbox used for RTKit communication with the co-processor + + resets: + maxItems: 1 + description: Reset used to start the ACIO block before booting the + co-processor + + power-domains: + maxItems: 3 + + apple,tunable-rc: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + items: + items: + - description: Register offset + - description: Mask of bits to clear + - description: Bits to set + description: | + List of (register offset, mask, value) tuples copied from Apple's De= vice + Tree, converted by the bootloader and used to configure the root com= plex + after the co-processor has booted. + + '#address-cells': + const: 1 + + '#size-cells': + const: 1 + + ranges: + maxItems: 1 + description: Single 16 MiB MMIO window containing all child registers + + nonposted-mmio: true + + ports: + $ref: /schemas/graph.yaml#/properties/ports + description: + OF graph ports for the USB4 router. The port numbers correspond to t= he + USB4 router adapter numbers. + properties: + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: Lane 0 adapter of the connector-facing USB4 port + + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: Lane 1 adapter of the connector-facing USB4 port + + port@3: + $ref: /schemas/graph.yaml#/properties/port + description: PCIe adapter + + port@4: + $ref: /schemas/graph.yaml#/properties/port + description: USB3 adapter + + port@5: + $ref: /schemas/graph.yaml#/properties/port + description: First DP IN adapter + + port@6: + $ref: /schemas/graph.yaml#/properties/port + description: Second DP IN adapter + + required: + - port@1 + + iommu@a80000: + $ref: /schemas/iommu/apple,dart.yaml# + description: DART IOMMU exposed by ACIO and used for DMA from the NHI + + nhi@f00000: + $ref: /schemas/thunderbolt/apple,t8103-usb4-nhi.yaml# + description: Native Host Interface exposed by ACIO + +required: + - compatible + - reg + - reg-names + - mboxes + - power-domains + - resets + - '#address-cells' + - '#size-cells' + - ranges + - nonposted-mmio + - ports + - iommu@a80000 + - nhi@f00000 + +additionalProperties: false + +examples: + - | + soc { + #address-cells =3D <2>; + #size-cells =3D <2>; + + cio@501ac0000 { + compatible =3D "apple,t8103-usb4-acio"; + reg =3D <0x5 0x01ac0000 0x0 0xc000>, + <0x5 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + ranges =3D <0x0 0x5 0x01000000 0x1000000>; + #address-cells =3D <1>; + mboxes =3D <&usb4_1_mbox>; + nonposted-mmio; + pinctrl-0 =3D <&acio1_pins>; + pinctrl-names =3D "default"; + power-domains =3D <&ps_atc1_cio>, + <&ps_atc1_cio_pcie>, + <&ps_atc1_cio_usb>; + resets =3D <&cio_reset 1>; + #size-cells =3D <1>; + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@1 { + reg =3D <1>; + + endpoint { + remote-endpoint =3D <&typec1_con_tbt>; + }; + }; + }; + + usb4_1_dart: iommu@a80000 { + compatible =3D "apple,t8103-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D <1 890 4>; + #iommu-cells =3D <1>; + }; + + nhi@f00000 { + compatible =3D "apple,t8103-usb4-nhi"; + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + interrupt-parent =3D <&aic>; + interrupts =3D <1 863 4>, <1 864 4>, <1 865 4>, <1 866 4>, + <1 867 4>, <1 868 4>, <1 869 4>, <1 870 4>, + <1 871 4>, <1 872 4>, <1 873 4>, <1 874 4>, + <1 875 4>, <1 876 4>, <1 877 4>, <1 878 4>, + <1 879 4>, <1 880 4>, <1 881 4>, <1 882 4>, + <1 883 4>, <1 884 4>, <1 885 4>, <1 886 4>; + interrupt-names =3D "txring0", "txring1", "txring2", "txri= ng3", + "txring4", "txring5", "txring6", "txring= 7", + "txring8", "txring9", "txring10", "txrin= g11", + "rxring0", "rxring1", "rxring2", "rxring= 3", + "rxring4", "rxring5", "rxring6", "rxring= 7", + "rxring8", "rxring9", "rxring10", "rxrin= g11"; + iommus =3D <&usb4_1_dart 1>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index a9d2e2a914c2..406cf664dedc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2659,6 +2659,7 @@ F: Documentation/devicetree/bindings/rtc/apple,smc-rt= c.yaml F: Documentation/devicetree/bindings/soc/apple/apple,t6000-pmgr-misc.yaml F: Documentation/devicetree/bindings/spi/apple,spi.yaml F: Documentation/devicetree/bindings/spmi/apple,spmi.yaml +F: Documentation/devicetree/bindings/thunderbolt/apple,t8103-usb4-acio.yaml F: Documentation/devicetree/bindings/thunderbolt/apple,t8103-usb4-nhi.yaml F: Documentation/devicetree/bindings/usb/apple,dwc3.yaml F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB7603C4169; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; cv=none; b=KEWjBes7TNozSiDY1MVTzhR+9N04QqLd+CoHCdkGHM+yml6se3U/T1x5zPls9ezID/OLm87KzXahxCfm3QbqvX9afzXD/PiETHaZGGqOAya0ovTNZySLrdDEXJgf57SG4iQ6VTS5fD1wEmyK/fwmxEVLyvbMquHnrkrEIzNl+oI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719827; c=relaxed/simple; bh=pwxcwyZ177lrb/kV9/qF46wwbZfRgBA0AoGXpy/5Mqg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ak42m+GgyqUbTQwA67qqH71tm6ZconI+Nmz3paGm5DMuwoAtQLZqRWn08r16GuRkseyNpS96Xsa4ZYKnUdjwg95BPRZOf5PIk65Hq9+bvHzN+3ZXCXzajqJc4/f7/DKu4dGNMm/CpIpX3QQzMY9oggaI8cMFPy3VQUg+GpYkjCk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=vPz1zIun; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="vPz1zIun" Received: by smtp.kernel.org (Postfix) with ESMTPS id A6642C2BD05; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=pwxcwyZ177lrb/kV9/qF46wwbZfRgBA0AoGXpy/5Mqg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=vPz1zIuntwS5hoVd71gGSkrJ/TMJ7gohuI/RjvZ/NOuaNjMrMb8cQbwVk2bzXdXjM k9wyvkxndcmvK8LWoIf1eEU5/MAGxIRBd6edAjoVyy5dvDaNdSbR0hNgnDtwCnu1hR Yat817X0DDeLAL99CWWkwEGw0rOPe7c8G7m6Nag9UadfedS4wlaxTxbZopqli1SmHj 4PvQwcpBfXIczrb0emksMCpfqorsrlO7J9/TkoFZJKGSyhKUJOno1ZAwz7CwCgvb1a A5pmTR40U3ZGg8qAwkMwsFj9H46OF2Ls7RBhLM6OPWJTse+QBSm27HraL+ZAJ7+1nc aMKxvjXCltStw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9220AC79FA0; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:30 +0200 Subject: [PATCH v2 07/22] thunderbolt: Try reading host DROM from device tree first 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-7-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter , Joshua Peisach X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2399; i=sven@kernel.org; h=from:subject:message-id; bh=pwxcwyZ177lrb/kV9/qF46wwbZfRgBA0AoGXpy/5Mqg=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTfsEHy9bOu34xDspJQwv9E6sfu8go97PKMb4vNNrk prqD73tHaUsDGJcDLJiiizb99ubPnn4RnDppkvvYeawMoEMYeDiFICJGO1iZLhulPaq3MLIdll0 +l3DtxduCCQv+5zw6W5LmNm5wt079GYwMpzL8D79P+ZXUKnwu61M4Tqsi/90XZypEuyia7daylR jCjcA X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 On Apple Silicon SoCs the DROM is provided by a device tree property. Try reading from that property first. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/eeprom.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c index 2a13fa6888ba..69d5c5f70eaf 100644 --- a/drivers/thunderbolt/eeprom.c +++ b/drivers/thunderbolt/eeprom.c @@ -468,14 +468,15 @@ static void tb_switch_drom_free(struct tb_switch *sw) } =20 /* - * tb_drom_copy_efi - copy drom supplied by EFI to sw->drom if present + * tb_drom_copy_property() - Copy DROM from a device property if present */ -static int tb_drom_copy_efi(struct tb_switch *sw, u16 *size) +static int tb_drom_copy_property(struct tb_switch *sw, const char *name, + u16 *size) { struct device *dev =3D sw->tb->nhi->dev; int len, res; =20 - len =3D device_property_count_u8(dev, "ThunderboltDROM"); + len =3D device_property_count_u8(dev, name); if (len < 0 || len < sizeof(struct tb_drom_header)) return -EINVAL; =20 @@ -483,8 +484,7 @@ static int tb_drom_copy_efi(struct tb_switch *sw, u16 *= size) if (res) return res; =20 - res =3D device_property_read_u8_array(dev, "ThunderboltDROM", sw->drom, - len); + res =3D device_property_read_u8_array(dev, name, sw->drom, len); if (res) goto err; =20 @@ -500,6 +500,16 @@ static int tb_drom_copy_efi(struct tb_switch *sw, u16 = *size) return -EINVAL; } =20 +static int tb_drom_copy_of_apple(struct tb_switch *sw, u16 *size) +{ + return tb_drom_copy_property(sw, "apple,thunderbolt-drom", size); +} + +static int tb_drom_copy_efi(struct tb_switch *sw, u16 *size) +{ + return tb_drom_copy_property(sw, "ThunderboltDROM", size); +} + static int tb_drom_copy_nvm(struct tb_switch *sw, u16 *size) { u16 drom_offset; @@ -675,6 +685,13 @@ static int tb_drom_host_read(struct tb_switch *sw) { u16 size; =20 + /* + * Apple Silicon machines always get their host DROM from the Device Tree, + * so make sure to try reading it first before any other method. + */ + if (!tb_drom_copy_of_apple(sw, &size)) + return tb_drom_parse(sw, size); + if (tb_switch_is_usb4(sw)) { usb4_switch_read_uid(sw, &sw->uid); if (!usb4_copy_drom(sw, &size)) --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E19E63CA48E; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=GP1OV7o86docP44uNdwCULEKwhKrvLWxZhMlqD3zxESUmVeXohf0Dwq0i6RUo2lZBtMaMzEx3KPZFydsc8OB8eGcVtIB/BYIXNX6+vLiKYFXWF/ZKDLAmCyLVm7jf4eZBB1vqImVU/Kws7IkvoTK7PXYsIoBj7zVIi4kkxzee+8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=nAvvsoDo0FnW497Le/eu1wxUngPW7Yw1+XhupbJs0xU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XKCoyLaOTqDcs9lVCwIfQWTu8nIUlCK3ZzROoXk+BUKL7HxNd5w8KrqApyJkTBDug8ACNOcD1hOJA/LI+kWbTDC0ejBWDFZruqrBfbSiUxJ4OFIlcPDVOjY2eA6IFthNgKw8gO14JeVsMurEsUD1SW9t+Xi5Qx7yfxJ5dYEjALc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ng91M1NW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ng91M1NW" Received: by smtp.kernel.org (Postfix) with ESMTPS id B4385C2BCFF; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=nAvvsoDo0FnW497Le/eu1wxUngPW7Yw1+XhupbJs0xU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Ng91M1NWr74/M+6TxNpdBaMm6WIRW4iPdEgAMHzkp8Vm4B6Pugj/LuI9FMeZQZOcn JLyhUG56klS+puycggm74hdhwcEHe62sT6G7DIULKGrLOCY7EyCcFY8VOlo0R+ATK0 VUrbZeDg/tzjzWUrAUcEW8gy2YgDUApTBJLySugf44hXEHvdv7fwKGOAFBhOop9Atl gtMjnpo1cGl5sEby2ctfLBtqjbs8WyeUrXkhaUP6JB70YKZuf/u8IlVZBrLvVWXohh AbbGWBKFIhyh18z3bbTi93wwJlNdRZ7vHRHGHIHKsrTYrEs8S8y+GQlUv+UlZJUKqe u0feJkOnt2RDg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1FAFC79F85; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:31 +0200 Subject: [PATCH v2 08/22] thunderbolt: Don't read the UID if we already know it 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-8-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter , Joshua Peisach X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1183; i=sven@kernel.org; h=from:subject:message-id; bh=nAvvsoDo0FnW497Le/eu1wxUngPW7Yw1+XhupbJs0xU=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTft1bIN3s71O0l644+DSY66WJwU0J+ZPd2KNX6Jp8 2rWPMMLHaUsDGJcDLJiiizb99ubPnn4RnDppkvvYeawMoEMYeDiFICJbJrDyPCP8cBJFrGu0xry bS2MqjJ5+b1LWh7XS5bY7Ol+1/NbUIuR4cFSFi6ZL3ExVSc9XOZEKQpxTJogVW5WPvXiadWgyyp yPAA= X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 On Apple Silicon the host router's UID comes from the DROM provided by the device tree and is already known by the time tb_switch_set_uuid() runs. Skip reading it from the config space again in that case. For other USB4 hosts this only drops a duplicate read because tb_drom_host_read() has already filled in the UID from ROUTER_CS_7 before tb_switch_set_uuid() runs. Device routers keep reading it unconditionally. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/switch.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 404c0693df50..3f54a5ae56b0 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -2692,9 +2692,11 @@ static int tb_switch_set_uuid(struct tb_switch *sw) return 0; =20 if (tb_switch_is_usb4(sw)) { - ret =3D usb4_switch_read_uid(sw, &sw->uid); - if (ret) - return ret; + if (tb_route(sw) || !sw->uid) { + ret =3D usb4_switch_read_uid(sw, &sw->uid); + if (ret) + return ret; + } uid =3D true; } else { /* --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F2C4D3CAA47; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=obgu/fNMRgQgd8dfaiQlnVuoWDvGCdtDH8nU7gldfnGM8iHEkT40uGnFdA84+54HKoG0ZZjh1GgsmpeVJLsViU5AXqFmAbGQUun5spE4TUsRYv+Y4U3nNVQ7klCjZ9obIkwYsHAjRMu2cZW1IzJe98fMJPjLpOuyRYQptpSKZK0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=pqtln2usNi6swABEnkmItz3rmeApDprpV00ba9Y2o4U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fvCBTzxd71jSUXzyiMkOrOiTfZBxxc3lNLELPIgRkxSxU6rSQGC5ebAFkV3IoqmpwU/rT48grYOO678QS2UdEcwSVV3nuXB7ZyJuhpEftGyvoXlBHl/W+kjShkh1CsIDYWwyMm7BG8ijJ2+7rXkX2clA3PIXKmN5QGzM2itMV3k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fOZMAjbI; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fOZMAjbI" Received: by smtp.kernel.org (Postfix) with ESMTPS id C5E4CC4AF10; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=pqtln2usNi6swABEnkmItz3rmeApDprpV00ba9Y2o4U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=fOZMAjbIX0884jjl+kMa1vf2JcyE437gyJ0WtLbS8E5+aQEP1PVQk5vEtLROy3lX9 UpvgcTC2hPmyG0Rjw1GqWyJPfcQYcr+d5UFCuX8J6KVigRim3MiHWvU06sCYCkw21u tIU+3wV/77x4ltaxFOC4FP9JGi8sukM6c7WfuoPvvgLSmQhSjEBzAE/En4yDLQaEbx 95Gv7f6xnP67PQv7wcAnEFLww5v2ZE1BTSiADFpm4leNrVzCAdhcfhvnzn9ePjxKzQ zo5JTNHb0ARS7YbTd+1PW16WeJJbLzFCRaUUFj0HXVlK5nsODv+kKhJFcNC8XRKbXu 8iftJN/X3hicw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B24F8C79FA3; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:32 +0200 Subject: [PATCH v2 09/22] thunderbolt: Allocate ring HopID before requesting the ring interrupt 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-9-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter , Joshua Peisach X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1903; i=sven@kernel.org; h=from:subject:message-id; bh=pqtln2usNi6swABEnkmItz3rmeApDprpV00ba9Y2o4U=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTfvfJHSebPS66FR+0uz22qYPSQqxzA955cyc3u/pM pbt8d/RUcrCIMbFICumyLJ9v73pk4dvBJduuvQeZg4rE8gQBi5OAZhIyX+G/zkGbVnfJaVSv516 XFy/6YkxV5+4zKuXZVKM3wNPTxX/Ks7I8H/PzPwJszvEb50wWnWj/8W+ws8VcjkLn61cv8941YS Ha1gA X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 The Apple NHI has one interrupt per ring and request_ring_irq picks it based on ring->hop which is still -1 at this point for rings allocated with an automatic HopID. Allocate the HopID first and release it again if the interrupt request fails. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/nhi.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index 5809809f64d4..6a97dcd57deb 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -534,6 +534,16 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb= _ring *ring) return ret; } =20 +static void nhi_free_hop(struct tb_nhi *nhi, struct tb_ring *ring) +{ + guard(spinlock_irq)(&nhi->lock); + + if (ring->is_tx) + nhi->tx_rings[ring->hop] =3D NULL; + else + nhi->rx_rings[ring->hop] =3D NULL; +} + static struct tb_ring *tb_ring_alloc(struct tb_nhi *nhi, u32 hop, int size, bool transmit, unsigned int flags, int e2e_tx_hop, u16 sof_mask, u16 eof_mask, @@ -581,19 +591,18 @@ static struct tb_ring *tb_ring_alloc(struct tb_nhi *n= hi, u32 hop, int size, if (!ring->descriptors) goto err_free_ring; =20 + if (nhi_alloc_hop(nhi, ring)) + goto err_free_descs; + if (!(flags & RING_FLAG_NO_INTERRUPT) && nhi->ops->request_ring_irq) { if (nhi->ops->request_ring_irq(ring, flags & RING_FLAG_NO_SUSPEND)) - goto err_free_descs; + goto err_free_hop; } =20 - if (nhi_alloc_hop(nhi, ring)) - goto err_release_msix; - return ring; =20 -err_release_msix: - if (nhi->ops->release_ring_irq) - nhi->ops->release_ring_irq(ring); +err_free_hop: + nhi_free_hop(nhi, ring); err_free_descs: dma_free_coherent(ring->nhi->dev, ring->size * sizeof(*ring->descriptors), --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 30D373CC324; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=uK65cXGDdqLU8OzW6h5fq4xVjfz0gwB62Z9yGNDAph7zMTg+IpdH112tmX8iNqsCfhUw7ePTUVbvR/jhfGLe2fngj36kYg/hVo2j+lU7KKJMw3OvHyFS9ODWf+H0hEF7zG7v0hVZrcb0PizCispa6wmRpk3EK7mAIJEPcTy8R/I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=pbpXxrcnBEcXBzVXZAWh/ik8j3e+Lr/BQd6kXeq0PEA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GXHlBdWJVuaxy60rhaRMb5snM981trSNo60sikFgPcnHoRYmYsNGR2/GIoyNWUS3/N+FxRZm3rIaIIEYnhneZ3H2iA08JC22o2qlGtOK6S/Va5RXkIAv7AamB8Q+SJ6jiNU6wUgTv4eIMl8zAHabdpI2mvxtkRHGNae4fJQ3nBM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hHHwSmrM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hHHwSmrM" Received: by smtp.kernel.org (Postfix) with ESMTPS id D0EB6C2BCF5; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=pbpXxrcnBEcXBzVXZAWh/ik8j3e+Lr/BQd6kXeq0PEA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hHHwSmrM5iuVVUdz8bmEDAsc+rWVBJ+wMZcRIwCS6RisOE+eRizQcHnx73Ye0egAu gpuxvrDRyLe4JsIFTPzPKgMBm9UUgAWC10FAc3dQDwVIsreP4fqwtDHezD3vXI/z5n /6nSsXPZfDEpPIReG87ynuutt0e9gn9cBXjEFzPCgg0vqrJvdnV/p16NbeOUu/AZ/6 7/axctQLHvOuTn82+4n8DdcdSou5SxW+SG40BYZuKaClOZ06fYxcIlvMuMY8/12QaD 8KmTC62qQORrlkaG31/DtHPnaL887D7uF1lDlwPbCHZO+bJS3JATiSjbLo8o1G2mU+ MdCUHZRkRKs2A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C148FC79F8C; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:33 +0200 Subject: [PATCH v2 10/22] thunderbolt: Unlock host router ports during startup 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-10-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1238; i=sven@kernel.org; h=from:subject:message-id; bh=pbpXxrcnBEcXBzVXZAWh/ik8j3e+Lr/BQd6kXeq0PEA=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTQcqm0T0zrw/crT/RDCT+NO8f4X/zl686divVHVsz 4tJ6T9udpSyMIhxMciKKbJs329v+uThG8Glmy69h5nDygQyhIGLUwAmomvD8E935ZVKXpM9flsv OPesj+3yetXlwyV4x+ai3NnZ9xJOvuph+MNfMDn6x/Wqljulkk7xP+vLfX62KFTtz/if3tjzN+V fGj8A X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 The downstream ports of the host router may still be locked after a reset. Unlock them when the software connection manager starts before scanning for any connected devices. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/tb.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 47753a5c0f2e..bf1c192ec10a 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -3016,6 +3016,7 @@ static int tb_scan_finalize_switch(struct device *dev= , void *data) static int tb_start(struct tb *tb, bool reset) { struct tb_cm *tcm =3D tb_priv(tb); + struct tb_port *port; bool discover =3D true; int ret; =20 @@ -3049,6 +3050,14 @@ static int tb_start(struct tb *tb, bool reset) return dev_err_probe(tb->nhi->dev, ret, "failed to add host router\n"); } =20 + /* Make all host router downstream ports accessible to the CM. */ + tb_switch_for_each_port(tb->root_switch, port) { + if (!tb_port_is_null(port)) + continue; + if (tb_port_unlock(port)) + tb_port_warn(port, "failed to unlock port\n"); + } + /* * To support highest CLx state, we set host router's TMU to * Normal mode. --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F55E3CB54D; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=ljE5eBEnFEIA240DQ03WAOUBjnybgXBswHCVJP3J58Dohlo2vpfYVMCPAGUFXOd4G6t1eUzzdb9CHRrtpJj/GRpmq41fy4oBFiAXlr2vXgTYpwFM7wbUSLSnE+RD5C9YV65MGHMnVvayVwtHl6BlKpz4oXGbrQivHov4+BheQZ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=hWtjtaprJYt4jyipWU9LokTTRoke60o6AWtWpZvW760=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UH/mCuPzhNKuJg6Eu08k8PUKHqwzvC5wuqNjDUCe5gafm87z7IeOWWm23iU5txoWTh9f88nWl8pjWKz+v61GeQBlbQ7Yjunduj07dVATq8P9QkeqOtQkVigwodaCBZfduUcMNfX1eGjdKkMnBXVjS8b/tWNy9Uth5iIgHM/cXrw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kCzez3hX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kCzez3hX" Received: by smtp.kernel.org (Postfix) with ESMTPS id E46B7C2BD01; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719827; bh=hWtjtaprJYt4jyipWU9LokTTRoke60o6AWtWpZvW760=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kCzez3hXHuRyj1+c76Sj44WAE82H1MVfNByAsJcjp72GvNkzdvGVquMWQ4IaSXgst OEg8eup7irnx4UBIudD33y2L/9pblkRO/1JhNXEBwmFT8QHvQeG4nHHqs/vjOXrd6n 5WqcX7jZLM6ToSjW0HS3x+j9Q8dHowN6CBW0DlLh5PsZIi6nHHZwZjII7MQOq5zOc7 uo3wpHRgqlRDd9ItmtEn3GZ/BWwbNBhmMBzXwnQ1QlRgCsWjbYIQokTLK0K/0sF901 0BvgB29MfIxvol8AgOECQyXQ/N99BcB2NsjPzh3xRQfgZ8/e22/r762io8H3gwxa+v MNp5Knq+k35rA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1F22C79F85; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:34 +0200 Subject: [PATCH v2 11/22] thunderbolt: Find Apple VSE capability during startup 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-11-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2467; i=sven@kernel.org; h=from:subject:message-id; bh=hWtjtaprJYt4jyipWU9LokTTRoke60o6AWtWpZvW760=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTQeP+QZZqqv3lf21S5op6nGjZtsUQ7d5LZFzQ2y3m bnmeLJ2lLIwiHExyIopsmzfb2/65OEbwaWbLr2HmcPKBDKEgYtTACbi+ZeRoWHKom2Moj7Mexm0 trcsX2nZ7Hpdq8WHU87p1d197PO1JBn+hzCoq79lrpKR3axyyW6+/2WPkmdMV47cMXUUML75Qjm NCQA= X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 Only Apple Silicon host routers have the Apple vendor-specific extended capability. Look it up when the software connection manager starts and store its offset in the root switch. The Apple NHI driver can then use the stored offset when programming cable information without searching the router capabilities itself. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/tb.c | 4 ++++ drivers/thunderbolt/tb.h | 2 ++ drivers/thunderbolt/tb_regs.h | 1 + 3 files changed, 7 insertions(+) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index bf1c192ec10a..d2832323cc36 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -3025,6 +3025,10 @@ static int tb_start(struct tb *tb, bool reset) return dev_err_probe(tb->nhi->dev, PTR_ERR(tb->root_switch), "failed to allocate host router\n"); =20 + ret =3D tb_switch_find_vse_cap(tb->root_switch, TB_VSE_CAP_APPLE); + if (ret > 0) + tb->root_switch->cap_vsec_apple =3D ret; + /* * ICM firmware upgrade needs running firmware and in native * mode that is not available so disable firmware upgrade of the diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 4373336d9425..fbd1a0a9927a 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -132,6 +132,7 @@ struct tb_switch_tmu { * @link_usb4: Upstream link is USB4 * @generation: Switch Thunderbolt generation * @cap_plug_events: Offset to the plug events capability (%0 if not found) + * @cap_vsec_apple: Offset to the Apple vendor specific capability (%0 if = not found) * @cap_vsec_tmu: Offset to the TMU vendor specific capability (%0 if not = found) * @cap_lc: Offset to the link controller capability (%0 if not found) * @cap_lp: Offset to the low power (CLx for TBT) capability (%0 if not fo= und) @@ -187,6 +188,7 @@ struct tb_switch { bool link_usb4; unsigned int generation; int cap_plug_events; + int cap_vsec_apple; int cap_vsec_tmu; int cap_lc; int cap_lp; diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h index 92d893634d2b..a37e55fec157 100644 --- a/drivers/thunderbolt/tb_regs.h +++ b/drivers/thunderbolt/tb_regs.h @@ -31,6 +31,7 @@ enum tb_switch_cap { }; =20 enum tb_switch_vse_cap { + TB_VSE_CAP_APPLE =3D 0x00, TB_VSE_CAP_PLUG_EVENTS =3D 0x01, /* also EEPROM */ TB_VSE_CAP_TIME2 =3D 0x03, TB_VSE_CAP_CP_LP =3D 0x04, --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33D253CC327; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=S1Ma/tP34NiNIP0giv7mCEneqTol+lwgdBl1mQ5p0V78L+XgPGGKvFGw9p508b7/HFLBF53zA4iWOzslXT651c8ByobNuWTEcW6zYYeWKdS8ejXCyl21X2p9hIezm2J/FBUjf6NoGP7zysRDsS1IpWdhcx07ANJkEDQZVrEU9hM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=JhMORvwjpL+vSOXSZRgQ34FsUDioPUDXHqRnLjyFxTw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VtDlHlRtMA2qMUpOLT3vL63F3d1TxhmqZlT9ZlIao+MguUjH2NLXHStL7XEtNn9lne88YsldOF9W+xj3ZB/VnrW0YbnpSzzTXiDUoqSbgJzDTOUBDFSJr6Azk3vU8uYBMqIjeeaOLBKWBKGsIhtQU1vfaaPNsoOeMlqh0FxZIBA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kJLhjAbN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kJLhjAbN" Received: by smtp.kernel.org (Postfix) with ESMTPS id 0911EC4AF12; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=JhMORvwjpL+vSOXSZRgQ34FsUDioPUDXHqRnLjyFxTw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kJLhjAbN/lnM+vW/3yBm2RV0TQrIrWFYS3Ky61E7RBYMCQKuBKbH+9dIXoKzkQ3tV 0Krbvw84Xk+ursQiufPbX0JY+YkcMbX90oooSQRGOJ6FmZyfEQUbMiIDNkRLRIyHz4 gqmWGDIHndsRjA04xwY+SsVuXZaOuQKDQf1qa2v7aIFiLvQOdi95iJ+pl/52dj1Y1M 1JRad26ejpYWP/xuQ6qxZu44Jmm2ojB+I1Gj74WUzUtC3nOSfDKB8iybuEXxnXgQQO 9tXYISd+Jfa+82/uL2DhmJuaKKK6/wtpwuXBYPHODKMpIIGQOjGwphy97iDcOnKpWA W0pcFOp2jvvFQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E37E3C79FA0; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:35 +0200 Subject: [PATCH v2 12/22] thunderbolt: Add ring_interrupt_active to tb_nhi_ops 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-12-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter , Joshua Peisach X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2844; i=sven@kernel.org; h=from:subject:message-id; bh=JhMORvwjpL+vSOXSZRgQ34FsUDioPUDXHqRnLjyFxTw=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTYc6Di2y31B1ZZp04ac3vlqF31cFbWjLvyTSuHTNR K+Q0MX7O0pZGMS4GGTFFFm277c3ffLwjeDSTZfew8xhZQIZwsDFKQATiXnP8N/tw420F0kTZkwz lN60Q1c4PUqiMHxZd5H/pf0LFZeLJ/YyMnxbcCzvxK4Fr8zj1Bf9Mrvz0iNIor9vaWNt78YfL56 98eIAAA== X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 The Apple NHI enables and disables ring interrupts differently. Add an optional tb_nhi_ops hook to override ring_interrupt_active which falls back to the standard USB4 method when it is not set. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/nhi.c | 12 ++++++++++-- drivers/thunderbolt/nhi.h | 4 ++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index 6a97dcd57deb..fc54ff7edfb9 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -149,6 +149,14 @@ static void ring_interrupt_active(struct tb_ring *ring= , bool active) nhi_mask_interrupt(ring->nhi, mask, index); } =20 +static void nhi_ring_interrupt_active(struct tb_ring *ring, bool active) +{ + if (ring->nhi->ops->ring_interrupt_active) + ring->nhi->ops->ring_interrupt_active(ring, active); + else + ring_interrupt_active(ring, active); +} + /* * nhi_disable_interrupts() - disable interrupts for all rings * @@ -724,7 +732,7 @@ void tb_ring_start(struct tb_ring *ring) } =20 if (!(ring->flags & RING_FLAG_NO_INTERRUPT)) - ring_interrupt_active(ring, true); + nhi_ring_interrupt_active(ring, true); ring->running =3D true; err: spin_unlock(&ring->lock); @@ -785,7 +793,7 @@ void tb_ring_stop(struct tb_ring *ring) goto err; } if (!(ring->flags & RING_FLAG_NO_INTERRUPT)) - ring_interrupt_active(ring, false); + nhi_ring_interrupt_active(ring, false); =20 ring_iowrite32options(ring, 0, 0); ring_iowrite64desc(ring, 0, 0); diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h index f72d6b274501..4884c3f5a2b2 100644 --- a/drivers/thunderbolt/nhi.h +++ b/drivers/thunderbolt/nhi.h @@ -52,6 +52,9 @@ extern const struct dev_pm_ops nhi_pm_ops; * @post_nvm_auth: hook to run after Thunderbolt 3 NVM authentication * @request_ring_irq: NHI specific interrupt retrieval hook * @release_ring_irq: NHI specific interrupt release hook + * @ring_interrupt_active: NHI specific hook to activate/deactivate the + * interrupt of a single ring. If not set the + * standard USB4 NHI registers are used. * @is_present: Whether the device is currently present on the parent bus * @init_interrupts: NHI specific interrupt initialization hook * @reset_interface: Resets the host interface @@ -67,6 +70,7 @@ struct tb_nhi_ops { void (*post_nvm_auth)(struct tb_nhi *nhi); int (*request_ring_irq)(struct tb_ring *ring, bool no_suspend); void (*release_ring_irq)(struct tb_ring *ring); + void (*ring_interrupt_active)(struct tb_ring *ring, bool active); bool (*is_present)(struct tb_nhi *nhi); int (*init_interrupts)(struct tb_nhi *nhi); void (*reset_interface)(struct tb_nhi *nhi); --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 341BA3CC7EB; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=Tzka8XHQ+mgCfY9+DBOqCSQbpMdI+7lvab7M0GcN15Y4s8wxOEhtvUVc4h5b1JoT+1HYKt2w3t8zq7NYJUaJZmlDp+ozCXJVUS/cirgtWjRafmOXUMiXNq2MXFRoar2OfBUHQsW8RdlneW4KbR4oCYgUSXOOkG5JGTr61/TlXsI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=XzwUrv8QkEnw2nIL7r4TaOTvzfuNbqBbIbkln6OG5pQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ABEYWvtt6c3AD0Z73HN1FkTLIVxET1GNWHPSLVsBPPuhwlA8tnIf7JS5cCETYD5nAb07G24a172ntnGd8qAVWhsvNoJNm0bl131DDk922JOoe8xfZlX1gc3140CiqdnDLtMXtWEZ3mIdcM4c9f9wYQMPOavYH5rasvHK+yOTJkA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ba5kwVu7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ba5kwVu7" Received: by smtp.kernel.org (Postfix) with ESMTPS id 133B1C32781; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=XzwUrv8QkEnw2nIL7r4TaOTvzfuNbqBbIbkln6OG5pQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Ba5kwVu7y6VLFD41n4xRuj2Ao5acq5FgjSpwQorMztwD262l+nPYoz26/N4DYoIvQ blK87Fv30k8Cg++FWTjyGxGkL7DpHJi+zu0PUdwf+lHsgvPeioqRB0cDxhdHIKhJ7n 8r8w7mSYcKqiKMAmiWQvVVgsIROw2m3k3zKxffiI3q/ro2nO05SoSza3at1k+XyJ17 +NDV1/M9i2Ynj0xC4fs6SggzXoZ4BabrCFEv//8pA35UO2UhqWvzy2denbgMMp5W+d JDL4CAPzuBLuh/yvv5usOJd9qHyiGS7RqHKJ/Iwk5Tf2DX6InUuiUHZkXz2VwC3kxE /Q8vqBaRq6O1A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F38EAC79FA1; Sun, 6 Sep 2026 18:37:07 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:36 +0200 Subject: [PATCH v2 13/22] thunderbolt: Add ring register accessors to tb_nhi_ops 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-13-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4323; i=sven@kernel.org; h=from:subject:message-id; bh=XzwUrv8QkEnw2nIL7r4TaOTvzfuNbqBbIbkln6OG5pQ=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTYd2HZoox/5JV2THtMBpEr6T8lP8Mnomd0yekCSfq N3zRvlLRykLgxgXg6yYIsv2/famTx6+EVy66dJ7mDmsTCBDGLg4BWAis5QZ/vAcYFXJZkl7WrKA Vclct8A7QFf88n43mw87OnY/mVnNcIHhf6RvsKon99cp3jPkjt+J2sIj9Xjx6bTMaz8mpHkfOHL iLhcA X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 The ring descriptor and options registers are laid out differently on the Apple NHI. Add optional tb_nhi_ops hooks for their base addresses which fall back to the standard USB4 register layout when they are not set. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/nhi.c | 32 ++++++++++++++++++++++++++------ drivers/thunderbolt/nhi.h | 6 ++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index fc54ff7edfb9..1b1e4a12c744 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -179,19 +179,37 @@ void nhi_disable_interrupts(struct tb_nhi *nhi) static void __iomem *ring_desc_base(struct tb_ring *ring) { void __iomem *io =3D ring->nhi->iobase; + io +=3D ring->is_tx ? REG_TX_RING_BASE : REG_RX_RING_BASE; io +=3D ring->hop * 16; return io; } =20 +static void __iomem *nhi_ring_desc_base(struct tb_ring *ring) +{ + if (ring->nhi->ops->ring_desc_base) + return ring->nhi->ops->ring_desc_base(ring); + + return ring_desc_base(ring); +} + static void __iomem *ring_options_base(struct tb_ring *ring) { void __iomem *io =3D ring->nhi->iobase; + io +=3D ring->is_tx ? REG_TX_OPTIONS_BASE : REG_RX_OPTIONS_BASE; io +=3D ring->hop * 32; return io; } =20 +static void __iomem *nhi_ring_options_base(struct tb_ring *ring) +{ + if (ring->nhi->ops->ring_options_base) + return ring->nhi->ops->ring_options_base(ring); + + return ring_options_base(ring); +} + static void ring_iowrite_cons(struct tb_ring *ring, u16 cons) { /* @@ -199,29 +217,31 @@ static void ring_iowrite_cons(struct tb_ring *ring, u= 16 cons) * are ignored by the hardware so we can save one ioread32() by * filling the read-only bits with zeroes. */ - iowrite32(cons, ring_desc_base(ring) + 8); + iowrite32(cons, nhi_ring_desc_base(ring) + 8); } =20 static void ring_iowrite_prod(struct tb_ring *ring, u16 prod) { /* See ring_iowrite_cons() above for explanation */ - iowrite32(prod << 16, ring_desc_base(ring) + 8); + iowrite32(prod << 16, nhi_ring_desc_base(ring) + 8); } =20 static void ring_iowrite32desc(struct tb_ring *ring, u32 value, u32 offset) { - iowrite32(value, ring_desc_base(ring) + offset); + iowrite32(value, nhi_ring_desc_base(ring) + offset); } =20 static void ring_iowrite64desc(struct tb_ring *ring, u64 value, u32 offset) { - iowrite32(value, ring_desc_base(ring) + offset); - iowrite32(value >> 32, ring_desc_base(ring) + offset + 4); + void __iomem *base =3D nhi_ring_desc_base(ring); + + iowrite32(value, base + offset); + iowrite32(value >> 32, base + offset + 4); } =20 static void ring_iowrite32options(struct tb_ring *ring, u32 value, u32 off= set) { - iowrite32(value, ring_options_base(ring) + offset); + iowrite32(value, nhi_ring_options_base(ring) + offset); } =20 static bool ring_full(struct tb_ring *ring) diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h index 4884c3f5a2b2..3a963b0b5b46 100644 --- a/drivers/thunderbolt/nhi.h +++ b/drivers/thunderbolt/nhi.h @@ -52,6 +52,10 @@ extern const struct dev_pm_ops nhi_pm_ops; * @post_nvm_auth: hook to run after Thunderbolt 3 NVM authentication * @request_ring_irq: NHI specific interrupt retrieval hook * @release_ring_irq: NHI specific interrupt release hook + * @ring_desc_base: NHI specific hook returning the ring descriptor regist= ers. + * If not set the standard USB4 NHI registers are used. + * @ring_options_base: NHI specific hook returning the ring option registe= rs. + * If not set the standard USB4 NHI registers are used. * @ring_interrupt_active: NHI specific hook to activate/deactivate the * interrupt of a single ring. If not set the * standard USB4 NHI registers are used. @@ -70,6 +74,8 @@ struct tb_nhi_ops { void (*post_nvm_auth)(struct tb_nhi *nhi); int (*request_ring_irq)(struct tb_ring *ring, bool no_suspend); void (*release_ring_irq)(struct tb_ring *ring); + void __iomem *(*ring_desc_base)(struct tb_ring *ring); + void __iomem *(*ring_options_base)(struct tb_ring *ring); void (*ring_interrupt_active)(struct tb_ring *ring, bool active); bool (*is_present)(struct tb_nhi *nhi); int (*init_interrupts)(struct tb_nhi *nhi); --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 48D823CEB8D; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=eu9QKgVNKJadnSkmjSHCKmW9WLFAU8ZTNy1GvZp4/ogPo9d1i6mLDixcOh5KP2NWDOlmjNQWCpUblGagKwc4WZyIGTRWwgZGDweFfxMBA6MFg96HwHj+P7BGQC+jjyPffjnRw1H4jnVPirMUePW3lrKqOK8zo4V7go8PQ0VBaYs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=HJ+d/OZeUWUlC39b4Bp/Qj2ekR0RdTWk6ov7g7kvJNs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=a3bdAzPKwTn5TtqDfusAV0t/T46GerojOqNgL9kNShh6xbA9724aSsSty9Gz0PkpjwzxyYzhxrIldyZypSVT2Ooxtn4xQor2riI7pKGPk02nfpQIUUEJO4vAAWmr/BMg3mSPhlLBusLdNOKevlMi4gCWjMeBtxUMwjgKSmpTsTY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cIXU3rHZ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cIXU3rHZ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 234F5C2BD00; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=HJ+d/OZeUWUlC39b4Bp/Qj2ekR0RdTWk6ov7g7kvJNs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cIXU3rHZp2xx7rD79RNZNBPC5BNwRYpKev1jnGOuylEsbV7Wrg3KlANao+VAWHR56 MB+oHhWDvO5B+7Zpu4xiHPX/SCUQdq+Zsxef5+PGpMrafTQJR1qjYbW2b8PDtlkUHA akreFeag6ykUHW6XD8UtzmTTgdCR8VWQuVJFtTnr799vDgmcqLReC/OR77xmgLtb62 aOhT1lWozBAcPZ3c2DwotcvUWzJeVfveg3H59mwdrXY04FPl3pr0eo3sBhQs0d9VW5 qif4d4FRkUAgNY2iGPAtmwqRgW9H80DmT59P/s9BQCV1F/UlVG7TIr0HlIe22P7GSt oLLnXoVZVMj1A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0EC01C79F8C; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:37 +0200 Subject: [PATCH v2 14/22] thunderbolt: Add ring_interrupt_mask to tb_nhi_ops 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-14-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter , Joshua Peisach X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2895; i=sven@kernel.org; h=from:subject:message-id; bh=HJ+d/OZeUWUlC39b4Bp/Qj2ekR0RdTWk6ov7g7kvJNs=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTYc7mz+onjuQkXho1qyMPy25X0QY17553XrW4NOmW 70CO84v6ChlYRDjYpAVU2TZvt/e9MnDN4JLN116DzOHlQlkCAMXpwBMRKSBkaH7/IFlj6xPnTkq 9pwn18Lc5k7o5uW+35YfzHt9btpbwbClDP+rI3I2f2J+0noriu2N1umZYt0911bwxjzx01GJ/eV 6RpcHAA== X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 Masking ring interrupts works differently on the Apple NHI as well. Add an optional tb_nhi_ops hook for it which falls back to the standard USB4 NHI method when it is not set. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/nhi.c | 12 ++++++++++-- drivers/thunderbolt/nhi.h | 4 ++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index 1b1e4a12c744..4ef86e7c0285 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -427,6 +427,14 @@ static void __ring_interrupt_mask(struct tb_ring *ring= , bool mask) iowrite32(val, ring->nhi->iobase + reg); } =20 +static void nhi_ring_interrupt_mask(struct tb_ring *ring, bool mask) +{ + if (ring->nhi->ops->ring_interrupt_mask) + ring->nhi->ops->ring_interrupt_mask(ring, mask); + else + __ring_interrupt_mask(ring, mask); +} + /* Both @nhi->lock and @ring->lock should be held */ static void __ring_interrupt(struct tb_ring *ring) { @@ -434,7 +442,7 @@ static void __ring_interrupt(struct tb_ring *ring) return; =20 if (ring->start_poll) { - __ring_interrupt_mask(ring, true); + nhi_ring_interrupt_mask(ring, true); ring->start_poll(ring->poll_data); } else { schedule_work(&ring->work); @@ -455,7 +463,7 @@ void tb_ring_poll_complete(struct tb_ring *ring) spin_lock_irqsave(&ring->nhi->lock, flags); spin_lock(&ring->lock); if (ring->start_poll) - __ring_interrupt_mask(ring, false); + nhi_ring_interrupt_mask(ring, false); spin_unlock(&ring->lock); spin_unlock_irqrestore(&ring->nhi->lock, flags); } diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h index 3a963b0b5b46..ca3eddf862e0 100644 --- a/drivers/thunderbolt/nhi.h +++ b/drivers/thunderbolt/nhi.h @@ -59,6 +59,9 @@ extern const struct dev_pm_ops nhi_pm_ops; * @ring_interrupt_active: NHI specific hook to activate/deactivate the * interrupt of a single ring. If not set the * standard USB4 NHI registers are used. + * @ring_interrupt_mask: NHI specific hook to mask/unmask the interrupt of= a + * single ring. If not set the standard USB4 NHI + * registers are used. * @is_present: Whether the device is currently present on the parent bus * @init_interrupts: NHI specific interrupt initialization hook * @reset_interface: Resets the host interface @@ -77,6 +80,7 @@ struct tb_nhi_ops { void __iomem *(*ring_desc_base)(struct tb_ring *ring); void __iomem *(*ring_options_base)(struct tb_ring *ring); void (*ring_interrupt_active)(struct tb_ring *ring, bool active); + void (*ring_interrupt_mask)(struct tb_ring *ring, bool mask); bool (*is_present)(struct tb_nhi *nhi); int (*init_interrupts)(struct tb_nhi *nhi); void (*reset_interface)(struct tb_nhi *nhi); --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5AE9A3CF1F4; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=bNPWSb7uZCx6CHb/LiO0WNDlIhDOCXpVVat/thRO2RG04KfHOVGuZPqWYdGgL+/kGCJZwQssYj+jsDuQGSeR3f6Xkc6U9J7k8QlZRdGN1j+Xez8gVNt9P1AIiMDfY4krps/Y+cBnwoWTYlHpnNqr8A3JJ1M/d99y66idSKXyhCM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=WVMy1qg0prw15BOC/1aO59pKjAwSsJirT8ivotx4wRA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I02yT3NaGjffDXg87nw2x52r0loUqpuuwExl7m10rXRvQyE6lLeaN4/pBdSUO2Crzyf7iu/qo3LKBVQCBrtmeq6RcDsaSn8GKG7ZAir2Cn6Th9w4VCoan5UlOmxZxnyYVIp3Wz7NdgTqYKkPHYmaP+Hz32DuvN/OjWu9DB9uwdw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mwkuQW73; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mwkuQW73" Received: by smtp.kernel.org (Postfix) with ESMTPS id 30F7DC2BCFD; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=WVMy1qg0prw15BOC/1aO59pKjAwSsJirT8ivotx4wRA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mwkuQW73Fy8sG3hVWSMxPGoAB18W7BBGfwpG/GRL+AXkQxVUeHYKEvGScNZs/91qT Pp+N9ul8f0GF7lf+pthV2UmHLzR4UfFLGVaZXi/9uAsM1V5GQQHsdlkteJxHDU2Xmx lMVtmSH/JnhuSSA5jM4VD4p5SGL/OmyOmtGeqXLSJRUKMUWV9Nt3M0/dQkbEbvhqWY d8HHhtDih3W5NiN5NH9YpD8S2NnPDT/Y954oWv4n/saqPJ44jXBhensaMiW6qULDdU gCK2oJiK9EXXxqmgH3q0j2coQRlTyhoWCr8GIvFimNJcFoS1zeCE8qWphK+rAh3jDu O9Ht2JKFw4uzw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E747C79F85; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:38 +0200 Subject: [PATCH v2 15/22] thunderbolt: Add ring_configure to tb_nhi_ops 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-15-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4518; i=sven@kernel.org; h=from:subject:message-id; bh=WVMy1qg0prw15BOC/1aO59pKjAwSsJirT8ivotx4wRA=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTUel/SJz/2/Un5uyeW9eiMTBq65LT0XWhi1IT3r2t GLf3CbZjlIWBjEuBlkxRZbt++1Nnzx8I7h006X3MHNYmUCGMHBxCsBEtk1l+Ct+wfOL91PHi7H+ Zp9rZM/+a/WqbTqTtink5/MfFWx5eiUM/3Rjo2bNNFP4dvP0m6jyAq6sKstc5hNvGZWWHtSWTU1 p4gEA X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 The Apple NHI also uses a separate register range for the receive ring PDF masks. Add an optional tb_nhi_ops hook for it which falls back to the standard USB4 NHI method when it is not set. For the standard method also just write E2E flow control at the same time the rest of the configuration is written. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/nhi.c | 48 +++++++++++++++++++++++++++----------------= ---- drivers/thunderbolt/nhi.h | 4 ++++ 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index 4ef86e7c0285..2d622b365c4f 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -244,6 +244,24 @@ static void ring_iowrite32options(struct tb_ring *ring= , u32 value, u32 offset) iowrite32(value, nhi_ring_options_base(ring) + offset); } =20 +static void ring_configure(struct tb_ring *ring, u32 flags, u32 e2e_flags) +{ + if (ring->is_tx) + ring_iowrite32options(ring, 0, 4); + else + ring_iowrite32options(ring, ring->sof_mask << 16 | ring->eof_mask, 4); + + ring_iowrite32options(ring, flags | e2e_flags, 0); +} + +static void nhi_ring_configure(struct tb_ring *ring, u32 flags, u32 e2e_fl= ags) +{ + if (ring->nhi->ops->ring_configure) + ring->nhi->ops->ring_configure(ring, flags, e2e_flags); + else + ring_configure(ring, flags, e2e_flags); +} + static bool ring_full(struct tb_ring *ring) { return ((ring->head + 1) % ring->size) =3D=3D ring->tail; @@ -699,6 +717,7 @@ EXPORT_SYMBOL_GPL(tb_ring_alloc_rx); */ void tb_ring_start(struct tb_ring *ring) { + u32 e2e_flags =3D 0; u16 frame_size; u32 flags; =20 @@ -722,30 +741,13 @@ void tb_ring_start(struct tb_ring *ring) flags =3D RING_FLAG_ENABLE | RING_FLAG_RAW; } =20 - ring_iowrite64desc(ring, ring->descriptors_dma, 0); - if (ring->is_tx) { - ring_iowrite32desc(ring, ring->size, 12); - ring_iowrite32options(ring, 0, 4); - ring_iowrite32options(ring, flags, 0); - } else { - u32 sof_eof_mask =3D ring->sof_mask << 16 | ring->eof_mask; - - ring_iowrite32desc(ring, (frame_size << 16) | ring->size, 12); - ring_iowrite32options(ring, sof_eof_mask, 4); - ring_iowrite32options(ring, flags, 0); - } - - /* - * Now that the ring valid bit is set we can configure E2E if - * enabled for the ring. - */ if (ring->flags & RING_FLAG_E2E) { if (!ring->is_tx) { u32 hop; =20 hop =3D ring->e2e_tx_hop << REG_RX_OPTIONS_E2E_HOP_SHIFT; hop &=3D REG_RX_OPTIONS_E2E_HOP_MASK; - flags |=3D hop; + e2e_flags |=3D hop; =20 dev_dbg(ring->nhi->dev, "enabling E2E for %s %d with TX HopID %d\n", @@ -755,10 +757,16 @@ void tb_ring_start(struct tb_ring *ring) RING_TYPE(ring), ring->hop); } =20 - flags |=3D RING_FLAG_E2E_FLOW_CONTROL; - ring_iowrite32options(ring, flags, 0); + e2e_flags |=3D RING_FLAG_E2E_FLOW_CONTROL; } =20 + ring_iowrite64desc(ring, ring->descriptors_dma, 0); + if (ring->is_tx) + ring_iowrite32desc(ring, ring->size, 12); + else + ring_iowrite32desc(ring, (frame_size << 16) | ring->size, 12); + nhi_ring_configure(ring, flags, e2e_flags); + if (!(ring->flags & RING_FLAG_NO_INTERRUPT)) nhi_ring_interrupt_active(ring, true); ring->running =3D true; diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h index ca3eddf862e0..e4964772a442 100644 --- a/drivers/thunderbolt/nhi.h +++ b/drivers/thunderbolt/nhi.h @@ -62,6 +62,9 @@ extern const struct dev_pm_ops nhi_pm_ops; * @ring_interrupt_mask: NHI specific hook to mask/unmask the interrupt of= a * single ring. If not set the standard USB4 NHI * registers are used. + * @ring_configure: NHI specific hook to program the ring options registers + * and enable the ring with the given flags. If not set + * the standard USB4 NHI registers are used. * @is_present: Whether the device is currently present on the parent bus * @init_interrupts: NHI specific interrupt initialization hook * @reset_interface: Resets the host interface @@ -81,6 +84,7 @@ struct tb_nhi_ops { void __iomem *(*ring_options_base)(struct tb_ring *ring); void (*ring_interrupt_active)(struct tb_ring *ring, bool active); void (*ring_interrupt_mask)(struct tb_ring *ring, bool mask); + void (*ring_configure)(struct tb_ring *ring, u32 flags, u32 e2e_flags); bool (*is_present)(struct tb_nhi *nhi); int (*init_interrupts)(struct tb_nhi *nhi); void (*reset_interface)(struct tb_nhi *nhi); --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 625933CF692; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=R4x+D/KDSfuZyS9dCPwFYGROweV1wvyVhUHLxgHfcgAaLG/Kd8xLJhG66AovxKhLrAHrfYgpoUKLNwyh+ph3phJnt24qDwtUkQ8gROVFzMVdG9w8TggGyxlqJb58Ga/U58TIH7zBQIauaBYckK8sENXK0V82Iif7X+Se7LNz+gI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=MLS3CfP65BeB4Vq9q2p9dx2GX03Sfxej/VHdxZD2j/I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kw1b53vEbNg7MaaoKDD4Ei3S57vQ4QPaeqegJ7XYexc0TCudvsw+/IMYJ+q6YIBGlPtlm1wfnddY+4QVt2HTrMapTcqL1G3YshCstjm2k989frcjfkuVn+o0H26Zz8O8q37KzxXbYkn0KzAnkr54VcetGIYxsT8itfbRNVcEotM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J6vNQRCi; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="J6vNQRCi" Received: by smtp.kernel.org (Postfix) with ESMTPS id 4191AC32786; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=MLS3CfP65BeB4Vq9q2p9dx2GX03Sfxej/VHdxZD2j/I=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=J6vNQRCi4tAu2qEGei0gS4gjV9SWH0Vcp4i/a3mMDk2vhWv3iZfhiouZsaUbiXHyG 62cuxj3DB52NmoDclEm+38rSmL2mK4qwfNBLx69t/bhJXAuufb1GpSC6KOjgIuJLYg VYM8S9XonPmIRErX+GFfHtd2lRODP4zv2N7S3NDGrywgKsakeFXuDK3uY9Z3h9AsRB PuuXnKgBzs/ToXAlN3gEB1yD1NLS1I61g90b0Rfuccx1RXcNoy92cGJRQA5LS87OdU DBBZdHsGWfbZbJmVOUFoQ95/+WnNpL9Aj+cYpa5YptEoTU7C6kQLOvnPTM/42zXRQs VkaDIAJD66WOw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E18AC79FA0; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:39 +0200 Subject: [PATCH v2 16/22] thunderbolt: Add add_links to tb_nhi_ops 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-16-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2198; i=sven@kernel.org; h=from:subject:message-id; bh=MLS3CfP65BeB4Vq9q2p9dx2GX03Sfxej/VHdxZD2j/I=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTcc/3nvmPkvR/JWjyJT51wU68uZVnFh8h2/PoWzVJ Xstc68XdZSyMIhxMciKKbJs329v+uThG8Glmy69h5nDygQyhIGLUwAm8uAoI8Os91IrOx6zlunv rJFNPH3A8WDgpk/+SzhZc/y8P07+8+wUI8NisW2WK05ucRbLqpBbZ7ybIeVqV5byd+OYV8u/mUn WTWUAAA== X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 PCI NHI drivers discover device links through ACPI or PCI topology but platform drivers, like the Apple Silicon one, can use neither of those methods. Instead, add a callback so that platform drivers can discover and add these links through e.g. device tree connections. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/nhi.h | 2 ++ drivers/thunderbolt/tb.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h index e4964772a442..addb8bcb4849 100644 --- a/drivers/thunderbolt/nhi.h +++ b/drivers/thunderbolt/nhi.h @@ -65,6 +65,7 @@ extern const struct dev_pm_ops nhi_pm_ops; * @ring_configure: NHI specific hook to program the ring options registers * and enable the ring with the given flags. If not set * the standard USB4 NHI registers are used. + * @add_links: NHI specific hook to add device links to tunneled native po= rts * @is_present: Whether the device is currently present on the parent bus * @init_interrupts: NHI specific interrupt initialization hook * @reset_interface: Resets the host interface @@ -85,6 +86,7 @@ struct tb_nhi_ops { void (*ring_interrupt_active)(struct tb_ring *ring, bool active); void (*ring_interrupt_mask)(struct tb_ring *ring, bool mask); void (*ring_configure)(struct tb_ring *ring, u32 flags, u32 e2e_flags); + bool (*add_links)(struct tb_nhi *nhi); bool (*is_present)(struct tb_nhi *nhi); int (*init_interrupts)(struct tb_nhi *nhi); void (*reset_interface)(struct tb_nhi *nhi); diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index d2832323cc36..72418a07166e 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -3434,7 +3434,8 @@ struct tb *tb_probe(struct tb_nhi *nhi) * before the PCIe/USB stack is resumed so complain here if we * found them missing. */ - if (!tb_apple_add_links(nhi) && !tb_acpi_add_links(nhi)) + if (!(nhi->ops->add_links && nhi->ops->add_links(nhi)) && + !tb_apple_add_links(nhi) && !tb_acpi_add_links(nhi)) tb_warn(tb, "device links to tunneled native ports are missing!\n"); =20 return tb; --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C6C53D0905; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=OcTzez1VskF5ZWKU6+CNOy9jmkFFOcRz/+9m1d3bXWTvmFLgFAzKcdHOxslcE9IWkOmsK/fqaC6vgdL5CChz35+UItkdYKxTLtc0sM/tFSg0KtgqYydqwOvnWyOphINQfg5ojjPUQ9TQJlffjku8IzMlmF8m4LnY/ITWriylTdI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=fDGXcEDT3HqF7GbnuemiQmkxSZ1c6I8Yl9AH275YygI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZU6hXx6pMrQYRcxqG3GnoV+xwZ5BoyKK6KMHozqfonE1Fo+PIXP1swqQcPdZ3MKcS52uIkOmgXAEaWjHcTsbGGRvm41bOGOtpySGXqg8qGEVVK9zA3X5YQt7EjfucZ91gwSplklVFqdDqcbPIC3vWsBEEfCZyE5JdR2RD7XCHB8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NPWSSUl6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NPWSSUl6" Received: by smtp.kernel.org (Postfix) with ESMTPS id 4F83CC2BCFB; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=fDGXcEDT3HqF7GbnuemiQmkxSZ1c6I8Yl9AH275YygI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NPWSSUl63IvbiOxVy/1rr2KtoUGQ4IBzU6SEayuDmAopAZua4hXc+wOja6OMXtHqr jlWzJrTTE84ehhZD8eGqW6Ia8pQbNy8Qlrfg6wd67DawuciCxF8kvKwcg5aXzrAzxh Cj+m4Rfb7VFJxQDUNsDw8Xf0upUo4+T9U4O0vh6N8xSKXtK3xgLjmy8jkgDC5RmR0n i1AWUz0pxF4trTPQwU3UFxDUqOlS7yU12+EBy7vC5JMebym/Zrz8KSrzaGtmx+3e+9 /8ldgAULkLCLumcbAqbK8z3SBYgoK3nx2KkYrqDnPUyYmxFyEkDvbnpi5civo/A3Ff SEytJfBU6ee2Q== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3DB8CC79FA3; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:40 +0200 Subject: [PATCH v2 17/22] thunderbolt: Add QUIRK_NO_USB3_BW_ALLOC 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-17-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5725; i=sven@kernel.org; h=from:subject:message-id; bh=fDGXcEDT3HqF7GbnuemiQmkxSZ1c6I8Yl9AH275YygI=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTSd6n359+r+wNKPT5rnF9h+s6ufjKyWNd51k8AxeN evYxzSPjlIWBjEuBlkxRZbt++1Nnzx8I7h006X3MHNYmUCGMHBxCsBEHv1n+F/0wOPYya1eL+Yt V/nH03jl63zesxHza0MsZ+57ZCIZ67mF4Q+H7uuzvVqnIw7ZmE3axb927nLJsBgjo5VeXP9btb8 ml7EDAA== X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 The host routers on Apple Silicon do not implement USB3 bandwidth allocation registers: the CMR bit set in ADP_USB3_CS_2 by usb4_usb3_port_cm_request() is never acknowledged and every USB3 tunnel bringup fails there after the timeout: [ 49.259325] thunderbolt-apple-nhi 501f00000.nhi: 1:16: available bandw= idth for new USB3 tunnel 18000/18000 Mb/s [ 49.265869] thunderbolt-apple-nhi 501f00000.nhi: 1:16: maximum require= d bandwidth for USB3 tunnel 9000 Mb/s [ 49.267894] thunderbolt-apple-nhi 501f00000.nhi: 0:4 <-> 1:16 (USB3): = activating [ 49.269410] thunderbolt-apple-nhi 501f00000.nhi: 0:4 <-> 1:16 (USB3): = allocating initial bandwidth 9000/9000 Mb/s [ 50.771764] thunderbolt-apple-nhi 501f00000.nhi: 1:16: USB3 tunnel act= ivation failed, aborting Add a quirk to skip bandwidth allocation entirely but keep tracking the initial allocation in software for the consumed bandwidth calculation. For completeness, discovered tunnels book 90% of the maximum link rate in software, matching tb_tunnel_alloc_usb3(), although Apple Silicon cannot have any pre-existing tunnels. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/quirks.c | 9 +++++++ drivers/thunderbolt/tb.h | 2 ++ drivers/thunderbolt/tunnel.c | 60 +++++++++++++++++++++++++++++-----------= ---- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/drivers/thunderbolt/quirks.c b/drivers/thunderbolt/quirks.c index 9f7914ac2f48..2ac1bfa01c15 100644 --- a/drivers/thunderbolt/quirks.c +++ b/drivers/thunderbolt/quirks.c @@ -46,6 +46,12 @@ static void quirk_usb3_maximum_bandwidth(struct tb_switc= h *sw) } } =20 +static void quirk_no_usb3_bw_alloc(struct tb_switch *sw) +{ + sw->quirks |=3D QUIRK_NO_USB3_BW_ALLOC; + tb_sw_dbg(sw, "disabling USB3 bandwidth allocation\n"); +} + static void quirk_block_rpm_in_redrive(struct tb_switch *sw) { sw->quirks |=3D QUIRK_KEEP_POWER_IN_DP_REDRIVE; @@ -61,6 +67,9 @@ struct tb_quirk { }; =20 static const struct tb_quirk tb_quirks[] =3D { + /* Apple Silicon host routers do not support USB3 bandwidth allocation */ + { 0x05ac, 0x2000, 0x0000, 0x0000, quirk_no_usb3_bw_alloc }, + /* Dell WD19TB supports self-authentication on unplug */ { 0x0000, 0x0000, 0x00d4, 0xb070, quirk_force_power_link }, { 0x0000, 0x0000, 0x00d4, 0xb071, quirk_force_power_link }, diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index fbd1a0a9927a..7c2fcf20e49f 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -26,6 +26,8 @@ #define QUIRK_NO_CLX BIT(1) /* Need to keep power on while USB4 port is in redrive mode */ #define QUIRK_KEEP_POWER_IN_DP_REDRIVE BIT(2) +/* Does not support USB3 bandwidth allocation */ +#define QUIRK_NO_USB3_BW_ALLOC BIT(3) =20 /** * struct tb_nvm - Structure holding NVM information diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index 7e8284575dff..0893ec19d606 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -2268,24 +2268,41 @@ struct tb_tunnel *tb_tunnel_discover_usb3(struct tb= *tb, struct tb_port *down, if (!tb_route(down->sw)) { int ret; =20 - /* - * Read the initial bandwidth allocation for the first - * hop tunnel. - */ - ret =3D usb4_usb3_port_allocated_bandwidth(down, - &tunnel->allocated_up, &tunnel->allocated_down); - if (ret) - goto err_deactivate; + tunnel->consumed_bandwidth =3D tb_usb3_consumed_bandwidth; + + if (down->sw->quirks & QUIRK_NO_USB3_BW_ALLOC) { + /* + * The host router does not implement the bandwidth + * allocation registers and nothing can be read back + * here. Book 90% of the maximum link rate in software + * instead. + */ + ret =3D tb_usb3_max_link_rate(tunnel->dst_port, down); + if (ret < 0) + goto err_deactivate; + + tunnel->allocated_up =3D ret * 90 / 100; + tunnel->allocated_down =3D tunnel->allocated_up; + } else { + /* + * Read the initial bandwidth allocation for the first + * hop tunnel. + */ + ret =3D usb4_usb3_port_allocated_bandwidth(down, + &tunnel->allocated_up, + &tunnel->allocated_down); + if (ret) + goto err_deactivate; + + tunnel->pre_activate =3D tb_usb3_pre_activate; + tunnel->release_unused_bandwidth =3D + tb_usb3_release_unused_bandwidth; + tunnel->reclaim_available_bandwidth =3D + tb_usb3_reclaim_available_bandwidth; + } =20 tb_tunnel_dbg(tunnel, "currently allocated bandwidth %d/%d Mb/s\n", tunnel->allocated_up, tunnel->allocated_down); - - tunnel->pre_activate =3D tb_usb3_pre_activate; - tunnel->consumed_bandwidth =3D tb_usb3_consumed_bandwidth; - tunnel->release_unused_bandwidth =3D - tb_usb3_release_unused_bandwidth; - tunnel->reclaim_available_bandwidth =3D - tb_usb3_reclaim_available_bandwidth; } =20 tb_tunnel_dbg(tunnel, "discovered\n"); @@ -2365,12 +2382,15 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *t= b, struct tb_port *up, tunnel->allocated_up =3D min(max_rate, max_up); tunnel->allocated_down =3D min(max_rate, max_down); =20 - tunnel->pre_activate =3D tb_usb3_pre_activate; tunnel->consumed_bandwidth =3D tb_usb3_consumed_bandwidth; - tunnel->release_unused_bandwidth =3D - tb_usb3_release_unused_bandwidth; - tunnel->reclaim_available_bandwidth =3D - tb_usb3_reclaim_available_bandwidth; + + if (!(down->sw->quirks & QUIRK_NO_USB3_BW_ALLOC)) { + tunnel->pre_activate =3D tb_usb3_pre_activate; + tunnel->release_unused_bandwidth =3D + tb_usb3_release_unused_bandwidth; + tunnel->reclaim_available_bandwidth =3D + tb_usb3_reclaim_available_bandwidth; + } } =20 return tunnel; --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 851343D0C1D; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=BB+gL7mxieeD5sbdO4odNM4IVkyTFBBD3o9K6mLUCPGl4c1JIUU6z69+ESv5qAc2X8Ilv1bTGbUOpIxQnSjTq65YpsIOBiFD+NY6+6DTHgfuAxmi/J9VdmbqybkEfJyQKpL6ebjZ+9JLO6LOsFoBO2993dnUkR8DHgbq2JbDI00= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=McNohOokOZvCOPztdqrD6IMpQ2o/cc6SdtnvvgnHzSA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DSNTJFazwgKIFthF70s9kyAExxR/WHugVGKClCOjPGgysyOd8p9ZaJofErLo0IyJwtrbiXKhjVQquyDrjY74DurKTBf8KA1ZbRFBz9HD+3qrwrNpA9yRyrGgf2am3ScmObDjaU8szTZMPzuijvoBtmL2V/mA53JT7asL/JTJu0o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q/UnS1vr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Q/UnS1vr" Received: by smtp.kernel.org (Postfix) with ESMTPS id 649D6C2BCF5; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=McNohOokOZvCOPztdqrD6IMpQ2o/cc6SdtnvvgnHzSA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Q/UnS1vr+6JQD2oEo34N1k8+dCAMqvk6igMeNbpF9zEoBKo57y2ahC98zkgUxLrou FV63WgWHm+hw4qXeXxylUaLUND2TzSset5FPZLZSKXegwnVs4XkpxR3k9wSDGSOmN+ Gisv7w9BAcsFermdN66ptpK+oPsLn0/BrdgYOF1LdPObqO0/Sz4j+4wNC94I93X+Py i12qPLap1f3GSqso+jlXncRLgP2bVua3MWFagrECETr5vSawMWyDjtzc1MeRMDX588 RrNqkMv3pZy4kA5A7xLTKOzAI2nT9zEay3HNlDyQZGUcrEnFZYJnFu8fIJTvIM24+z mfS/4sSczpu6g== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4EA71C79FA1; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:41 +0200 Subject: [PATCH v2 18/22] thunderbolt: Export symbols required by the Apple Silicon driver 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-18-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter , Joshua Peisach X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2413; i=sven@kernel.org; h=from:subject:message-id; bh=McNohOokOZvCOPztdqrD6IMpQ2o/cc6SdtnvvgnHzSA=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTSdZK8S/HbugNl+Wt8oy+XhEgu36p59+sgc2Luk42 n5kQUxGRykLgxgXg6yYIsv2/famTx6+EVy66dJ7mDmsTCBDGLg4BWAieyMZ/ie2ml3ZlrJ4+v4H pqWaHcd0vlcsSLD9xbDnAvsfm3StyXIM/5PSy6yEY2/IPpeY/aXQR9B4fnjydL0gYzct5a+6O4K 7mAE= X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 The driver for the ACIO host router complex on Apple Silicon SoCs can be built as a module and needs tb_probe() and the domain functions to register its NHI with the software connection manager as well as tb_cfg_write() to configure the cable details for its co-processor. Restrict these exports to the thunderbolt_apple module to keep them internal to the Thunderbolt subsystem. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- drivers/thunderbolt/ctl.c | 2 ++ drivers/thunderbolt/domain.c | 2 ++ drivers/thunderbolt/tb.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c index cd47b627f97b..b2a6b300e934 100644 --- a/drivers/thunderbolt/ctl.c +++ b/drivers/thunderbolt/ctl.c @@ -8,6 +8,7 @@ =20 #include #include +#include #include #include #include @@ -1159,6 +1160,7 @@ int tb_cfg_write(struct tb_ctl *ctl, const void *buff= er, u64 route, u32 port, } return res.err; } +EXPORT_SYMBOL_FOR_MODULES(tb_cfg_write, "thunderbolt_apple"); =20 /** * tb_cfg_get_upstream_port() - get upstream port number of switch at route diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c index 12c88509a54f..477a64258b87 100644 --- a/drivers/thunderbolt/domain.c +++ b/drivers/thunderbolt/domain.c @@ -490,6 +490,7 @@ int tb_domain_add(struct tb *tb, bool reset) =20 return ret; } +EXPORT_SYMBOL_FOR_MODULES(tb_domain_add, "thunderbolt_apple"); =20 /** * tb_domain_remove() - Removes and releases a domain @@ -514,6 +515,7 @@ void tb_domain_remove(struct tb *tb) =20 device_unregister(&tb->dev); } +EXPORT_SYMBOL_FOR_MODULES(tb_domain_remove, "thunderbolt_apple"); =20 /** * tb_domain_suspend_noirq() - Suspend a domain diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 72418a07166e..98bf67360cc4 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -6,6 +6,7 @@ * Copyright (C) 2019, Intel Corporation */ =20 +#include #include #include #include @@ -3440,3 +3441,4 @@ struct tb *tb_probe(struct tb_nhi *nhi) =20 return tb; } +EXPORT_SYMBOL_FOR_MODULES(tb_probe, "thunderbolt_apple"); --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 947563D1AA2; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=ODsaQih0/IiCWTdaDum7jjhMW8JIHuvojq8aZd2NECd8DwMaQqH03OSX1p45UcIlZjVNMvlYdQ69DvC7daiJwq+QaXu3FQQYj8HjtZbdlEvMWyJDx/WpYxAgML/wFrb3IKCnDYIoZOC6JbYEBhRcu8qI9cOwgbL9dCpcJ19zJvQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=3zUbPx8mykzL9oqPguTr50GoDwxQcBfWA7x4cF+x+hM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sLXCnz7hVseSeua35FmcT1ZmaRWZ1WtUeYFubukCW3Ic4mYdnH2x7rO3SimsJsT2xsyhq0opgdkwQ6QDcpyI1kF62EJQiMPYxtcANrzXAue0xL2JSgjxdDZDe++m1h9UxBZO8LcQpQwpvqPodMAmQUXc0S2fIKtw7EZcJPIbTJI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jtAcB6mX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jtAcB6mX" Received: by smtp.kernel.org (Postfix) with ESMTPS id 74CE3C2BCB8; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=3zUbPx8mykzL9oqPguTr50GoDwxQcBfWA7x4cF+x+hM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jtAcB6mXG6TAtOH+ikFtgTarjmQkmL3KaePAQTs0s97cDY13uVAXwVzeIrVQPFQJm TjVUNOVjE0z21gxeuNO0Ff7z1GR8tlp7VdZFj07bZID79D2tG6E8IrdV2MzOIbiMgo 6AUNrsXJxUmpcSC9z0UgXZIoxRJOsH17W6O9rBIgN1FD8J782H+dHRM0AiBvkoxDLy aswsqFS6wo7grCN1ziD4P4S1eROilU7lXij2KwH48D+0YKGgnJoAXWU+JsYVZ+mxTF NmQrLMqqHl80SVMIHFdAKDfDBGQJ/nBRwLLjMauxyvVbMfbY1OXg+uzSAzDEI0JGJ5 v2HYrxqVBf4NA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 64692C79F8C; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:42 +0200 Subject: [PATCH v2 19/22] thunderbolt: Add Apple Silicon support 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-19-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=45061; i=sven@kernel.org; h=from:subject:message-id; bh=3zUbPx8mykzL9oqPguTr50GoDwxQcBfWA7x4cF+x+hM=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTacFe9b8UlkR5fTo6crrMYcnf7nopyNz9mD6nZM3X hdc3+S1pqOUhUGMi0FWTJFl+3570ycP3wgu3XTpPcwcViaQIQxcnAIwkVsWjAwnBD8/f/GmZv8s 1cQgzQ7Rg91emUqqPfpHDjy4Lu/3oTyL4X/q7PC+D+vmV6cu2XJ82aUzKTlssY9Pyx/cUdkW9pm vX40bAA== X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 Add a platform driver for the ACIO host router complex and Native Host Interface (NHI) found on Apple Silicon SoCs. The driver registers notifications for Thunderbolt and USB4 partner modes on the Type-C bus and derives the cable details from the Thunderbolt VDOs or USB4 EUDO. After powering up ACIO, the driver boots its RTKit co-processor and populates the DART and NHI child devices once their MMIO regions become accessible. It then registers the NHI with the software connection manager and forwards the cable details to the host router. The Apple NHI uses one interrupt per ring and overrides the generic ring register accessors, interrupt handling and ring configuration. It also uses the OF graph connection between the USB3 adapter and the DWC3 controller to create the device link required to restore tunnels before USB resumes. As of this commit only XDomain connections and USB3-via-USB4 tunnels are supported. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- MAINTAINERS | 1 + drivers/thunderbolt/Kconfig | 13 + drivers/thunderbolt/Makefile | 3 + drivers/thunderbolt/apple.c | 1277 ++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 1294 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 406cf664dedc..a0ddea98813c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2692,6 +2692,7 @@ F: drivers/rtc/rtc-macsmc.c F: drivers/soc/apple/* F: drivers/spi/spi-apple.c F: drivers/spmi/spmi-apple-controller.c +F: drivers/thunderbolt/apple.c F: drivers/usb/dwc3/dwc3-apple.c F: drivers/video/backlight/apple_dwi_bl.c F: drivers/watchdog/apple_wdt.c diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig index 294b3227a545..d9fbe3a0dc3f 100644 --- a/drivers/thunderbolt/Kconfig +++ b/drivers/thunderbolt/Kconfig @@ -75,4 +75,17 @@ config USB4_STREAM To compile this driver a module, choose M here. The module will be called thunderbolt_stream. =20 +config USB4_APPLE_SOC + tristate "Apple Silicon USB4/Thunderbolt Support" + depends on ARCH_APPLE || COMPILE_TEST + depends on OF && APPLE_RTKIT + depends on TYPEC + select APPLE_TUNABLE + help + Say Y here to add support for the USB4 and Thunderbolt host + routers found on Apple Silicon machines starting with the M1. + + To compile the driver as a module, choose M here. The module + will be called thunderbolt_apple. + endif # USB4 diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile index beb054c3126b..edcfe58bc8de 100644 --- a/drivers/thunderbolt/Makefile +++ b/drivers/thunderbolt/Makefile @@ -16,3 +16,6 @@ obj-$(CONFIG_USB4_DMA_TEST) +=3D thunderbolt_dma_test.o =20 thunderbolt_stream-${CONFIG_USB4_STREAM} +=3D stream.o obj-$(CONFIG_USB4_STREAM) +=3D thunderbolt_stream.o + +obj-$(CONFIG_USB4_APPLE_SOC) +=3D thunderbolt_apple.o +thunderbolt_apple-y :=3D apple.o diff --git a/drivers/thunderbolt/apple.c b/drivers/thunderbolt/apple.c new file mode 100644 index 000000000000..f4b16f60701e --- /dev/null +++ b/drivers/thunderbolt/apple.c @@ -0,0 +1,1277 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Apple Silicon USB4 and Thunderbolt driver + * Copyright (c) Sven Peter + * + * This driver implements the Host Router / ACIO coprocessor as well as the + * Native Host Interface (NHI) as shown in the diagram below. + * The ACIO is a Cortex-M3 coprocessor which handles the Thunderbolt + * protocol and exposes its own hardware blocks like the USB4 Native Host + * Interface (NHI) and its IOMMU to the main SoC bus. The entire block + * can only be brought up after the unified Type-C PHY has been initialized + * to Thunderbolt or USB4 mode and needs an out-of-band notification from + * the Type-C PD driver. + * + * +--------------------+ + * | | +--------------------------------------------+ + * | Display Controller | | Host Router / ACIO | + * | dcpext0 | | +----------------+ | + * | | | | Native | | + * +--------+-----------+ | | Host | | + * | | | Interface | | + * | +---------+ +----------------+ +---------+ = +--------+ + * | +--------->| DP IN | | PCIE DN |<= --->| APCIEC | + * v | | Adapter | +----------------+ | Adapter | = +--------+ + * +---------+-+ +---------+ | | +---------+ + * | Display | | | IOMMU / DART | | + * | Crossbar | | | | +---------+ = +------+ + * +---------+-+ +---------+ +----------------+ | USB3 |<= --->| DWC3 | + * ^ | | DP IN | | Adapter | = +------+ + * | +--------->| Adapter | +---------+ + * | +---------+ | + * | | | + * | | +----------+ | + * +--------+-----------+ | | Type C | | + * | | | | Adapter | | + * | Display Controller | +-----------------+----------+---------------+ + * | dcpext1 | ^ ^ + * | | | | + * +--------------------+ | | + * v | + * +--------------+ | SBRX/TX + * | Apple Type-C | | + * | PHY | | + * +--------------+ | + * ^ | + * | v + * | +---------+ + * +---->| Type C | + * SSRX/TX | Port | + * +---------+ + * + * ACIO and ATCPHY have strict ordering requirements. When a USB4/Thunderb= olt + * connection is requested after a device has been connected the Type-C PD + * driver performs the following sequence: + * + * 1) Configure the PHY for the negotiated mode and orientation through + * typec_mux_set() + * 2) Mark the negotiated Type-C alternate mode active + * 3) Power up ACIO, boot its RTKit co-processor and apply the tunables + * 4) Probe the DART and NHI children now that their MMIO is accessible fr= om + * the main SoC bus + * 5) Register the USB4 domain and write the cable details to the host rou= ter + * which brings up the link and starts discovery + * + * ACIO must not be started before the PHY is configured. The child devices + * cannot remain populated while ACIO is powered off because they are part + * of the ACIO block and only exposed to the main SoC bus and will SError + * once ACIO is off. Violating this ordering can panic the kernel with an + * async SError at best and trigger some internal watchdog that will reset + * the entire SoC at worst. + * + * When the cable is disconnected ACIO shutdown and PHY shutdown can happe= n in + * either order as long as both have been shutdown before the next connect= ion + * is established. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nhi.h" +#include "tb.h" + +#define APPLE_CIO_M3_CTRL 0x0c +#define APPLE_CIO_M3_CTRL_START BIT(1) +#define APPLE_CIO_M3_STAT 0xa8 +#define APPLE_CIO_M3_STAT_STATE GENMASK(30, 24) + +#define APPLE_CIO_NHI_HOP_COUNT 0x0 +#define APPLE_CIO_NHI_HOP_COUNT_MASK GENMASK(9, 0) + +#define APPLE_CIO_NHI_TXRING_DESC_BASE 0x10000 +#define APPLE_CIO_NHI_RXRING_DESC_BASE 0x80000 +#define APPLE_CIO_NHI_RING_STRIDE 0x4000 + +#define APPLE_CIO_NHI_PDF_STRIDE 0x4000 + +#define APPLE_CIO_USB3_ADAPTER 4 + +#define APPLE_CIO_NHI_IRQ_STATUS 0xd0000 +#define APPLE_CIO_NHI_IRQ_ENABLE 0xd0010 +#define APPLE_CIO_NHI_IRQ_THROTTLE 0xd004c +#define APPLE_CIO_NHI_IRQ_THROTTLE_INTERVAL_MASK GENMASK(15, 0) +#define APPLE_CIO_NHI_IRQ_THROTTLE_GRANULARITY_NSEC 256 + +#define APPLE_CIO_SRAM_IOVA_BASE 0x10000000 + +#define APPLE_CIO_NHI_BOOT_TIMEOUT 10000 /* ms */ + +/* + * The Apple vendor-specific extended capability contains a cable-informat= ion + * word which has to be programmed from the USB4/Thunderbolt details repor= ted + * out-of-band by the Type-C PD controller. It must be programmed into the + * host router before link discovery starts. + */ +#define TB_VSE_CAP_APPLE_CABLE_INFO 0x01 +#define TB_VSE_CAP_APPLE_CABLE_INFO_PRESENT BIT(0) +#define TB_VSE_CAP_APPLE_CABLE_INFO_ORIENTATION_REVERSE BIT(1) +#define TB_VSE_CAP_APPLE_CABLE_INFO_ACTIVE_CABLE BIT(2) +#define TB_VSE_CAP_APPLE_CABLE_INFO_BIDIR_LSRX BIT(3) +#define TB_VSE_CAP_APPLE_CABLE_INFO_20_GBPS BIT(4) +#define TB_VSE_CAP_APPLE_CABLE_INFO_LEGACY_ADAPTER BIT(9) +#define TB_VSE_CAP_APPLE_CABLE_INFO_TBT2_3 BIT(10) + +struct apple_cio; + +struct apple_cio_altmode { + struct apple_cio *acio; + struct typec_altmode *altmode; + struct notifier_block notifier; +}; + +/** + * struct apple_cio - Apple Converged I/O block + * @dev: ACIO device + * @np: ACIO device tree node + * @rtk: RTKit instance for the ACIO co-processor + * @rc_base: ACIO root controller registers + * @rc_res: ACIO root controller MMIO resource + * @rc_tunable: Tunable sequence for the ACIO root controller + * @sram_res: ACIO co-processor SRAM resource + * @sram_base: ACIO co-processor SRAM + * @reset: ACIO reset controller + * @pd_list: Power domains used by the ACIO block + * @lock: Serializes cable transitions and ACIO power changes + * @current_cable_info: Cable information currently programmed into ACIO + * @target_cable_info: Cable information requested by the Type-C PD driver + * @nhi_boot_completion: Signals completion of the NHI bringup + * @nhi_boot_status: Status returned by the NHI bringup + * @connector: Type-C connector firmware node linked to this ACIO + * @typec_lock: Serializes Type-C alternate mode attachment and removal + * @typec_notifier: Type-C bus notifier used to discover partner alternate= modes + * @tbt_altmode: Thunderbolt partner alternate mode subscription + * @usb4_altmode: USB4 partner alternate mode subscription + */ +struct apple_cio { + struct device *dev; + struct device_node *np; + struct apple_rtkit *rtk; + void __iomem *rc_base; + struct resource *rc_res; + struct apple_tunable *rc_tunable; + struct resource *sram_res; + void __iomem *sram_base; + struct reset_control *reset; + struct dev_pm_domain_list *pd_list; + struct mutex lock; + u32 current_cable_info; + u32 target_cable_info; + struct completion nhi_boot_completion; + int nhi_boot_status; + struct fwnode_handle *connector; + struct mutex typec_lock; + struct notifier_block typec_notifier; + struct apple_cio_altmode tbt_altmode; + struct apple_cio_altmode usb4_altmode; +}; + +/** + * struct apple_nhi - Apple Native Host Interface + * @dev: NHI device + * @pdev: NHI platform device + * @np: NHI device tree node + * @acio: Parent ACIO block + * @tb: USB4 domain and software connection manager + * @nhi: NHI struct + * @nhi_base: NHI registers + * @pdf_base: PDF (Protocol Defined Field) configuration registers + * @tx_irqs: Transmit ring interrupts indexed by HopID + * @rx_irqs: Receive ring interrupts indexed by HopID + * @tx_irq_names: Names of the transmit ring interrupts + * @rx_irq_names: Names of the receive ring interrupts + * @nrings: Number of rings in each direction + */ +struct apple_nhi { + struct device *dev; + struct platform_device *pdev; + struct device_node *np; + struct apple_cio *acio; + struct tb *tb; + struct tb_nhi nhi; + void __iomem *nhi_base; + void __iomem *pdf_base; + int *tx_irqs; + int *rx_irqs; + const char **tx_irq_names; + const char **rx_irq_names; + size_t nrings; +}; + +#define nhi_to_anhi(nhi_) container_of((nhi_), struct apple_nhi, nhi) + +/** + * apple_cio_rtkit_shmem_setup() - Map an RTKit shared memory buffer + * @cookie: ACIO instance passed to RTKit + * @bfr: RTKit shared memory buffer descriptor + * + * Translate the firmware-provided IOVA into the ACIO SRAM mapping and rej= ect + * buffers that fall outside the reserved SRAM resource. + * + * Return: 0 on success or a negative error code on failure. + */ +static int apple_cio_rtkit_shmem_setup(void *cookie, struct apple_rtkit_sh= mem *bfr) +{ + struct apple_cio *acio =3D cookie; + struct resource res =3D { + .name =3D "acio_rtkit_buffer", + .flags =3D acio->sram_res->flags, + }; + + if (!bfr->iova) + return -EIO; + + if (bfr->iova < APPLE_CIO_SRAM_IOVA_BASE) { + dev_err(acio->dev, "firmware requested invalid buffer before SRAM IOVA b= ase 0x%llx\n", + bfr->iova); + return -EFAULT; + } + + res.start =3D bfr->iova - APPLE_CIO_SRAM_IOVA_BASE + acio->sram_res->star= t; + res.end =3D res.start + bfr->size - 1; + + if (res.end < res.start) { + dev_err(acio->dev, "firmware requested invalid buffer %pR\n", &res); + return -EFAULT; + } + + if (!resource_contains(acio->sram_res, &res)) { + dev_err(acio->dev, "firmware requested buffer %pR outside SRAM %pR\n", &= res, + acio->sram_res); + return -EFAULT; + } + + bfr->iomem =3D acio->sram_base + (res.start - acio->sram_res->start); + bfr->is_mapped =3D true; + return 0; +} + +static const struct apple_rtkit_ops apple_cio_rtkit_ops =3D { + .shmem_setup =3D apple_cio_rtkit_shmem_setup, +}; + +static int apple_nhi_probe_irqs(struct apple_nhi *anhi) +{ + char name[64]; + int nirqs; + + nirqs =3D platform_irq_count(anhi->pdev); + if (nirqs < 0) + return dev_err_probe(anhi->dev, nirqs, "platform_irq_count failed\n"); + if (!nirqs) + return dev_err_probe(anhi->dev, -EINVAL, "no interrupts found\n"); + if (nirqs % 2) + return dev_err_probe(anhi->dev, -EINVAL, + "invalid number of interrupts: %d must be even\n", + nirqs); + anhi->nrings =3D nirqs / 2; + + anhi->rx_irqs =3D devm_kcalloc(anhi->dev, anhi->nrings, + sizeof(*anhi->rx_irqs), GFP_KERNEL); + if (!anhi->rx_irqs) + return -ENOMEM; + anhi->tx_irqs =3D devm_kcalloc(anhi->dev, anhi->nrings, + sizeof(*anhi->tx_irqs), GFP_KERNEL); + if (!anhi->tx_irqs) + return -ENOMEM; + anhi->rx_irq_names =3D devm_kcalloc(anhi->dev, anhi->nrings, + sizeof(*anhi->rx_irq_names), GFP_KERNEL); + if (!anhi->rx_irq_names) + return -ENOMEM; + anhi->tx_irq_names =3D devm_kcalloc(anhi->dev, anhi->nrings, + sizeof(*anhi->tx_irq_names), GFP_KERNEL); + if (!anhi->tx_irq_names) + return -ENOMEM; + + for (int i =3D 0; i < anhi->nrings; ++i) { + snprintf(name, sizeof(name), "rxring%d", i); + anhi->rx_irqs[i] =3D platform_get_irq_byname(anhi->pdev, name); + if (anhi->rx_irqs[i] < 0) + return anhi->rx_irqs[i]; + anhi->rx_irq_names[i] =3D devm_kasprintf(anhi->dev, GFP_KERNEL, "%s-%s", + dev_name(anhi->dev), name); + if (!anhi->rx_irq_names[i]) + return -ENOMEM; + + snprintf(name, sizeof(name), "txring%d", i); + anhi->tx_irqs[i] =3D platform_get_irq_byname(anhi->pdev, name); + if (anhi->tx_irqs[i] < 0) + return anhi->tx_irqs[i]; + anhi->tx_irq_names[i] =3D devm_kasprintf(anhi->dev, GFP_KERNEL, "%s-%s", + dev_name(anhi->dev), name); + if (!anhi->tx_irq_names[i]) + return -ENOMEM; + } + + return 0; +} + +static unsigned int apple_cio_ring_index(struct tb_ring *ring) +{ + struct apple_nhi *anhi =3D nhi_to_anhi(ring->nhi); + + if (ring->is_tx) + return ring->hop; + else + return ring->hop + anhi->nrings; +} + +static void apple_nhi_ring_interrupt_active(struct tb_ring *ring, bool act= ive) +{ + struct apple_nhi *anhi =3D nhi_to_anhi(ring->nhi); + unsigned int idx =3D apple_cio_ring_index(ring); + u32 reg, interval; + + lockdep_assert_held(&ring->nhi->lock); + + if (active && ring->interval_nsec) { + interval =3D min_t(u32, ring->interval_nsec, + FIELD_MAX(APPLE_CIO_NHI_IRQ_THROTTLE_INTERVAL_MASK) * + APPLE_CIO_NHI_IRQ_THROTTLE_GRANULARITY_NSEC); + interval =3D DIV_ROUND_UP(interval, + APPLE_CIO_NHI_IRQ_THROTTLE_GRANULARITY_NSEC); + writel(interval, anhi->nhi_base + APPLE_CIO_NHI_IRQ_THROTTLE + + 4 * idx); + } + + reg =3D readl(anhi->nhi_base + APPLE_CIO_NHI_IRQ_ENABLE); + + if (active) + reg |=3D BIT(idx); + else + reg &=3D ~BIT(idx); + + writel(reg, anhi->nhi_base + APPLE_CIO_NHI_IRQ_ENABLE); +} + +static void apple_nhi_ring_interrupt_mask(struct tb_ring *ring, bool mask) +{ + apple_nhi_ring_interrupt_active(ring, !mask); +} + +static irqreturn_t apple_cio_ring_irq(int irq, void *data) +{ + struct tb_ring *ring =3D data; + struct apple_nhi *anhi; + unsigned int idx; + + anhi =3D nhi_to_anhi(ring->nhi); + idx =3D apple_cio_ring_index(ring); + + guard(spinlock)(&ring->nhi->lock); + guard(spinlock)(&ring->lock); + + writel(BIT(idx), anhi->nhi_base + APPLE_CIO_NHI_IRQ_STATUS); + if (!ring->running) + return IRQ_HANDLED; + + if (ring->start_poll) { + apple_nhi_ring_interrupt_mask(ring, true); + ring->start_poll(ring->poll_data); + } else { + schedule_work(&ring->work); + } + + return IRQ_HANDLED; +} + +static int apple_nhi_request_irq(struct tb_ring *ring, bool no_suspend) +{ + struct apple_nhi *anhi =3D nhi_to_anhi(ring->nhi); + const char *name; + + if (ring->is_tx) { + ring->irq =3D anhi->tx_irqs[ring->hop]; + name =3D anhi->tx_irq_names[ring->hop]; + } else { + ring->irq =3D anhi->rx_irqs[ring->hop]; + name =3D anhi->rx_irq_names[ring->hop]; + } + + return devm_request_irq(anhi->dev, ring->irq, apple_cio_ring_irq, + no_suspend ? IRQF_NO_SUSPEND : 0, name, ring); +} + +static void apple_nhi_release_irq(struct tb_ring *ring) +{ + if (ring->irq <=3D 0) + return; + + devm_free_irq(ring->nhi->dev, ring->irq, ring); + ring->irq =3D 0; +} + +static void __iomem *apple_nhi_ring_desc_base(struct tb_ring *ring) +{ + struct apple_nhi *anhi =3D nhi_to_anhi(ring->nhi); + void __iomem *io =3D anhi->nhi_base; + + io +=3D ring->hop * APPLE_CIO_NHI_RING_STRIDE; + io +=3D ring->is_tx ? APPLE_CIO_NHI_TXRING_DESC_BASE : + APPLE_CIO_NHI_RXRING_DESC_BASE; + return io; +} + +static void __iomem *apple_nhi_ring_options_base(struct tb_ring *ring) +{ + return apple_nhi_ring_desc_base(ring) + 0x10; +} + +static void apple_nhi_ring_configure(struct tb_ring *ring, u32 flags, u32 = e2e_flags) +{ + void __iomem *options =3D apple_nhi_ring_options_base(ring); + struct apple_nhi *anhi =3D nhi_to_anhi(ring->nhi); + u32 sof_eof_mask; + + lockdep_assert_held(&ring->lock); + + if (ring->is_tx) { + /* + * All TX rings share what macOS calls a shared buffer with 232 entries.= This is how + * macOS splits it up, ring 0 only carries control packets and gets the = minimum. + */ + if (ring->hop =3D=3D 0) + writel(2, options + 4); + else if (ring->hop <=3D 5) + writel(40, options + 4); + else + writel(5, options + 4); + } else { + sof_eof_mask =3D ring->sof_mask << 16 | ring->eof_mask; + writel(sof_eof_mask, options + 4); + writel(sof_eof_mask, anhi->pdf_base + ring->hop * APPLE_CIO_NHI_PDF_STRI= DE); + } + + /* + * The firmware samples the ring configuration when the valid bit is set = and E2E flow + * control never engages when configured afterwards. Write everything at = once like macOS. + */ + writel(flags | e2e_flags, options); +} + +static bool apple_nhi_add_links(struct tb_nhi *nhi) +{ + struct apple_nhi *anhi =3D nhi_to_anhi(nhi); + struct fwnode_handle *endpoint, *remote; + struct device_link *link; + struct device *consumer; + + endpoint =3D fwnode_graph_get_endpoint_by_id(dev_fwnode(anhi->acio->dev), + APPLE_CIO_USB3_ADAPTER, 0, 0); + if (!endpoint) + return false; + + remote =3D fwnode_graph_get_remote_port_parent(endpoint); + fwnode_handle_put(endpoint); + if (!remote) + return false; + + consumer =3D bus_find_device_by_fwnode(&platform_bus_type, remote); + fwnode_handle_put(remote); + if (!consumer) + return false; + + link =3D device_link_add(consumer, nhi->dev, + DL_FLAG_AUTOREMOVE_SUPPLIER | + DL_FLAG_PM_RUNTIME); + if (link) + dev_dbg(nhi->dev, "created link from %s\n", dev_name(consumer)); + else + dev_warn(nhi->dev, "device link creation from %s failed\n", + dev_name(consumer)); + + put_device(consumer); + + return !!link; +} + +static const struct tb_nhi_ops apple_nhi_ops =3D { + .request_ring_irq =3D apple_nhi_request_irq, + .release_ring_irq =3D apple_nhi_release_irq, + .ring_desc_base =3D apple_nhi_ring_desc_base, + .ring_options_base =3D apple_nhi_ring_options_base, + .ring_interrupt_active =3D apple_nhi_ring_interrupt_active, + .ring_interrupt_mask =3D apple_nhi_ring_interrupt_mask, + .ring_configure =3D apple_nhi_ring_configure, + .add_links =3D apple_nhi_add_links, +}; + +static int apple_nhi_probe(struct platform_device *pdev) +{ + struct apple_cio *acio =3D dev_get_drvdata(pdev->dev.parent); + struct apple_tunable *tunable; + struct apple_nhi *anhi; + struct resource *res; + int ret =3D 0; + + anhi =3D devm_kzalloc(&pdev->dev, sizeof(*anhi), GFP_KERNEL); + if (!anhi) { + ret =3D -ENOMEM; + goto err; + } + + anhi->pdev =3D pdev; + anhi->dev =3D &pdev->dev; + anhi->np =3D pdev->dev.of_node; + anhi->acio =3D acio; + platform_set_drvdata(pdev, anhi); + + /* + * Only 42 bits seem to be wired up for the IOVA space but this may be fu= rther + * limited by the IOMMU's capabilities. + */ + ret =3D dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(42)); + if (ret) + goto err; + + res =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "nhi"); + anhi->nhi_base =3D devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(anhi->nhi_base)) { + ret =3D dev_err_probe(&pdev->dev, PTR_ERR(anhi->nhi_base), + "unable to map NHI regs\n"); + goto err; + } + tunable =3D devm_apple_tunable_parse(&pdev->dev, anhi->np, "apple,tunable= -nhi", res); + if (IS_ERR(tunable)) { + ret =3D dev_err_probe(&pdev->dev, PTR_ERR(tunable), + "unable to load NHI tunable\n"); + goto err; + } + apple_tunable_apply(anhi->nhi_base, tunable); + + res =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "pdf"); + anhi->pdf_base =3D devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(anhi->pdf_base)) { + ret =3D dev_err_probe(&pdev->dev, PTR_ERR(anhi->pdf_base), + "unable to map PDF regs\n"); + goto err; + } + + ret =3D apple_nhi_probe_irqs(anhi); + if (ret) + goto err; + + spin_lock_init(&anhi->nhi.lock); + /* DMA transactions on this platform always go through a DART IOMMU. */ + anhi->nhi.iommu_dma_protection =3D true; + anhi->nhi.ops =3D &apple_nhi_ops; + anhi->nhi.iobase =3D anhi->nhi_base; + anhi->nhi.hop_count =3D readl(anhi->nhi_base + APPLE_CIO_NHI_HOP_COUNT) & + APPLE_CIO_NHI_HOP_COUNT_MASK; + if (anhi->nhi.hop_count !=3D anhi->nrings) { + ret =3D dev_err_probe(anhi->dev, -EINVAL, + "ring IRQs (%zd) !=3D HOP_COUNT (%d)\n", + anhi->nrings, anhi->nhi.hop_count); + goto err; + } + + anhi->nhi.tx_rings =3D devm_kcalloc(&pdev->dev, anhi->nhi.hop_count, + sizeof(*anhi->nhi.tx_rings), GFP_KERNEL); + anhi->nhi.rx_rings =3D devm_kcalloc(&pdev->dev, anhi->nhi.hop_count, + sizeof(*anhi->nhi.rx_rings), GFP_KERNEL); + if (!anhi->nhi.tx_rings || !anhi->nhi.rx_rings) { + ret =3D -ENOMEM; + goto err; + } + + anhi->nhi.dev =3D &pdev->dev; + init_completion(&anhi->nhi.domain_released); + anhi->tb =3D tb_probe(&anhi->nhi); + if (!anhi->tb) { + ret =3D dev_err_probe(anhi->dev, -ENODEV, + "failed to init software connection manager\n"); + goto err; + } + + ret =3D tb_domain_add(anhi->tb, false); + if (ret) { + dev_err_probe(anhi->dev, ret, "failed to add domain\n"); + tb_domain_put(anhi->tb); + wait_for_completion(&anhi->nhi.domain_released); + goto err; + } + + mutex_lock(&anhi->tb->lock); + + if (!anhi->tb->root_switch->drom) { + dev_err(anhi->dev, "no valid host DROM in the device tree\n"); + ret =3D -EINVAL; + goto err_unlock_tb_domain; + } + + if (!anhi->tb->root_switch->cap_vsec_apple) { + dev_err(anhi->dev, "unable to find VSE Apple capability\n"); + ret =3D -ENODEV; + goto err_unlock_tb_domain; + } + + ret =3D tb_sw_write(anhi->tb->root_switch, &acio->target_cable_info, TB_C= FG_SWITCH, + anhi->tb->root_switch->cap_vsec_apple + + TB_VSE_CAP_APPLE_CABLE_INFO, 1); + if (ret) { + dev_warn(anhi->dev, "setting VSE Apple cable info failed: %d\n", ret); + goto err_unlock_tb_domain; + } + + mutex_unlock(&anhi->tb->lock); + + acio->nhi_boot_status =3D 0; + complete(&acio->nhi_boot_completion); + return 0; + +err_unlock_tb_domain: + mutex_unlock(&anhi->tb->lock); + tb_domain_remove(anhi->tb); + wait_for_completion(&anhi->nhi.domain_released); +err: + acio->nhi_boot_status =3D ret; + complete(&acio->nhi_boot_completion); + + return ret; +} + +static void apple_nhi_remove(struct platform_device *pdev) +{ + struct apple_nhi *anhi =3D platform_get_drvdata(pdev); + + tb_domain_remove(anhi->tb); + wait_for_completion(&anhi->nhi.domain_released); +} + +static const struct of_device_id apple_nhi_match[] =3D { + { + .compatible =3D "apple,t8103-usb4-nhi", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, apple_nhi_match); + +static struct platform_driver apple_nhi_driver =3D { + .driver =3D { + .name =3D "thunderbolt-apple-nhi", + .of_match_table =3D apple_nhi_match, + }, + .probe =3D apple_nhi_probe, + .remove =3D apple_nhi_remove, +}; + +/** + * apple_cio_stop() - Stop and power down the ACIO block + * @acio: ACIO block to stop + * + * Remove the NHI and DART children before shutting down the co-processor = and + * dropping the power-domain links. The caller must hold @acio->lock. + */ +static void apple_cio_stop(struct apple_cio *acio) +{ + int ret, i; + + lockdep_assert_held(&acio->lock); + + /* + * First, shutdown the blocks inside the ACIO block, like the NHI and the= IOMMU. + * After we shut down the ACIO co-processor we will no longer be able to = access + * the MMIO space of these so make sure nothing tries to do just that. + */ + of_platform_depopulate(acio->dev); + + /* Try to shut down and power off the co-processor gracefully */ + ret =3D apple_rtkit_poweroff(acio->rtk); + if (ret) + dev_warn(acio->dev, + "failed to shutdown M3 RTKit, continuing ACIO shutdown anyway\n"); + apple_rtkit_free(acio->rtk); + + /* Finally, remove the links to the PD domains to power everything off */ + for (i =3D 0; i < acio->pd_list->num_pds; i++) { + if (acio->pd_list->pd_links[i]) + device_link_del(acio->pd_list->pd_links[i]); + acio->pd_list->pd_links[i] =3D NULL; + } + + acio->current_cable_info =3D 0; +} + +/** + * apple_cio_start() - Power up and start the ACIO block + * @acio: ACIO block to start + * + * The Type-C PHY must already be configured for USB4 or Thunderbolt. Powe= r up + * ACIO, boot its RTKit co-processor, populate its child devices and wait = for + * the NHI to register the USB4 domain. The caller must hold @acio->lock. + * + * Return: 0 on success or a negative error code on failure. + */ +static int apple_cio_start(struct apple_cio *acio) +{ + int i, ret; + u32 state; + + lockdep_assert_held(&acio->lock); + + /* Create device links to the power domains in order to power them on */ + for (i =3D 0; i < acio->pd_list->num_pds; i++) { + struct device_link *link; + + link =3D device_link_add(acio->dev, acio->pd_list->pd_devs[i], + DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); + if (!link) { + ret =3D -ENODEV; + goto remove_links; + } + acio->pd_list->pd_links[i] =3D link; + } + + /* + * After the power domains are on we need to signal and wait for the ACIO= block + * to actually start before we can bring up the co-processor. + */ + ret =3D reset_control_deassert(acio->reset); + if (ret) { + dev_err(acio->dev, "ACIO block failed to start: %d\n", ret); + goto remove_links; + } + + /* Start and wait for the co-processor to boot */ + writel(APPLE_CIO_M3_CTRL_START, acio->rc_base + APPLE_CIO_M3_CTRL); + acio->rtk =3D apple_rtkit_init(acio->dev, acio, NULL, 0, &apple_cio_rtkit= _ops); + if (IS_ERR(acio->rtk)) { + ret =3D PTR_ERR(acio->rtk); + dev_err(acio->dev, "failed to initialize RTKit: %d\n", ret); + goto remove_links; + } + + ret =3D apple_rtkit_boot(acio->rtk); + if (ret) { + dev_err(acio->dev, "M3 RTKit failed to boot: %d\n", ret); + goto err_free_rtkit; + } + + ret =3D readl_poll_timeout(acio->rc_base + APPLE_CIO_M3_STAT, state, + state & APPLE_CIO_M3_STAT_STATE, 100, 500000); + if (ret < 0) { + dev_err(acio->dev, "M3 firmware failed to get ready: %d\n", ret); + goto err_shutdown_rtkit; + } + + apple_tunable_apply(acio->rc_base, acio->rc_tunable); + + /* + * Bring up devices which are part of ACIO and are now accessible by the = main SoC + * and specifically wait for the NHI to be up to prevent concurrent shutd= owns. + */ + reinit_completion(&acio->nhi_boot_completion); + ret =3D of_platform_populate(acio->np, NULL, NULL, acio->dev); + if (ret) { + dev_err(acio->dev, "failed to populate children: %d\n", ret); + goto err_depopulate; + } + + if (!wait_for_completion_timeout(&acio->nhi_boot_completion, + msecs_to_jiffies(APPLE_CIO_NHI_BOOT_TIMEOUT))) { + dev_err(acio->dev, "timed out waiting for the NHI to come up\n"); + ret =3D -ETIMEDOUT; + goto err_depopulate; + } + if (acio->nhi_boot_status) { + ret =3D acio->nhi_boot_status; + goto err_depopulate; + } + + acio->current_cable_info =3D acio->target_cable_info; + return 0; + +err_depopulate: + of_platform_depopulate(acio->dev); +err_shutdown_rtkit: + /* Ignore errors here since we're about to cut power to the entire block = anyway */ + apple_rtkit_poweroff(acio->rtk); +err_free_rtkit: + apple_rtkit_free(acio->rtk); +remove_links: + /* Cut power to reset the entire block */ + for (i =3D 0; i < acio->pd_list->num_pds; i++) { + if (acio->pd_list->pd_links[i]) + device_link_del(acio->pd_list->pd_links[i]); + acio->pd_list->pd_links[i] =3D NULL; + } + + return ret; +} + +static int apple_cio_set_cable_info(struct apple_cio *acio, u32 cable_info) +{ + guard(mutex)(&acio->lock); + + acio->target_cable_info =3D cable_info; + if (acio->target_cable_info =3D=3D acio->current_cable_info) + return 0; + + /* + * Transitions between different cables without a shutdown inbetween are = invalid and can + * only happen when there's a bug inside the Type-C PD driver. If we trie= d such a + * transition, ACIO would crash and then trigger some watchdog that would= reset the entire + * SoC a few seconds later. Shutting down instead only makes the connecte= d device not work + * but we should be able to recover once the next cable is plugged in. + */ + if (acio->current_cable_info && acio->target_cable_info) { + dev_err(acio->dev, + "invalid cable transition from 0x%x to 0x%x, shutting down instead\n", + acio->current_cable_info, acio->target_cable_info); + acio->target_cable_info =3D 0; + } + + /* + * Bring up or power down the ACIO block + * current_cable_info will be updated in the start/stop functions + */ + if (acio->target_cable_info) + return apple_cio_start(acio); + + apple_cio_stop(acio); + return 0; +} + +static int apple_cio_tbt_cable_info(struct apple_cio *acio, + struct typec_altmode *altmode, u32 *cable_info) +{ + u32 info =3D TB_VSE_CAP_APPLE_CABLE_INFO_PRESENT | + TB_VSE_CAP_APPLE_CABLE_INFO_TBT2_3; + enum typec_orientation orientation; + struct typec_altmode *plug; + u32 cable_mode; + + plug =3D typec_altmode_get_plug(altmode, TYPEC_PLUG_SOP_P); + if (!plug) + return -ENODEV; + + cable_mode =3D plug->vdo; + typec_altmode_put_plug(plug); + orientation =3D typec_altmode_get_orientation(altmode); + + if (cable_mode & TBT_CABLE_ACTIVE_PASSIVE) { + info |=3D TB_VSE_CAP_APPLE_CABLE_INFO_ACTIVE_CABLE; + if (!(cable_mode & TBT_CABLE_LINK_TRAINING)) + info |=3D TB_VSE_CAP_APPLE_CABLE_INFO_BIDIR_LSRX; + } + if (TBT_ADAPTER(altmode->vdo)) + info |=3D TB_VSE_CAP_APPLE_CABLE_INFO_LEGACY_ADAPTER; + if (TBT_CABLE_SPEED(cable_mode) =3D=3D TBT_CABLE_10_AND_20GBPS) + info |=3D TB_VSE_CAP_APPLE_CABLE_INFO_20_GBPS; + if (orientation =3D=3D TYPEC_ORIENTATION_REVERSE) + info |=3D TB_VSE_CAP_APPLE_CABLE_INFO_ORIENTATION_REVERSE; + + dev_dbg(acio->dev, + "TBT cable: cable mode %#x, device mode %#x, orientation %d -> cable inf= o %#x\n", + cable_mode, altmode->vdo, orientation, info); + *cable_info =3D info; + return 0; +} + +static int apple_cio_usb4_cable_info(struct apple_cio *acio, + struct typec_altmode *altmode, u32 *cable_info) +{ + u32 info =3D TB_VSE_CAP_APPLE_CABLE_INFO_PRESENT; + enum typec_orientation orientation; + u32 eudo =3D altmode->eudo; + + if (FIELD_GET(EUDO_USB_MODE_MASK, eudo) !=3D EUDO_USB_MODE_USB4) + return -EINVAL; + + orientation =3D typec_altmode_get_orientation(altmode); + if (FIELD_GET(EUDO_CABLE_TYPE_MASK, eudo) !=3D EUDO_CABLE_TYPE_PASSIVE) + info |=3D TB_VSE_CAP_APPLE_CABLE_INFO_ACTIVE_CABLE; + if (FIELD_GET(EUDO_CABLE_SPEED_MASK, eudo) =3D=3D EUDO_CABLE_SPEED_USB4_G= EN3) + info |=3D TB_VSE_CAP_APPLE_CABLE_INFO_20_GBPS; + if (orientation =3D=3D TYPEC_ORIENTATION_REVERSE) + info |=3D TB_VSE_CAP_APPLE_CABLE_INFO_ORIENTATION_REVERSE; + + dev_dbg(acio->dev, "USB4 cable: EUDO %#x, orientation %d -> cable info %#= x\n", + eudo, orientation, info); + *cable_info =3D info; + return 0; +} + +static int apple_cio_altmode_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct apple_cio_altmode *subscription; + struct typec_altmode *altmode =3D data; + struct apple_cio *acio; + u32 cable_info; + int ret; + + subscription =3D container_of(nb, struct apple_cio_altmode, notifier); + acio =3D subscription->acio; + + if (altmode !=3D subscription->altmode) + return NOTIFY_DONE; + + switch (action) { + case TYPEC_ALTMODE_ENTERED: + if (altmode->mode_kind =3D=3D TYPEC_MODE_KIND_ALTMODE && + altmode->svid =3D=3D USB_TYPEC_TBT_SID) + ret =3D apple_cio_tbt_cable_info(acio, altmode, &cable_info); + else if (altmode->mode_kind =3D=3D TYPEC_MODE_KIND_USB4) + ret =3D apple_cio_usb4_cable_info(acio, altmode, &cable_info); + else + ret =3D -EINVAL; + if (ret) { + dev_err(acio->dev, "failed to read Type-C cable information: %d\n", ret= ); + return NOTIFY_OK; + } + break; + case TYPEC_ALTMODE_EXITED: + cable_info =3D 0; + break; + default: + return NOTIFY_DONE; + } + + /* + * The altmode has already been negotiated and we can't exit it anyway + * on Apple Silicon so just warn the we couldn't start but still return + * success. + */ + ret =3D apple_cio_set_cable_info(acio, cable_info); + if (ret) + dev_warn(acio->dev, "failed to start ACIO: %d\n", ret); + + return NOTIFY_OK; +} + +static struct apple_cio_altmode * +apple_cio_altmode_subscription(struct apple_cio *acio, struct typec_altmod= e *altmode) +{ + if (altmode->mode_kind =3D=3D TYPEC_MODE_KIND_ALTMODE && + altmode->svid =3D=3D USB_TYPEC_TBT_SID) + return &acio->tbt_altmode; + if (altmode->mode_kind =3D=3D TYPEC_MODE_KIND_USB4) + return &acio->usb4_altmode; + return NULL; +} + +static bool apple_cio_altmode_matches(struct apple_cio *acio, + struct typec_altmode *altmode) +{ + if (!apple_cio_altmode_subscription(acio, altmode)) + return false; + + return dev_fwnode(altmode->dev.parent->parent) =3D=3D acio->connector; +} + +static int apple_cio_altmode_attach_locked(struct apple_cio *acio, + struct typec_altmode *altmode) +{ + struct apple_cio_altmode *subscription; + int ret; + + lockdep_assert_held(&acio->typec_lock); + + if (!apple_cio_altmode_matches(acio, altmode)) + return 0; + + subscription =3D apple_cio_altmode_subscription(acio, altmode); + + if (subscription->altmode =3D=3D altmode) + return 0; + if (subscription->altmode) + return -EBUSY; + + get_device(&altmode->dev); + subscription->altmode =3D altmode; + ret =3D typec_altmode_register_notifier(altmode, &subscription->notifier); + if (ret) { + subscription->altmode =3D NULL; + put_device(&altmode->dev); + } + + return ret; +} + +static int apple_cio_altmode_attach(struct apple_cio *acio, + struct typec_altmode *altmode) +{ + guard(mutex)(&acio->typec_lock); + + return apple_cio_altmode_attach_locked(acio, altmode); +} + +static void apple_cio_altmode_detach(struct apple_cio *acio, + struct typec_altmode *altmode) +{ + struct apple_cio_altmode *subscription; + bool active; + + subscription =3D apple_cio_altmode_subscription(acio, altmode); + if (!subscription) + return; + + guard(mutex)(&acio->typec_lock); + if (subscription->altmode !=3D altmode) + return; + + active =3D altmode->active; + typec_altmode_unregister_notifier(altmode, &subscription->notifier); + subscription->altmode =3D NULL; + if (active) + apple_cio_set_cable_info(acio, 0); + put_device(&altmode->dev); +} + +static int apple_cio_typec_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct apple_cio *acio =3D container_of(nb, struct apple_cio, typec_notif= ier); + struct typec_altmode *altmode; + struct device *dev =3D data; + int ret; + + if (!is_typec_partner_altmode(dev)) + return NOTIFY_DONE; + + altmode =3D to_typec_altmode(dev); + switch (action) { + case BUS_NOTIFY_ADD_DEVICE: + ret =3D apple_cio_altmode_attach(acio, altmode); + if (ret) + dev_err(acio->dev, + "failed to register for alternate mode notifications: %d\n", ret); + break; + case BUS_NOTIFY_DEL_DEVICE: + case BUS_NOTIFY_REMOVED_DEVICE: + apple_cio_altmode_detach(acio, altmode); + break; + default: + break; + } + + return NOTIFY_DONE; +} + +static int apple_cio_scan_altmode(struct device *dev, void *data) +{ + if (!is_typec_partner_altmode(dev)) + return 0; + + return apple_cio_altmode_attach_locked(data, to_typec_altmode(dev)); +} + +static void apple_cio_unregister_typec(struct apple_cio *acio) +{ + bus_unregister_notifier(&typec_bus, &acio->typec_notifier); + if (acio->tbt_altmode.altmode) + apple_cio_altmode_detach(acio, acio->tbt_altmode.altmode); + if (acio->usb4_altmode.altmode) + apple_cio_altmode_detach(acio, acio->usb4_altmode.altmode); +} + +static void apple_cio_put_connector(void *data) +{ + struct apple_cio *acio =3D data; + + fwnode_handle_put(acio->connector); +} + +static int apple_cio_probe(struct platform_device *pdev) +{ + struct dev_pm_domain_attach_data pd_data =3D { + .pd_flags =3D PD_FLAG_NO_DEV_LINK, + }; + struct device *dev =3D &pdev->dev; + struct fwnode_handle *endpoint; + struct apple_cio *acio; + int ret; + + acio =3D devm_kzalloc(dev, sizeof(*acio), GFP_KERNEL); + if (!acio) + return -ENOMEM; + platform_set_drvdata(pdev, acio); + + ret =3D devm_mutex_init(dev, &acio->lock); + if (ret) + return ret; + + ret =3D devm_mutex_init(dev, &acio->typec_lock); + if (ret) + return ret; + + init_completion(&acio->nhi_boot_completion); + acio->dev =3D &pdev->dev; + acio->np =3D dev->of_node; + acio->typec_notifier.notifier_call =3D apple_cio_typec_notify; + acio->tbt_altmode.acio =3D acio; + acio->tbt_altmode.notifier.notifier_call =3D apple_cio_altmode_notify; + acio->usb4_altmode.acio =3D acio; + acio->usb4_altmode.notifier.notifier_call =3D apple_cio_altmode_notify; + + endpoint =3D fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 1, 0, 0); + if (!endpoint) + return dev_err_probe(dev, -ENODEV, "unable to find Type-C graph endpoint= \n"); + acio->connector =3D fwnode_graph_get_remote_port_parent(endpoint); + fwnode_handle_put(endpoint); + if (!acio->connector) + return dev_err_probe(dev, -ENODEV, "unable to find Type-C connector\n"); + ret =3D devm_add_action_or_reset(dev, apple_cio_put_connector, acio); + if (ret) + return ret; + + acio->sram_res =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "sr= am"); + if (!acio->sram_res) + return dev_err_probe(dev, -EIO, "failed to get SRAM resource\n"); + acio->sram_base =3D devm_ioremap_resource(dev, acio->sram_res); + if (IS_ERR(acio->sram_base)) + return dev_err_probe(dev, PTR_ERR(acio->sram_base), "failed to map SRAM\= n"); + + acio->rc_res =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc"); + acio->rc_base =3D devm_ioremap_resource(&pdev->dev, acio->rc_res); + if (IS_ERR(acio->rc_base)) + return dev_err_probe(dev, PTR_ERR(acio->rc_base), "unable to map rc regs= \n"); + acio->rc_tunable =3D + devm_apple_tunable_parse(dev, acio->np, "apple,tunable-rc", acio->rc_res= ); + if (IS_ERR(acio->rc_tunable)) + return dev_err_probe(dev, PTR_ERR(acio->rc_tunable), + "unable to load rc tunable\n"); + + acio->reset =3D devm_reset_control_get_exclusive(dev, NULL); + if (IS_ERR(acio->reset)) + return dev_err_probe(dev, PTR_ERR(acio->reset), "unable to get CIO reset= \n"); + + /* + * If there is only a single PM domain listed in the device tree the + * platform driver framework will already attach it. Thus, if we find an + * already attached PM domain here something's wrong in the device tree + * because we expect at least three separate domains that we have to + * control manually. + */ + if (dev->pm_domain) { + dev_err(dev, "PM domain already attached, check if the DT lists three do= mains\n"); + return -EINVAL; + } + + /* + * Find and attach the PM domains but don't power them on yet since we mu= st only + * do that after the PHY has already been configured into USB4/Thunderbol= t mode. + */ + ret =3D devm_pm_domain_attach_list(dev, &pd_data, &acio->pd_list); + if (ret < 0) + return dev_err_probe(dev, ret, "unable to attach PM domains\n"); + else if (ret < 3) + return dev_err_probe(dev, -EINVAL, "not enough PM domains\n"); + + ret =3D bus_register_notifier(&typec_bus, &acio->typec_notifier); + if (ret) + return dev_err_probe(dev, ret, "unable to register Type-C notifier\n"); + + scoped_guard(mutex, &acio->typec_lock) { + ret =3D bus_for_each_dev(&typec_bus, NULL, acio, apple_cio_scan_altmode); + } + if (ret) { + apple_cio_unregister_typec(acio); + return dev_err_probe(dev, ret, + "unable to register for alternate modes notifications\n"); + } + + return 0; +} + +static void apple_cio_remove(struct platform_device *pdev) +{ + struct apple_cio *acio =3D platform_get_drvdata(pdev); + + apple_cio_unregister_typec(acio); + + guard(mutex)(&acio->lock); + if (acio->current_cable_info) + apple_cio_stop(acio); +} + +static int apple_cio_prepare(struct device *dev) +{ + struct apple_cio *acio =3D dev_get_drvdata(dev); + + guard(mutex)(&acio->lock); + + if (acio->current_cable_info) { + dev_err(dev, "unable to suspend while a USB4/Thunderbolt connection is a= ctive\n"); + return -EBUSY; + } + + return 0; +} + +static const struct dev_pm_ops apple_cio_pm_ops =3D { + .prepare =3D apple_cio_prepare, +}; + +static const struct of_device_id apple_acio_match[] =3D { + { + .compatible =3D "apple,t8103-usb4-acio", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, apple_acio_match); + +static struct platform_driver apple_cio_driver =3D { + .driver =3D { + .name =3D "thunderbolt-apple-acio", + .of_match_table =3D apple_acio_match, + .pm =3D pm_sleep_ptr(&apple_cio_pm_ops), + }, + .probe =3D apple_cio_probe, + .remove =3D apple_cio_remove, +}; + +static struct platform_driver * const apple_cio_drivers[] =3D { + &apple_nhi_driver, + &apple_cio_driver, +}; + +static int __init apple_cio_init(void) +{ + return platform_register_drivers(apple_cio_drivers, + ARRAY_SIZE(apple_cio_drivers)); +} +module_init(apple_cio_init); + +static void __exit apple_cio_exit(void) +{ + platform_unregister_drivers(apple_cio_drivers, + ARRAY_SIZE(apple_cio_drivers)); +} +module_exit(apple_cio_exit); + +MODULE_AUTHOR("Sven Peter "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Apple Silicon USB4/Thunderbolt driver"); --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A4FA93D2FF4; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=r7nHg/hAlaGkZjtcuuwAyfk703sd9cECl9ZXU9ybM6SAIJJct4Gvq4Y4W0WwfX2/tmY8xncaOlhe2Z/pEcvfMHRgK6HMT9ZAgLl3grqnlcyZvRpMaID2O6SOz8IkeLKHoawPsGqATdLKu/aYqLMmzZriMv0TCWA1oA+DGEbigVM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=+AIT3rGrnA1dnHtXc4jyApvNKaFqdKHWbR5KbldVPvw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aWueHQRfwcfaJP+11s8C292VsfJAIUtWshH74+UK+SRFvRPPvrpoIw1MOJuwgOuMOhtKk/eGJ08PSgU7mTTBQgPQXkKzmpuSb1Gqp3t82IEWx4oyj+b4fRuLNnH8yqWtzxbJ4uTUGgK4FZ2rGrcfxkuDpvxAVqapvcZfS2WNGu0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GJvO9ssV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GJvO9ssV" Received: by smtp.kernel.org (Postfix) with ESMTPS id 879A1C2BD01; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=+AIT3rGrnA1dnHtXc4jyApvNKaFqdKHWbR5KbldVPvw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GJvO9ssV520DGnB1ITeCB/an1UtojxE7k/TVyCOECPzwBSeUh0Iueo51EdysMuik3 Paf1mhUAJ85i+An5bQwNapcr3kGbdLyvfuhgqN+DRF+bh9MRnXbDh3gae5diaGkTPH kp9h2TMKuF71pvH1xeOsZrIYiq3mj2Q5KOs15Me9/Ifm3vBYYFqGhUsvwKASCg4iev 6DCA2FkHTntO3WrPOOJ1/CGX+tZ5+BARi+8FKdkl/j5RINUPAWDmJQb59QdLwRW3Eh ICNjBxPahsQpbMHU09FodYtPi1Bsdq48TZUrScQHUEqstNE9/eX5wDMjIM2giG5WaH d21YMsdh1aXjQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 76A24C79FA0; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:43 +0200 Subject: [PATCH v2 20/22] arm64: dts: apple: t8103: Add USB4 ACIO and NHI 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-20-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=10392; i=sven@kernel.org; h=from:subject:message-id; bh=+AIT3rGrnA1dnHtXc4jyApvNKaFqdKHWbR5KbldVPvw=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTWfm/ZV93LNvs0HqFM71LNvyntR8NjNWbJb7ukGuc WHnuxVSHaUsDGJcDLJiiizb99ubPnn4RnDppkvvYeawMoEMYeDiFICJvFjPyHBq37QzaWve6jzT +rIt5MECSfvG5LiSCy/P3S22qBdjiuliZJgvvFw6ulL3dNkbjehWBk3+UqZN4RPUok8yrL77rZz lHB8A X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 Add the ACIO host router, NHI, DART and M3 mailbox nodes for both Type-C ports on t8103 and connect the host routers to the Type-C connectors. Also describe the USB3 path from each host router to its DWC3 controller so the NHI driver can create the required device link. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- arch/arm64/boot/dts/apple/t8103-jxxx.dtsi | 95 ++++++++++++++- arch/arm64/boot/dts/apple/t8103.dtsi | 184 ++++++++++++++++++++++++++= ++++ 2 files changed, 277 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi b/arch/arm64/boot/dt= s/apple/t8103-jxxx.dtsi index 686fb1dd215d..01c942b0a75b 100644 --- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi @@ -17,6 +17,10 @@ aliases { wifi0 =3D &wifi0; atcphy0 =3D &atcphy0; atcphy1 =3D &atcphy1; + usb4-0-acio =3D &usb4_0_acio; + usb4-0-nhi =3D &usb4_0_nhi; + usb4-1-acio =3D &usb4_1_acio; + usb4-1-nhi =3D &usb4_1_nhi; }; =20 chosen { @@ -76,6 +80,13 @@ typec0_connector_ss: endpoint { remote-endpoint =3D <&atcphy0_typec_lanes>; }; }; + + port@2 { + reg =3D <2>; + typec0_con_tbt: endpoint { + remote-endpoint =3D <&usb4_0_acio_tbt>; + }; + }; }; }; }; @@ -107,6 +118,13 @@ typec1_connector_ss: endpoint { remote-endpoint =3D <&atcphy1_typec_lanes>; }; }; + + port@2 { + reg =3D <2>; + typec1_con_tbt: endpoint { + remote-endpoint =3D <&usb4_1_acio_tbt>; + }; + }; }; }; }; @@ -126,10 +144,19 @@ dwc3_0_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_0_ss: endpoint { + + dwc3_0_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy0_usb3>; }; + + dwc3_0_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_0_acio_usb3>; + }; }; }; }; @@ -147,10 +174,19 @@ dwc3_1_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_1_ss: endpoint { + + dwc3_1_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy1_usb3>; }; + + dwc3_1_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_1_acio_usb3>; + }; }; }; }; @@ -198,6 +234,61 @@ atcphy1_usb3: endpoint { }; }; =20 +/* USB4 */ +&usb4_0_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_0_acio_tbt: endpoint { + remote-endpoint =3D <&typec0_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_0_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_0_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_1_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_1_acio_tbt: endpoint { + remote-endpoint =3D <&typec1_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_1_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_1_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + /* * Force the bus number assignments so that we can declare some of the * on-board devices and properties that are populated by the bootloader diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/app= le/t8103.dtsi index 985dbd8e68ca..735591c72fde 100644 --- a/arch/arm64/boot/dts/apple/t8103.dtsi +++ b/arch/arm64/boot/dts/apple/t8103.dtsi @@ -988,6 +988,14 @@ pinctrl_aop: pinctrl@24a820000 { , , ; + + acio0_pins: acio0-pins { + pinmux =3D ; + }; + + acio1_pins: acio1-pins { + pinmux =3D ; + }; }; =20 ans_mbox: mbox@277408000 { @@ -1024,6 +1032,94 @@ nvme@27bcc0000 { resets =3D <&ps_ans2>; }; =20 + usb4_0_mbox: mailbox@381100000 { + compatible =3D "apple,t8103-m3-mailbox", + "apple,m3-mailbox-v2"; + reg =3D <0x3 0x81100000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + usb4_0_acio: cio@381ac0000 { + compatible =3D "apple,t8103-usb4-acio"; + reg =3D <0x3 0x81ac0000 0x0 0xc000>, + <0x3 0x81080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&usb4_0_mbox>; + resets =3D <&cio_reset 0>; + + power-domains =3D <&ps_atc0_cio>, + <&ps_atc0_cio_pcie>, + <&ps_atc0_cio_usb>; + + pinctrl-0 =3D <&acio0_pins>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0x3 0x81000000 0x1000000>; + nonposted-mmio; + + usb4_0_dart: iommu@a80000 { + compatible =3D "apple,t8103-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + }; + + usb4_0_nhi: nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&usb4_0_dart 1>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + dwc3_0: usb@382280000 { compatible =3D "apple,t8103-dwc3"; reg =3D <0x3 0x82280000 0x0 0xcd00>, <0x3 0x8228cd00 0x0 0x3200>; @@ -1076,6 +1172,94 @@ atcphy0: phy@383000000 { power-domains =3D <&ps_atc0_usb>; }; =20 + usb4_1_mbox: mailbox@501100000 { + compatible =3D "apple,t8103-m3-mailbox", + "apple,m3-mailbox-v2"; + reg =3D <0x5 0x01100000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + usb4_1_acio: cio@501ac0000 { + compatible =3D "apple,t8103-usb4-acio"; + reg =3D <0x5 0x01ac0000 0x0 0xc000>, + <0x5 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&usb4_1_mbox>; + resets =3D <&cio_reset 1>; + + power-domains =3D <&ps_atc1_cio>, + <&ps_atc1_cio_pcie>, + <&ps_atc1_cio_usb>; + + pinctrl-0 =3D <&acio1_pins>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0x5 0x01000000 0x1000000>; + nonposted-mmio; + + usb4_1_dart: iommu@a80000 { + compatible =3D "apple,t8103-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + }; + + usb4_1_nhi: nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&usb4_1_dart 1>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + dwc3_1: usb@502280000 { compatible =3D "apple,t8103-dwc3"; reg =3D <0x5 0x02280000 0x0 0xcd00>, <0x5 0x0228cd00 0x0 0x3200>; --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2FB13D3305; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=grKVARM/NlBuO/KeXwyZdz6YJB4puqJmPMlx5Jtvkkf4CZo3QdAAex7WHriJ2Q7GNQZuE3etcWp1SwfkeVLZidsHwz3R6k4Uks5txQCw8T8MrJuwT7wZtHyNZdDyjvazkc5Ht9itcEGl+MA/x5wAr82UM1ncdcTs43YXiY9aApc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=yCkOmBaR5nil6EWh+gg1vqFVc4hjJ7N+uufRHhr7jwc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rcDtgMzHC+pC+j8DYhu3nU0QOUUg0RR+RgpCfcapyC6WUnwFHu9C4In+YVzlzalS0k7H+qJAKmlqhLvEFGzg1iUcP555PA9txLvPGah2fSDxSL6kupvLxGFTUSfOWF+qB5On0qXtNf1wm3pYr2ybQcmoan+B4tWVh4elcLoUosI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XurR2UW/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XurR2UW/" Received: by smtp.kernel.org (Postfix) with ESMTPS id 97D06C2BCFF; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=yCkOmBaR5nil6EWh+gg1vqFVc4hjJ7N+uufRHhr7jwc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=XurR2UW/SAiJf7jSfEB1+y4Uwm7Pd9pIcVDA+YQqEsZJGwONaXo3bzY0P3i1v2pft RDmNvAsVOo9alwQ54l3XLDRhMPvOtOIldzq9BqNmpGyV47kZWMn8C+HqnU3gCGZpxo hDXpkdtq3fnxh1IGzB1uU1aOQvL9Nahh4VRTvos9HaPXj3bigFQmRSchXEUHtFy8P3 UBDAGl7iZQtuTsR71doP+fO8nceZn3GzczedCNrhT1117od4xSr2j5S9+733Fk9u0W 6a7+dIn1+drFSo7oIy1PVG9INRHETAEdtLu+P3sNIPISDHNv7X15T4VcYpujDn59HY wr07RwQLrBCwg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86AE3C79FA3; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:44 +0200 Subject: [PATCH v2 21/22] arm64: dts: apple: t8112: Add USB4 ACIO and NHI 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-21-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=10505; i=sven@kernel.org; h=from:subject:message-id; bh=yCkOmBaR5nil6EWh+gg1vqFVc4hjJ7N+uufRHhr7jwc=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTWe3bLoX8SFp0buN0X4LP5nz/D1bqfjsfMH+XLGbz yyazky62VHKwiDGxSArpsiyfb+96ZOHbwSXbrr0HmYOKxPIEAYuTgGYiOImRoaHvAncd4/Jylc7 6upKtG39u1z40oW+9TLHEqzO/34k872O4X+m2s6fe08dCsz9sGmrY3jhbbbeZdej4/++8ajNvh9 fcYsXAA== X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 Add the ACIO host router, NHI, DART and mailbox nodes for both Type-C ports on t8112 and connect the host routers to the Type-C connectors. Also describe the USB3 path from each host router to its DWC3 controller so the NHI driver can create the required device link. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- arch/arm64/boot/dts/apple/t8112-jxxx.dtsi | 95 ++++++++++++++- arch/arm64/boot/dts/apple/t8112.dtsi | 186 ++++++++++++++++++++++++++= ++++ 2 files changed, 279 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi b/arch/arm64/boot/dt= s/apple/t8112-jxxx.dtsi index 562e7a25a1e8..d0dc7eaaca35 100644 --- a/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8112-jxxx.dtsi @@ -13,6 +13,10 @@ / { aliases { atcphy0 =3D &atcphy0; atcphy1 =3D &atcphy1; + usb4-0-acio =3D &usb4_0_acio; + usb4-0-nhi =3D &usb4_0_nhi; + usb4-1-acio =3D &usb4_1_acio; + usb4-1-nhi =3D &usb4_1_nhi; serial0 =3D &serial0; serial2 =3D &serial2; }; @@ -76,6 +80,13 @@ typec0_connector_ss: endpoint { remote-endpoint =3D <&atcphy0_typec_lanes>; }; }; + + port@2 { + reg =3D <2>; + typec0_con_tbt: endpoint { + remote-endpoint =3D <&usb4_0_acio_tbt>; + }; + }; }; }; }; @@ -107,6 +118,13 @@ typec1_connector_ss: endpoint { remote-endpoint =3D <&atcphy1_typec_lanes>; }; }; + + port@2 { + reg =3D <2>; + typec1_con_tbt: endpoint { + remote-endpoint =3D <&usb4_1_acio_tbt>; + }; + }; }; }; }; @@ -126,10 +144,19 @@ dwc3_0_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_0_ss: endpoint { + + dwc3_0_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy0_usb3>; }; + + dwc3_0_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_0_acio_usb3>; + }; }; }; }; @@ -147,10 +174,19 @@ dwc3_1_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_1_ss: endpoint { + + dwc3_1_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy1_usb3>; }; + + dwc3_1_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_1_acio_usb3>; + }; }; }; }; @@ -198,6 +234,61 @@ atcphy1_usb3: endpoint { }; }; =20 +/* USB4 */ +&usb4_0_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_0_acio_tbt: endpoint { + remote-endpoint =3D <&typec0_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_0_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_0_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_1_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_1_acio_tbt: endpoint { + remote-endpoint =3D <&typec1_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_1_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_1_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + &i2c1 { status =3D "okay"; }; diff --git a/arch/arm64/boot/dts/apple/t8112.dtsi b/arch/arm64/boot/dts/app= le/t8112.dtsi index 2c3b59e05e01..e70ed4a470e1 100644 --- a/arch/arm64/boot/dts/apple/t8112.dtsi +++ b/arch/arm64/boot/dts/apple/t8112.dtsi @@ -991,6 +991,14 @@ pinctrl_aop: pinctrl@24a820000 { , , ; + + acio0_pins: acio0-pins { + pinmux =3D ; + }; + + acio1_pins: acio1-pins { + pinmux =3D ; + }; }; =20 ans_mbox: mbox@277408000 { @@ -1027,6 +1035,95 @@ nvme@27bcc0000 { resets =3D <&ps_ans>; }; =20 + usb4_0_mbox: mailbox@381108000 { + compatible =3D "apple,t8112-asc-mailbox", + "apple,asc-mailbox-v4"; + reg =3D <0x3 0x81108000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + usb4_0_acio: cio@381ac0000 { + compatible =3D "apple,t8112-usb4-acio", "apple,t8103-usb4-acio"; + reg =3D <0x3 0x81ac0000 0x0 0xc000>, + <0x3 0x81080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&usb4_0_mbox>; + resets =3D <&cio_reset 0>; + + power-domains =3D <&ps_atc0_cio>, + <&ps_atc0_cio_pcie>, + <&ps_atc0_cio_usb>; + + pinctrl-0 =3D <&acio0_pins>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0x3 0x81000000 0x1000000>; + nonposted-mmio; + + usb4_0_dart: iommu@a80000 { + compatible =3D "apple,t8110-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + }; + + usb4_0_nhi: nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t8112-usb4-nhi", + "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&usb4_0_dart 1>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + dwc3_0: usb@382280000 { compatible =3D "apple,t8112-dwc3", "apple,t8103-dwc3"; reg =3D <0x3 0x82280000 0x0 0xcd00>, <0x3 0x8228cd00 0x0 0x3200>; @@ -1079,6 +1176,95 @@ atcphy0: phy@383000000 { power-domains =3D <&ps_atc0_usb>; }; =20 + usb4_1_mbox: mailbox@501108000 { + compatible =3D "apple,t8112-asc-mailbox", + "apple,asc-mailbox-v4"; + reg =3D <0x5 0x01108000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + usb4_1_acio: cio@501ac0000 { + compatible =3D "apple,t8112-usb4-acio", "apple,t8103-usb4-acio"; + reg =3D <0x5 0x01ac0000 0x0 0xc000>, + <0x5 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&usb4_1_mbox>; + resets =3D <&cio_reset 1>; + + power-domains =3D <&ps_atc1_cio>, + <&ps_atc1_cio_pcie>, + <&ps_atc1_cio_usb>; + + pinctrl-0 =3D <&acio1_pins>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0x5 0x01000000 0x1000000>; + nonposted-mmio; + + usb4_1_dart: iommu@a80000 { + compatible =3D "apple,t8110-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + }; + + usb4_1_nhi: nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t8112-usb4-nhi", + "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&usb4_1_dart 1>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + dwc3_1: usb@502280000 { compatible =3D "apple,t8112-dwc3", "apple,t8103-dwc3"; reg =3D <0x5 0x02280000 0x0 0xcd00>, <0x5 0x0228cd00 0x0 0x3200>; --=20 2.55.0 From nobody Sat Sep 26 01:05:02 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C93023D3CED; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; cv=none; b=ePbrpVXqCGr3rSvgxfl6Gk3z9wyz8ykxGXLzK38Wi2FNXXlJokr9N0t7X8jSjnRVDRlTaLG/2jvm/EtDQnEaCH9SxF+GJaSD8UNmey0ywnph+UUHDvx+ryTw2yjYDw2S+GUYCS6b18RI1UtutZjblEoacQwPXsbhekUKRqpcxEk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788719828; c=relaxed/simple; bh=X87Bo5nHz82LjOFPhHoCnms1F5YSIAAbuWhYyJ3Rjmg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZJUQnRPc1huaRkTl6iqqT3gBmqf4qCPKbcw+GHy/tms7PLXfo8tB70IjwDcVUYVcOispNK8A2OFOwh6/cbnE8sAHActUdlbO5LAcRufs3GqYLleCrx6aRX+h/8WrX8L5+Oi196DPuQPmFdpw5UNEVgc/V/VnEUi3X4fdYo8NJZo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GonzylF+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GonzylF+" Received: by smtp.kernel.org (Postfix) with ESMTPS id AC3F5C2BCF5; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788719828; bh=X87Bo5nHz82LjOFPhHoCnms1F5YSIAAbuWhYyJ3Rjmg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GonzylF+A/fy22iLCiYRY22B3ItU8BhJluPL3MZjolQ/m1ah1tu5uFtulxkxQKaHh BDntYOTi2TysSQ5CTg2zye43irbpeAGteDzzLepF9TZtsm1D20gmmxQ6RmsFvSQP7s 1vjjLp28zpipEXXCzlCW+9R926ST3EWItr9ODRqKK06SM6hMa/yYJUq1mmkZnC5Wt8 09CYs79WikDNaoAwP+pfIWdPFg8SBh8o8JM9FleEloBaQtnWYidqgwO8k+53mIcZC2 y+Cw6DCSGtD6x7hjA0zwSzKwZ6c4YMO0T6CLVW+mnNjVFuv8qNK5HxZyZVsBiYIt9O P69ylGOFoN5ag== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A567C79FA1; Sun, 6 Sep 2026 18:37:08 +0000 (UTC) From: Sven Peter Date: Sun, 06 Sep 2026 20:36:45 +0200 Subject: [PATCH v2 22/22] arm64: dts: apple: t60xx: Add USB4 ACIO and NHI 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 Message-Id: <20260906-b4-apple-soc-tbt-v2-22-1f80085f93fb@kernel.org> References: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> In-Reply-To: <20260906-b4-apple-soc-tbt-v2-0-1f80085f93fb@kernel.org> To: Heikki Krogerus , Greg Kroah-Hartman , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Janne Grunau , Neal Gompa , Andreas Noever , Mika Westerberg , Yehezkel Bernat , Philipp Zabel Cc: Konrad Dybcio , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Sven Peter X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=53817; i=sven@kernel.org; h=from:subject:message-id; bh=X87Bo5nHz82LjOFPhHoCnms1F5YSIAAbuWhYyJ3Rjmg=; b=owGbwMvMwCXmIlirolUq95LxtFoSQ9bcTeclTv6ZmN6fc6LP4qFKI4vHI0aT2ZeSGF3PdLYfv vzhmN/LjlIWBjEuBlkxRZbt++1Nnzx8I7h006X3MHNYmUCGMHBxCsBEYpkYGY60F+pc9OZc6fTD TPzw+1thipJvHvnezjMOsXY8PyH001GGf9o9e59nS9RskQpsnmkWsflXVkGeEceN1Kwy9XON653 9uQA= X-Developer-Key: i=sven@kernel.org; a=openpgp; fpr=A1E3E34A2B3C820DBC4955E5993B08092F131F93 X-Endpoint-Received: by B4 Relay for sven@kernel.org/default with auth_id=407 Add the ACIO host router, NHI, DART and mailbox nodes for the four ATC instances on each t600x and t602x die and connect the host routers to the Type-C connectors on the MacBook Pro (j314/j316 and j414/j416), Mac Studio (j375 and j475), Mac mini (j474) and Mac Pro (j180d) boards. Also describe the USB3 path from each host router to its DWC3 controller so the NHI driver can create the required device link. Signed-off-by: Sven Peter Reviewed-by: Joshua Peisach --- arch/arm64/boot/dts/apple/t6002-j375d.dts | 101 ++++++- arch/arm64/boot/dts/apple/t600x-dieX.dtsi | 376 +++++++++++++++++++++= ++++ arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi | 158 ++++++++++- arch/arm64/boot/dts/apple/t600x-j375.dtsi | 205 +++++++++++++- arch/arm64/boot/dts/apple/t6022-j180d.dts | 304 +++++++++++++++++++- arch/arm64/boot/dts/apple/t6022-j475d.dts | 10 + arch/arm64/boot/dts/apple/t6022-jxxxd.dtsi | 91 +++++- arch/arm64/boot/dts/apple/t602x-dieX.dtsi | 376 +++++++++++++++++++++= ++++ 8 files changed, 1604 insertions(+), 17 deletions(-) diff --git a/arch/arm64/boot/dts/apple/t6002-j375d.dts b/arch/arm64/boot/dt= s/apple/t6002-j375d.dts index e6eb6b6c386d..93f07df1c006 100644 --- a/arch/arm64/boot/dts/apple/t6002-j375d.dts +++ b/arch/arm64/boot/dts/apple/t6002-j375d.dts @@ -18,6 +18,10 @@ / { aliases { atcphy4 =3D &atcphy0_die1; atcphy5 =3D &atcphy1_die1; + usb4-4-acio =3D &usb4_0_acio_die1; + usb4-4-nhi =3D &usb4_0_nhi_die1; + usb4-5-acio =3D &usb4_1_acio_die1; + usb4-5-nhi =3D &usb4_1_nhi_die1; }; }; =20 @@ -52,6 +56,13 @@ typec4_connector_ss: endpoint { remote-endpoint =3D <&atcphy4_typec_lanes>; }; }; + + port@2 { + reg =3D <2>; + typec4_con_tbt: endpoint { + remote-endpoint =3D <&usb4_4_acio_tbt>; + }; + }; }; }; }; @@ -85,6 +96,13 @@ typec5_connector_ss: endpoint { remote-endpoint =3D <&atcphy5_typec_lanes>; }; }; + + port@2 { + reg =3D <2>; + typec5_con_tbt: endpoint { + remote-endpoint =3D <&usb4_5_acio_tbt>; + }; + }; }; }; }; @@ -112,10 +130,19 @@ dwc3_4_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_4_ss: endpoint { + + dwc3_4_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy4_usb3>; }; + + dwc3_4_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_4_acio_usb3>; + }; }; }; }; @@ -133,10 +160,19 @@ dwc3_5_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_5_ss: endpoint { + + dwc3_5_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy5_usb3>; }; + + dwc3_5_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_5_acio_usb3>; + }; }; }; }; @@ -186,8 +222,69 @@ atcphy5_usb3: endpoint { =20 #include "hwmon-fan-dual.dtsi" =20 +/* USB4 on die 1 */ +&usb4_0_acio_die1 { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_4_acio_tbt: endpoint { + remote-endpoint =3D <&typec4_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_4_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_4_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_1_acio_die1 { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_5_acio_tbt: endpoint { + remote-endpoint =3D <&typec5_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_5_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_5_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + /* delete unused USB nodes on die 1 */ =20 +/delete-node/ &usb4_2_acio_die1; +/delete-node/ &usb4_2_mbox_die1; + +/delete-node/ &usb4_3_acio_die1; +/delete-node/ &usb4_3_mbox_die1; + /delete-node/ &dwc3_2_dart_0_die1; /delete-node/ &dwc3_2_dart_1_die1; /delete-node/ &dwc3_2_die1; diff --git a/arch/arm64/boot/dts/apple/t600x-dieX.dtsi b/arch/arm64/boot/dt= s/apple/t600x-dieX.dtsi index 5e163d756a7f..b7ef3321b57d 100644 --- a/arch/arm64/boot/dts/apple/t600x-dieX.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-dieX.dtsi @@ -99,6 +99,22 @@ DIE_NODE(pinctrl_aop): pinctrl@293820000 { , , ; + + DIE_NODE(acio0_pins): acio0-pins { + pinmux =3D ; + }; + + DIE_NODE(acio1_pins): acio1-pins { + pinmux =3D ; + }; + + DIE_NODE(acio2_pins): acio2-pins { + pinmux =3D ; + }; + + DIE_NODE(acio3_pins): acio3-pins { + pinmux =3D ; + }; }; =20 DIE_NODE(pinctrl_ap): pinctrl@39b028000 { @@ -126,6 +142,96 @@ DIE_NODE(pinctrl_ap): pinctrl@39b028000 { #interrupt-cells =3D <2>; }; =20 + DIE_NODE(usb4_0_mbox): mailbox@701100000 { + compatible =3D "apple,t6000-m3-mailbox", + "apple,m3-mailbox-v2"; + reg =3D <0x7 0x01100000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + DIE_NODE(usb4_0_acio): cio@701ac0000 { + compatible =3D "apple,t6000-usb4-acio", "apple,t8103-usb4-acio"; + reg =3D <0x7 0x01ac0000 0x0 0xc000>, + <0x7 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&DIE_NODE(usb4_0_mbox)>; + resets =3D <&DIE_NODE(cio_reset) 0>; + + power-domains =3D <&DIE_NODE(ps_atc0_cio)>, + <&DIE_NODE(ps_atc0_cio_pcie)>, + <&DIE_NODE(ps_atc0_cio_usb)>; + + pinctrl-0 =3D <&DIE_NODE(acio0_pins)>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0x7 0x01000000 0x1000000>; + nonposted-mmio; + + DIE_NODE(usb4_0_dart): iommu@a80000 { + compatible =3D "apple,t6000-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + }; + + DIE_NODE(usb4_0_nhi): nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t6000-usb4-nhi", + "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&DIE_NODE(usb4_0_dart) 1>, + <&DIE_NODE(usb4_0_dart) 2>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + DIE_NODE(dwc3_0): usb@702280000 { compatible =3D "apple,t6000-dwc3", "apple,t8103-dwc3"; reg =3D <0x7 0x02280000 0x0 0xcd00>, <0x7 0x0228cd00 0x0 0x3200>; @@ -179,6 +285,96 @@ DIE_NODE(atcphy0): phy@703000000 { power-domains =3D <&DIE_NODE(ps_atc0_usb)>; }; =20 + DIE_NODE(usb4_1_mbox): mailbox@b01100000 { + compatible =3D "apple,t6000-m3-mailbox", + "apple,m3-mailbox-v2"; + reg =3D <0xb 0x01100000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + DIE_NODE(usb4_1_acio): cio@b01ac0000 { + compatible =3D "apple,t6000-usb4-acio", "apple,t8103-usb4-acio"; + reg =3D <0xb 0x01ac0000 0x0 0xc000>, + <0xb 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&DIE_NODE(usb4_1_mbox)>; + resets =3D <&DIE_NODE(cio_reset) 1>; + + power-domains =3D <&DIE_NODE(ps_atc1_cio)>, + <&DIE_NODE(ps_atc1_cio_pcie)>, + <&DIE_NODE(ps_atc1_cio_usb)>; + + pinctrl-0 =3D <&DIE_NODE(acio1_pins)>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0xb 0x01000000 0x1000000>; + nonposted-mmio; + + DIE_NODE(usb4_1_dart): iommu@a80000 { + compatible =3D "apple,t6000-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + }; + + DIE_NODE(usb4_1_nhi): nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t6000-usb4-nhi", + "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&DIE_NODE(usb4_1_dart) 1>, + <&DIE_NODE(usb4_1_dart) 2>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + DIE_NODE(dwc3_1): usb@b02280000 { compatible =3D "apple,t6000-dwc3", "apple,t8103-dwc3"; reg =3D <0xb 0x02280000 0x0 0xcd00>, <0xb 0x0228cd00 0x0 0x3200>; @@ -232,6 +428,96 @@ DIE_NODE(atcphy1): phy@b03000000 { power-domains =3D <&DIE_NODE(ps_atc1_usb)>; }; =20 + DIE_NODE(usb4_2_mbox): mailbox@f01100000 { + compatible =3D "apple,t6000-m3-mailbox", + "apple,m3-mailbox-v2"; + reg =3D <0xf 0x01100000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + DIE_NODE(usb4_2_acio): cio@f01ac0000 { + compatible =3D "apple,t6000-usb4-acio", "apple,t8103-usb4-acio"; + reg =3D <0xf 0x01ac0000 0x0 0xc000>, + <0xf 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&DIE_NODE(usb4_2_mbox)>; + resets =3D <&DIE_NODE(cio_reset) 2>; + + power-domains =3D <&DIE_NODE(ps_atc2_cio)>, + <&DIE_NODE(ps_atc2_cio_pcie)>, + <&DIE_NODE(ps_atc2_cio_usb)>; + + pinctrl-0 =3D <&DIE_NODE(acio2_pins)>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0xf 0x01000000 0x1000000>; + nonposted-mmio; + + DIE_NODE(usb4_2_dart): iommu@a80000 { + compatible =3D "apple,t6000-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + }; + + DIE_NODE(usb4_2_nhi): nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t6000-usb4-nhi", + "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&DIE_NODE(usb4_2_dart) 1>, + <&DIE_NODE(usb4_2_dart) 2>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + DIE_NODE(dwc3_2): usb@f02280000 { compatible =3D "apple,t6000-dwc3", "apple,t8103-dwc3"; reg =3D <0xf 0x02280000 0x0 0xcd00>, <0xf 0x0228cd00 0x0 0x3200>; @@ -285,6 +571,96 @@ DIE_NODE(atcphy2): phy@f03000000 { power-domains =3D <&DIE_NODE(ps_atc2_usb)>; }; =20 + DIE_NODE(usb4_3_mbox): mailbox@1301100000 { + compatible =3D "apple,t6000-m3-mailbox", + "apple,m3-mailbox-v2"; + reg =3D <0x13 0x01100000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + DIE_NODE(usb4_3_acio): cio@1301ac0000 { + compatible =3D "apple,t6000-usb4-acio", "apple,t8103-usb4-acio"; + reg =3D <0x13 0x01ac0000 0x0 0xc000>, + <0x13 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&DIE_NODE(usb4_3_mbox)>; + resets =3D <&DIE_NODE(cio_reset) 3>; + + power-domains =3D <&DIE_NODE(ps_atc3_cio)>, + <&DIE_NODE(ps_atc3_cio_pcie)>, + <&DIE_NODE(ps_atc3_cio_usb)>; + + pinctrl-0 =3D <&DIE_NODE(acio3_pins)>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0x13 0x01000000 0x1000000>; + nonposted-mmio; + + DIE_NODE(usb4_3_dart): iommu@a80000 { + compatible =3D "apple,t6000-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + }; + + DIE_NODE(usb4_3_nhi): nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t6000-usb4-nhi", + "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&DIE_NODE(usb4_3_dart) 1>, + <&DIE_NODE(usb4_3_dart) 2>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + DIE_NODE(dwc3_3): usb@1302280000 { compatible =3D "apple,t6000-dwc3", "apple,t8103-dwc3"; reg =3D <0x13 0x02280000 0x0 0xcd00>, <0x13 0x0228cd00 0x0 0x3200>; diff --git a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi b/arch/arm64/bo= ot/dts/apple/t600x-j314-j316.dtsi index caded1636f3d..8287e2c0eb84 100644 --- a/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-j314-j316.dtsi @@ -21,6 +21,12 @@ aliases { atcphy3 =3D &atcphy3; bluetooth0 =3D &bluetooth0; serial0 =3D &serial0; + usb4-0-acio =3D &usb4_0_acio; + usb4-0-nhi =3D &usb4_0_nhi; + usb4-1-acio =3D &usb4_1_acio; + usb4-1-nhi =3D &usb4_1_nhi; + usb4-2-acio =3D &usb4_2_acio; + usb4-2-nhi =3D &usb4_2_nhi; wifi0 =3D &wifi0; }; =20 @@ -222,10 +228,19 @@ dwc3_0_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_0_ss: endpoint { + + dwc3_0_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy0_usb3>; }; + + dwc3_0_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_0_acio_usb3>; + }; }; }; }; @@ -243,10 +258,19 @@ dwc3_1_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_1_ss: endpoint { + + dwc3_1_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy1_usb3>; }; + + dwc3_1_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_1_acio_usb3>; + }; }; }; }; @@ -264,10 +288,19 @@ dwc3_2_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_2_ss: endpoint { + + dwc3_2_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy2_usb3>; }; + + dwc3_2_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_2_acio_usb3>; + }; }; }; }; @@ -366,6 +399,125 @@ &atcphy3 { status =3D "disabled"; }; =20 +&typec0 { + ports { + port@2 { + reg =3D <2>; + typec0_con_tbt: endpoint { + remote-endpoint =3D <&usb4_0_acio_tbt>; + }; + }; + }; +}; + +&typec1 { + ports { + port@2 { + reg =3D <2>; + typec1_con_tbt: endpoint { + remote-endpoint =3D <&usb4_1_acio_tbt>; + }; + }; + }; +}; + +&typec2 { + ports { + port@2 { + reg =3D <2>; + typec2_con_tbt: endpoint { + remote-endpoint =3D <&usb4_2_acio_tbt>; + }; + }; + }; +}; + +/* USB4 */ +&usb4_0_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_0_acio_tbt: endpoint { + remote-endpoint =3D <&typec0_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_0_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_0_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_1_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_1_acio_tbt: endpoint { + remote-endpoint =3D <&typec1_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_1_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_1_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_2_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_2_acio_tbt: endpoint { + remote-endpoint =3D <&typec2_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_2_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_2_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +/* ATC3 is used for DP-to-HDMI only and has no USB4 host router */ +/delete-node/ &usb4_3_acio; +/delete-node/ &usb4_3_mbox; + #include "spi1-nvram.dtsi" #include "hwmon-laptop.dtsi" #include "hwmon-fan-dual.dtsi" diff --git a/arch/arm64/boot/dts/apple/t600x-j375.dtsi b/arch/arm64/boot/dt= s/apple/t600x-j375.dtsi index 8a1494949e4c..18348192d143 100644 --- a/arch/arm64/boot/dts/apple/t600x-j375.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-j375.dtsi @@ -20,6 +20,14 @@ aliases { bluetooth0 =3D &bluetooth0; ethernet0 =3D ðernet0; serial0 =3D &serial0; + usb4-0-acio =3D &usb4_0_acio; + usb4-0-nhi =3D &usb4_0_nhi; + usb4-1-acio =3D &usb4_1_acio; + usb4-1-nhi =3D &usb4_1_nhi; + usb4-2-acio =3D &usb4_2_acio; + usb4-2-nhi =3D &usb4_2_nhi; + usb4-3-acio =3D &usb4_3_acio; + usb4-3-nhi =3D &usb4_3_nhi; wifi0 =3D &wifi0; }; =20 @@ -193,10 +201,19 @@ dwc3_0_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_0_ss: endpoint { + + dwc3_0_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy0_usb3>; }; + + dwc3_0_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_0_acio_usb3>; + }; }; }; }; @@ -214,10 +231,19 @@ dwc3_1_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_1_ss: endpoint { + + dwc3_1_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy1_usb3>; }; + + dwc3_1_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_1_acio_usb3>; + }; }; }; }; @@ -235,10 +261,19 @@ dwc3_2_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_2_ss: endpoint { + + dwc3_2_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy2_usb3>; }; + + dwc3_2_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_2_acio_usb3>; + }; }; }; }; @@ -256,10 +291,19 @@ dwc3_3_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_3_ss: endpoint { + + dwc3_3_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy3_usb3>; }; + + dwc3_3_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_3_acio_usb3>; + }; }; }; }; @@ -410,4 +454,157 @@ &pcie0_dart_3 { status =3D "okay"; }; =20 +&typec0 { + ports { + port@2 { + reg =3D <2>; + typec0_con_tbt: endpoint { + remote-endpoint =3D <&usb4_0_acio_tbt>; + }; + }; + }; +}; + +&typec1 { + ports { + port@2 { + reg =3D <2>; + typec1_con_tbt: endpoint { + remote-endpoint =3D <&usb4_1_acio_tbt>; + }; + }; + }; +}; + +&typec2 { + ports { + port@2 { + reg =3D <2>; + typec2_con_tbt: endpoint { + remote-endpoint =3D <&usb4_2_acio_tbt>; + }; + }; + }; +}; + +&typec3 { + ports { + port@2 { + reg =3D <2>; + typec3_con_tbt: endpoint { + remote-endpoint =3D <&usb4_3_acio_tbt>; + }; + }; + }; +}; + +/* USB4 */ +&usb4_0_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_0_acio_tbt: endpoint { + remote-endpoint =3D <&typec0_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_0_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_0_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_1_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_1_acio_tbt: endpoint { + remote-endpoint =3D <&typec1_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_1_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_1_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_2_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_2_acio_tbt: endpoint { + remote-endpoint =3D <&typec2_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_2_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_2_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_3_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_3_acio_tbt: endpoint { + remote-endpoint =3D <&typec3_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_3_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_3_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + #include "spi1-nvram.dtsi" diff --git a/arch/arm64/boot/dts/apple/t6022-j180d.dts b/arch/arm64/boot/dt= s/apple/t6022-j180d.dts index f76b887429dd..1ddde77e00c0 100644 --- a/arch/arm64/boot/dts/apple/t6022-j180d.dts +++ b/arch/arm64/boot/dts/apple/t6022-j180d.dts @@ -26,6 +26,22 @@ aliases { atcphy5 =3D &atcphy1_die1; atcphy6 =3D &atcphy2_die1; atcphy7 =3D &atcphy3_die1; + usb4-0-acio =3D &usb4_0_acio; + usb4-0-nhi =3D &usb4_0_nhi; + usb4-1-acio =3D &usb4_1_acio; + usb4-1-nhi =3D &usb4_1_nhi; + usb4-2-acio =3D &usb4_2_acio; + usb4-2-nhi =3D &usb4_2_nhi; + usb4-3-acio =3D &usb4_3_acio; + usb4-3-nhi =3D &usb4_3_nhi; + usb4-4-acio =3D &usb4_0_acio_die1; + usb4-4-nhi =3D &usb4_0_nhi_die1; + usb4-5-acio =3D &usb4_1_acio_die1; + usb4-5-nhi =3D &usb4_1_nhi_die1; + usb4-6-acio =3D &usb4_2_acio_die1; + usb4-6-nhi =3D &usb4_2_nhi_die1; + usb4-7-acio =3D &usb4_3_acio_die1; + usb4-7-nhi =3D &usb4_3_nhi_die1; nvram =3D &nvram; serial0 =3D &serial0; }; @@ -152,6 +168,13 @@ typec6_connector_ss: endpoint { remote-endpoint =3D <&atcphy6_typec_lanes>; }; }; + + port@2 { + reg =3D <2>; + typec6_con_tbt: endpoint { + remote-endpoint =3D <&usb4_6_acio_tbt>; + }; + }; }; }; }; @@ -184,6 +207,13 @@ typec7_connector_ss: endpoint { remote-endpoint =3D <&atcphy7_typec_lanes>; }; }; + + port@2 { + reg =3D <2>; + typec7_con_tbt: endpoint { + remote-endpoint =3D <&usb4_7_acio_tbt>; + }; + }; }; }; }; @@ -280,10 +310,19 @@ dwc3_0_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_0_ss: endpoint { + + dwc3_0_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy0_usb3>; }; + + dwc3_0_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_0_acio_usb3>; + }; }; }; }; @@ -301,10 +340,19 @@ dwc3_1_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_1_ss: endpoint { + + dwc3_1_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy1_usb3>; }; + + dwc3_1_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_1_acio_usb3>; + }; }; }; }; @@ -322,10 +370,19 @@ dwc3_2_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_2_ss: endpoint { + + dwc3_2_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy2_usb3>; }; + + dwc3_2_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_2_acio_usb3>; + }; }; }; }; @@ -343,10 +400,19 @@ dwc3_3_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_3_ss: endpoint { + + dwc3_3_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy3_usb3>; }; + + dwc3_3_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_3_acio_usb3>; + }; }; }; }; @@ -365,10 +431,19 @@ dwc3_6_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_6_ss: endpoint { + + dwc3_6_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy6_usb3>; }; + + dwc3_6_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_6_acio_usb3>; + }; }; }; }; @@ -386,10 +461,19 @@ dwc3_7_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_7_ss: endpoint { + + dwc3_7_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy7_usb3>; }; + + dwc3_7_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_7_acio_usb3>; + }; }; }; }; @@ -535,4 +619,212 @@ &nco_clkref { clock-frequency =3D <1068000000>; }; =20 +/* USB4 on die 1 */ +&usb4_2_acio_die1 { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_6_acio_tbt: endpoint { + remote-endpoint =3D <&typec6_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_6_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_6_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_3_acio_die1 { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_7_acio_tbt: endpoint { + remote-endpoint =3D <&typec7_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_7_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_7_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&typec0 { + ports { + port@2 { + reg =3D <2>; + typec0_con_tbt: endpoint { + remote-endpoint =3D <&usb4_0_acio_tbt>; + }; + }; + }; +}; + +&typec1 { + ports { + port@2 { + reg =3D <2>; + typec1_con_tbt: endpoint { + remote-endpoint =3D <&usb4_1_acio_tbt>; + }; + }; + }; +}; + +&typec2 { + ports { + port@2 { + reg =3D <2>; + typec2_con_tbt: endpoint { + remote-endpoint =3D <&usb4_2_acio_tbt>; + }; + }; + }; +}; + +&typec3 { + ports { + port@2 { + reg =3D <2>; + typec3_con_tbt: endpoint { + remote-endpoint =3D <&usb4_3_acio_tbt>; + }; + }; + }; +}; + +/* USB4 */ +&usb4_0_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_0_acio_tbt: endpoint { + remote-endpoint =3D <&typec0_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_0_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_0_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_1_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_1_acio_tbt: endpoint { + remote-endpoint =3D <&typec1_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_1_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_1_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_2_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_2_acio_tbt: endpoint { + remote-endpoint =3D <&typec2_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_2_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_2_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_3_acio { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_3_acio_tbt: endpoint { + remote-endpoint =3D <&typec3_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_3_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_3_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + #include "spi1-nvram.dtsi" diff --git a/arch/arm64/boot/dts/apple/t6022-j475d.dts b/arch/arm64/boot/dt= s/apple/t6022-j475d.dts index 32938a3bf96a..d99633160beb 100644 --- a/arch/arm64/boot/dts/apple/t6022-j475d.dts +++ b/arch/arm64/boot/dts/apple/t6022-j475d.dts @@ -20,6 +20,10 @@ / { aliases { atcphy4 =3D &atcphy0_die1; atcphy5 =3D &atcphy1_die1; + usb4-4-acio =3D &usb4_0_acio_die1; + usb4-4-nhi =3D &usb4_0_nhi_die1; + usb4-5-acio =3D &usb4_1_acio_die1; + usb4-5-nhi =3D &usb4_1_nhi_die1; }; }; =20 @@ -57,6 +61,12 @@ &typec5 { /delete-node/ &dwc3_3_die1; /delete-node/ &atcphy3_die1; =20 +/delete-node/ &usb4_2_acio_die1; +/delete-node/ &usb4_2_mbox_die1; + +/delete-node/ &usb4_3_acio_die1; +/delete-node/ &usb4_3_mbox_die1; + /* delete unused always-on power-domains on die 1 */ /delete-node/ &ps_atc2_usb_aon_die1; /delete-node/ &ps_atc2_usb_die1; diff --git a/arch/arm64/boot/dts/apple/t6022-jxxxd.dtsi b/arch/arm64/boot/d= ts/apple/t6022-jxxxd.dtsi index dc877bd604f8..6a3e866f83be 100644 --- a/arch/arm64/boot/dts/apple/t6022-jxxxd.dtsi +++ b/arch/arm64/boot/dts/apple/t6022-jxxxd.dtsi @@ -46,6 +46,13 @@ typec4_connector_ss: endpoint { remote-endpoint =3D <&atcphy4_typec_lanes>; }; }; + + port@2 { + reg =3D <2>; + typec4_con_tbt: endpoint { + remote-endpoint =3D <&usb4_4_acio_tbt>; + }; + }; }; }; }; @@ -78,6 +85,13 @@ typec5_connector_ss: endpoint { remote-endpoint =3D <&atcphy5_typec_lanes>; }; }; + + port@2 { + reg =3D <2>; + typec5_con_tbt: endpoint { + remote-endpoint =3D <&usb4_5_acio_tbt>; + }; + }; }; }; }; @@ -98,10 +112,19 @@ dwc3_4_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_4_ss: endpoint { + + dwc3_4_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy4_usb3>; }; + + dwc3_4_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_4_acio_usb3>; + }; }; }; }; @@ -119,10 +142,19 @@ dwc3_5_hs: endpoint { }; =20 port@1 { + #address-cells =3D <1>; + #size-cells =3D <0>; reg =3D <1>; - dwc3_5_ss: endpoint { + + dwc3_5_ss: endpoint@0 { + reg =3D <0>; remote-endpoint =3D <&atcphy5_usb3>; }; + + dwc3_5_usb4: endpoint@1 { + reg =3D <1>; + remote-endpoint =3D <&usb4_5_acio_usb3>; + }; }; }; }; @@ -169,3 +201,58 @@ atcphy5_usb3: endpoint { }; }; }; + +/* USB4 on die 1 */ +&usb4_0_acio_die1 { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_4_acio_tbt: endpoint { + remote-endpoint =3D <&typec4_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_4_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_4_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; + +&usb4_1_acio_die1 { + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + /* 1: USB4 port */ + port@1 { + reg =3D <1>; + usb4_5_acio_tbt: endpoint { + remote-endpoint =3D <&typec5_con_tbt>; + }; + }; + + /* 2: USB4 lane 1 adapter */ + /* 3: PCIe */ + port@4 { + reg =3D <4>; + usb4_5_acio_usb3: endpoint { + remote-endpoint =3D <&dwc3_5_usb4>; + }; + }; + + /* 5: DP0 */ + /* 6: DP1 */ + }; +}; diff --git a/arch/arm64/boot/dts/apple/t602x-dieX.dtsi b/arch/arm64/boot/dt= s/apple/t602x-dieX.dtsi index fd4d572a04e7..1fba52e38ad8 100644 --- a/arch/arm64/boot/dts/apple/t602x-dieX.dtsi +++ b/arch/arm64/boot/dts/apple/t602x-dieX.dtsi @@ -98,6 +98,22 @@ DIE_NODE(pinctrl_aop): pinctrl@2a6820000 { , , ; + + DIE_NODE(acio0_pins): acio0-pins { + pinmux =3D ; + }; + + DIE_NODE(acio1_pins): acio1-pins { + pinmux =3D ; + }; + + DIE_NODE(acio2_pins): acio2-pins { + pinmux =3D ; + }; + + DIE_NODE(acio3_pins): acio3-pins { + pinmux =3D ; + }; }; =20 DIE_NODE(pinctrl_ap): pinctrl@39b028000 { @@ -133,6 +149,96 @@ DIE_NODE(pmgr_gfx): power-management@404e80000 { reg =3D <0x4 0x4e80000 0 0x4000>; }; =20 + DIE_NODE(usb4_0_mbox): mailbox@701108000 { + compatible =3D "apple,t6020-asc-mailbox", + "apple,asc-mailbox-v4"; + reg =3D <0x7 0x01108000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + DIE_NODE(usb4_0_acio): cio@701ac0000 { + compatible =3D "apple,t6020-usb4-acio", "apple,t8103-usb4-acio"; + reg =3D <0x7 0x01ac0000 0x0 0xc000>, + <0x7 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&DIE_NODE(usb4_0_mbox)>; + resets =3D <&DIE_NODE(cio_reset) 0>; + + power-domains =3D <&DIE_NODE(ps_atc0_cio)>, + <&DIE_NODE(ps_atc0_cio_pcie)>, + <&DIE_NODE(ps_atc0_cio_usb)>; + + pinctrl-0 =3D <&DIE_NODE(acio0_pins)>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0x7 0x01000000 0x1000000>; + nonposted-mmio; + + DIE_NODE(usb4_0_dart): iommu@a80000 { + compatible =3D "apple,t6020-dart", "apple,t8110-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <5>; + }; + + DIE_NODE(usb4_0_nhi): nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t6020-usb4-nhi", + "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&DIE_NODE(usb4_0_dart) 1 0x100 0x0 0x10 0x0>, + <&DIE_NODE(usb4_0_dart) 2 0x100 0x0 0x10 0x0>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + DIE_NODE(dwc3_0): usb@702280000 { compatible =3D "apple,t6020-dwc3", "apple,t8103-dwc3"; reg =3D <0x7 0x02280000 0x0 0xcd00>, <0x7 0x0228cd00 0x0 0x3200>; @@ -186,6 +292,96 @@ DIE_NODE(atcphy0): phy@703000000 { power-domains =3D <&DIE_NODE(ps_atc0_usb)>; }; =20 + DIE_NODE(usb4_1_mbox): mailbox@b01108000 { + compatible =3D "apple,t6020-asc-mailbox", + "apple,asc-mailbox-v4"; + reg =3D <0xb 0x01108000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + DIE_NODE(usb4_1_acio): cio@b01ac0000 { + compatible =3D "apple,t6020-usb4-acio", "apple,t8103-usb4-acio"; + reg =3D <0xb 0x01ac0000 0x0 0xc000>, + <0xb 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&DIE_NODE(usb4_1_mbox)>; + resets =3D <&DIE_NODE(cio_reset) 1>; + + power-domains =3D <&DIE_NODE(ps_atc1_cio)>, + <&DIE_NODE(ps_atc1_cio_pcie)>, + <&DIE_NODE(ps_atc1_cio_usb)>; + + pinctrl-0 =3D <&DIE_NODE(acio1_pins)>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0xb 0x01000000 0x1000000>; + nonposted-mmio; + + DIE_NODE(usb4_1_dart): iommu@a80000 { + compatible =3D "apple,t6020-dart", "apple,t8110-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <5>; + }; + + DIE_NODE(usb4_1_nhi): nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t6020-usb4-nhi", + "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&DIE_NODE(usb4_1_dart) 1 0x100 0x0 0x10 0x0>, + <&DIE_NODE(usb4_1_dart) 2 0x100 0x0 0x10 0x0>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + DIE_NODE(dwc3_1): usb@b02280000 { compatible =3D "apple,t6020-dwc3", "apple,t8103-dwc3"; reg =3D <0xb 0x02280000 0x0 0xcd00>, <0xb 0x0228cd00 0x0 0x3200>; @@ -239,6 +435,96 @@ DIE_NODE(atcphy1): phy@b03000000 { power-domains =3D <&DIE_NODE(ps_atc1_usb)>; }; =20 + DIE_NODE(usb4_2_mbox): mailbox@f01108000 { + compatible =3D "apple,t6020-asc-mailbox", + "apple,asc-mailbox-v4"; + reg =3D <0xf 0x01108000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + DIE_NODE(usb4_2_acio): cio@f01ac0000 { + compatible =3D "apple,t6020-usb4-acio", "apple,t8103-usb4-acio"; + reg =3D <0xf 0x01ac0000 0x0 0xc000>, + <0xf 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&DIE_NODE(usb4_2_mbox)>; + resets =3D <&DIE_NODE(cio_reset) 2>; + + power-domains =3D <&DIE_NODE(ps_atc2_cio)>, + <&DIE_NODE(ps_atc2_cio_pcie)>, + <&DIE_NODE(ps_atc2_cio_usb)>; + + pinctrl-0 =3D <&DIE_NODE(acio2_pins)>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0xf 0x01000000 0x1000000>; + nonposted-mmio; + + DIE_NODE(usb4_2_dart): iommu@a80000 { + compatible =3D "apple,t6020-dart", "apple,t8110-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <5>; + }; + + DIE_NODE(usb4_2_nhi): nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t6020-usb4-nhi", + "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&DIE_NODE(usb4_2_dart) 1 0x100 0x0 0x10 0x0>, + <&DIE_NODE(usb4_2_dart) 2 0x100 0x0 0x10 0x0>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + DIE_NODE(dwc3_2): usb@f02280000 { compatible =3D "apple,t6020-dwc3", "apple,t8103-dwc3"; reg =3D <0xf 0x02280000 0x0 0xcd00>, <0xf 0x0228cd00 0x0 0x3200>; @@ -292,6 +578,96 @@ DIE_NODE(atcphy2): phy@f03000000 { power-domains =3D <&DIE_NODE(ps_atc2_usb)>; }; =20 + DIE_NODE(usb4_3_mbox): mailbox@1301108000 { + compatible =3D "apple,t6020-asc-mailbox", + "apple,asc-mailbox-v4"; + reg =3D <0x13 0x01108000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + }; + + DIE_NODE(usb4_3_acio): cio@1301ac0000 { + compatible =3D "apple,t6020-usb4-acio", "apple,t8103-usb4-acio"; + reg =3D <0x13 0x01ac0000 0x0 0xc000>, + <0x13 0x01080000 0x0 0x20000>; + reg-names =3D "rc", "sram"; + + mboxes =3D <&DIE_NODE(usb4_3_mbox)>; + resets =3D <&DIE_NODE(cio_reset) 3>; + + power-domains =3D <&DIE_NODE(ps_atc3_cio)>, + <&DIE_NODE(ps_atc3_cio_pcie)>, + <&DIE_NODE(ps_atc3_cio_usb)>; + + pinctrl-0 =3D <&DIE_NODE(acio3_pins)>; + pinctrl-names =3D "default"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges =3D <0x0 0x13 0x01000000 0x1000000>; + nonposted-mmio; + + DIE_NODE(usb4_3_dart): iommu@a80000 { + compatible =3D "apple,t6020-dart", "apple,t8110-dart"; + reg =3D <0xa80000 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <5>; + }; + + DIE_NODE(usb4_3_nhi): nhi@f00000 { + reg =3D <0xf00000 0x100000>, + <0xdb0000 0x30004>; + reg-names =3D "nhi", "pdf"; + compatible =3D "apple,t6020-usb4-nhi", + "apple,t8103-usb4-nhi"; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names =3D + "txring0", "txring1", "txring2", + "txring3", "txring4", "txring5", + "txring6", "txring7", "txring8", + "txring9", "txring10", "txring11", + "rxring0", "rxring1", "rxring2", + "rxring3", "rxring4", "rxring5", + "rxring6", "rxring7", "rxring8", + "rxring9", "rxring10", "rxring11"; + iommus =3D <&DIE_NODE(usb4_3_dart) 1 0x100 0x0 0x10 0x0>, + <&DIE_NODE(usb4_3_dart) 2 0x100 0x0 0x10 0x0>; + /* To be filled by the loader */ + apple,thunderbolt-drom =3D [00]; + }; + }; + DIE_NODE(dwc3_3): usb@1302280000 { compatible =3D "apple,t6020-dwc3", "apple,t8103-dwc3"; reg =3D <0x13 0x02280000 0x0 0xcd00>, <0x13 0x0228cd00 0x0 0x3200>; --=20 2.55.0