From nobody Mon Dec 1 22:05:38 2025 Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9371D2BEC4A for ; Thu, 27 Nov 2025 04:44:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764218652; cv=none; b=SnWFJFKRCSdIx1IYk0b9gGizhN6ebq3V3RDL61odm90ANhdOqyJNljyVmmBBrvRSkTFVSr/ML+U8wuq86aDREnKkEkHtsa2i7pj1g0gl1hJT3+4ExFs+014HMVitcH4eTBn6ptHao4t0fYxnOPS21P49MmMuSRrE/YhzIXXZFDw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764218652; c=relaxed/simple; bh=PE/0iha3lu4eon9mx9GEVPjUc2b0FJYFb3kNrYBYBRg=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=MsLKvrbNIVHZMzjCOTRwuX+d/yXoWuU1u72CLHE4w5IYVigvEINlwvej+0BAIWR0MivpcdJ2FtXqt8PMldq3xBHXIVu5VwNIxwvI27dob0nDc53/Ui9qGEJz7uY5eAzJE8Ng/q50ne0GrngmgQe5paBR5c+T3Vw/+N8OWZ95C+A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=reject dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=hfDb/g6u; arc=none smtp.client-ip=209.85.210.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=reject dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hfDb/g6u" Received: by mail-pf1-f176.google.com with SMTP id d2e1a72fcca58-7ba55660769so341242b3a.1 for ; Wed, 26 Nov 2025 20:44:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1764218650; x=1764823450; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:sender:from:to:cc:subject:date:message-id:reply-to; bh=x7BjBMa+JRnqZfeT1IW4v+bUgZq+0v2oxPOk5e1+Mak=; b=hfDb/g6uEbbUrWnLkAuC6mBvdu8KWOhdz5X4PcZ1NI62gY4Rq71NxzTEZge0A8XhMl siPtvjVz7GM/tpRc4T3mJ0eDk+tUJD1Rlek4UXXCdyi+taQf1rnnGrCG0g14Fgs2Xzkh vsJrlqSinGpkHX53uhjrZxY1vBloJbQLb6OwcOAl/pOhn3smPy/9nKC3agW45PXEI470 9sjF6scFBiBfnZF27Mg3J/S5zCZxmyVJxS7LEU7+SQF3Bez1s8QQK2lBt6hCZR1dezXG BtUUK3Ono/WhZEJE5UGJ/N6j03cZO0+2et40oH3szDnSO36KDyNBQlsA+P75FDKVYmbK c9xQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764218650; x=1764823450; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:sender:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=x7BjBMa+JRnqZfeT1IW4v+bUgZq+0v2oxPOk5e1+Mak=; b=LlAJNG2XDUU+0Zai1hHFXwSg61/e4fQspH0+mg5NqJMGY79ivHfOs6WqSFEA6XK/G0 zhO5N8q3pAWOxgQXIfyXUpBcmrcSy9U4K7YIQqzdlJ3daG0NHqyEgO2hf7QOdHKLxLii 5/PO6QTYokZU27dwrwg/+43bUfS8+LJDyzqhagQkTlkwmq/tpv9wTIUnc8IIjfl07Jb6 qTIYQzmDPselmEQkVSQKy8uE8Em8ZoLpdgS8mtQJpkJ6cktgR3KlIkzxeVUcUQtV0OD+ E2gGiNvoAfDBSaEeMwcjF94E80sBV6s11F+qUQcImr6Z1r5Gtjt+1nvzOqTpeyz5qLJO MmPw== X-Forwarded-Encrypted: i=1; AJvYcCVTSyfUfm0aVZKz/VciwAcOHJl7EwfoKrISL0AO9NGWQ3D/HjRgTcEnOSk2hDTXA6BtbZfdNSkcY8QDM94=@vger.kernel.org X-Gm-Message-State: AOJu0Yx2BoEKb5fKuuQ20xz7nIvishcmUnXI4orHeEFaXAA1DkgHqkYa Fzb01UGo/6eXA7sC3nxD5KKMyNOE/+tI5jF+S+iyriEeQdaZEa7romA8FXDTkitc X-Gm-Gg: ASbGnctp7TnscTsqC/k1Bsg1c2e1jIX2pwqkczEoH3EQpm7QBS2EQVTK+uQPlVFR+GW WFq+0/aQhurObYqnlAF0gqjQhfOM4EkRCZloZHmwzj+qg7d0F4B+zVKvOkcLPwixTq0rsxfayDd g4RWt1xGsrM3Icztq+B5dy7/ilQyZRD7oJzQzPFK4KGJOC2aVR8BtwGyDVIgccR8SGRyA061KDF zmkF1j6JBX6NVEZUIwC6H6wQadAag8suU1WDUC0+LsQcIz3mbThu+5v5PtzBU87e2nM7Z88g05Q cTf6GsD4x1MxPmknR/C4RXzWBAY9K7sAg6XyiwL0GYEckj+OYPfwarbXZgtCO0ZOUL1Qu18f6uD uP0p4pcBT5JfoABorJ5gXw4HaKkAzuS+hQDh1EqrpLiiPGJ/JuE1TjalN2YWPvW30Sa8DhMnH55 /faNHuJ+jbLlfG4OV36+qu0+7HykIxAUFAVggFgBf+ X-Google-Smtp-Source: AGHT+IGzwx8XxKIfrZDVhykQGzSqr62sGMg9gUipriPRuelgVcksceVllUvwkK7+tgeHc5shxjATTQ== X-Received: by 2002:a05:6a00:2e9e:b0:7b2:1fb0:6da0 with SMTP id d2e1a72fcca58-7c58e602d9dmr26604730b3a.28.1764218649685; Wed, 26 Nov 2025 20:44:09 -0800 (PST) Received: from localhost (211-75-139-220.hinet-ip.hinet.net. [211.75.139.220]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7d150b6853bsm313375b3a.14.2025.11.26.20.44.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Nov 2025 20:44:09 -0800 (PST) Sender: AceLan Kao From: "Chia-Lin Kao (AceLan)" To: Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , David Airlie , Simona Vetter , intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH] drm/i915/dp: Add byte-by-byte fallback for broken USB-C adapters Date: Thu, 27 Nov 2025 12:44:06 +0800 Message-ID: <20251127044406.618543-1-acelan.kao@canonical.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Some USB-C hubs and adapters have buggy firmware where multi-byte AUX reads from DPCD address 0x00000 consistently timeout, while single-byte reads from the same address work correctly. Known affected devices that exhibit this issue: - Lenovo USB-C to VGA adapter (VIA VL817 chipset) idVendor=3D17ef, idProduct=3D7217 - Dell DA310 USB-C mobile adapter hub idVendor=3D413c, idProduct=3Dc010 Analysis of the failure pattern shows: - Single-byte probes to 0xf0000 (LTTPR) succeed - Single-byte probes to 0x00102 (TRAINING_AUX_RD_INTERVAL) succeed - 15-byte reads from 0x00000 (DPCD capabilities) timeout with -ETIMEDOUT - Retrying does not help - the failure is consistent across all attempts The issue appears to be a firmware bug in the AUX transaction handling that specifically affects multi-byte reads from the base DPCD address. Add a fallback mechanism that attempts byte-by-byte reading when the normal multi-byte drm_dp_read_dpcd_caps() fails. This workaround only activates for adapters that fail the standard read path, ensuring no impact on correctly functioning hardware. The byte-by-byte read uses drm_dp_dpcd_readb() to read each of the 15 DPCD capability bytes individually, working around the firmware bug while maintaining compatibility with all other adapters. Tested with: - Lenovo USB-C to VGA adapter (VIA VL817) - now works with fallback - Dell DA310 USB-C hub - now works with fallback - Dell/Analogix Slimport adapter - continues to work with normal path Signed-off-by: Chia-Lin Kao (AceLan) --- .../drm/i915/display/intel_dp_link_training.c | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/driver= s/gpu/drm/i915/display/intel_dp_link_training.c index aad5fe14962f..738a5bb4adb3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -213,6 +213,7 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_d= p, const u8 dpcd[DP_RECEI int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER= _CAP_SIZE]) { struct intel_display *display =3D to_intel_display(intel_dp); + int ret, i; =20 if (intel_dp_is_edp(intel_dp)) return 0; @@ -226,7 +227,25 @@ int intel_dp_read_dprx_caps(struct intel_dp *intel_dp,= u8 dpcd[DP_RECEIVER_CAP_S DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV)) return -EIO; =20 - if (drm_dp_read_dpcd_caps(&intel_dp->aux, dpcd)) + ret =3D drm_dp_read_dpcd_caps(&intel_dp->aux, dpcd); + if (ret =3D=3D 0) + return 0; + + /* + * Workaround for USB-C hubs/adapters with buggy firmware that fail + * multi-byte AUX reads from DPCD address 0x00000 but work with + * single-byte reads. Known affected devices: + * - Lenovo USB-C to VGA adapter (VIA VL817, idVendor=3D17ef, idProduct= =3D7217) + * - Dell DA310 USB-C hub (idVendor=3D413c, idProduct=3Dc010) + * Read the DPCD capabilities byte-by-byte as a fallback. + */ + for (i =3D 0; i < DP_RECEIVER_CAP_SIZE; i++) { + ret =3D drm_dp_dpcd_readb(&intel_dp->aux, DP_DPCD_REV + i, &dpcd[i]); + if (ret < 0) + return -EIO; + } + + if (dpcd[DP_DPCD_REV] =3D=3D 0) return -EIO; =20 return 0; --=20 2.43.0