From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: Vlad Mykhailichenko <dywedir@gra.red>
Cc: linux-usb@vger.kernel.org, Mark Pearson <mpearson-lenovo@squebb.ca>
Subject: Re: ucsi_acpi: ThinkPad X13 Gen 1 (AMD) - VERSION reads 0, and GET_PDOS returns one PDO per command
Date: Mon, 26 Oct 2026 14:08:37 +0100 [thread overview]
Message-ID: <at9Q1fBiXFFr92AY@black.igk.intel.com> (raw)
In-Reply-To: <ea0ed395-47a3-4982-8eb7-54059726e6b7@gra.red>
Hi Vlad,
On Tue, Oct 20, 2026 at 12:55:36PM +0300, Vlad Mykhailichenko wrote:
> Hi Heikki,
>
> On a ThinkPad X13 Gen 1 (AMD Ryzen 5 PRO 4650U, 20UGS2K101, BIOS
> R1CET86W 1.55, 2026-05-08), UCSI never comes up, and once it is forced up it
> reports only the first source PDO. Seen on 6.18.56 and 7.2.10 (NixOS), with
> identical PPM responses on both. The relevant code in ucsi.c looks unchanged
> in current master (7.3).
>
> 1) ucsi_acpi probe fails silently with -ENODEV
>
> ucsi_acpi loads, USBC000:00 has _STA 0xF, but the device stays unbound and
> /sys/class/typec is empty. Nothing is logged, even with dyndbg=+p. A manual
> bind returns ENODEV:
>
> # echo USBC000:00 > /sys/bus/platform/drivers/ucsi_acpi/bind
> echo: write error: No such device
>
> USBC000:00 is not in devices_deferred. The silent path is the version check
> in ucsi_register():
>
> if (!ucsi->version)
> return -ENODEV;
>
> The firmware's SSDT (LENOVO UsbCTabl rev 1) declares the mailbox as
> \_SB.UBTC.USBC at 0xCC235000 (0x30 bytes; VER1, VER2, RSV1, RSV2, CCI0-3,
> CTL0-7, MGI0-F, MGO0-F). Its _DSM read path (ECRD) copies CCI and MGI from
> the
> EC. Nothing in any table writes VER1/VER2, so VERSION presumably stays 0
> unless the BIOS fills it during POST, which it evidently does not. I could
> not read the mailbox directly because of STRICT_DEVMEM.
>
> As a workaround, an additional SSDT from the initrd (not a replacement of
> UsbCTabl) sets VERSION to 1.0 at load time:
>
> DefinitionBlock ("", "SSDT", 2, "WATTSN", "UcsiVer", 0x00000001)
> {
> External (\_SB.UBTC.VER1, FieldUnitObj)
> External (\_SB.UBTC.VER2, FieldUnitObj)
>
> If (CondRefOf (\_SB.UBTC.VER2))
> {
> If (((\_SB.UBTC.VER1 == Zero) && (\_SB.UBTC.VER2 == Zero)))
> {
> \_SB.UBTC.VER2 = One
> }
> }
> }
>
> With that, ucsi_acpi binds, port0/port1 register and are linked to
> usb2/usb3-port1 and usb4/usb5-port1, and no PPM errors are logged. On 7.2.10
> the existing reserved-bit check also fires, so GET_CAPABILITY from the same
> firmware sets bit 7 of bNumConnectors as well (0x82 for 2 connectors):
>
> ucsi_acpi USBC000:00: UCSI: Invalid num_connectors 130. Likely buggy FW
>
> 2) GET_PDOS returns a single PDO regardless of the number requested
>
> With a 45 W USB PD charger on connector 2, the partner's source caps show
> only "1:fixed_supply 5000mV 3000mA". ucsi-source-psy-USBC000:002 reports
> voltage_now 0, current_now 2250000, current_max 3000000, voltage_min/max
> 5000000.
>
> GET_PDOS via debugfs (partner, source, connector 2), one PDO at a time:
>
> offset 0 0x400820010 -> ...5383ff01 0801912c fixed 5 V 3.00 A
> offset 1 0x401820010 -> ...5383ff01 0002d12c fixed 9 V 3.00 A
> offset 2 0x402820010 -> ...5383ff01 0003c12c fixed 12 V 3.00 A
> offset 3 0x403820010 -> ...5383ff01 0004b12c fixed 15 V 3.00 A
> offset 4 0x404820010 -> ...5383ff01 000640e1 fixed 20 V 2.25 A
> offset 5 0x405820010 -> ...5383ff01 c8dc325a PPS 5.0-11.0 V 4.5 A
> offset 6 0x406820010 -> ...5383ff01 00000000
>
> Four at a time, only the first dword of the response is a valid PDO and the
> rest looks stale:
>
> offset 0 0x700820010 -> 0x01100200012000015383ff010801912c
> offset 4 0x704820010 -> 0x01100200012000015383ff01000640e1
>
> ucsi_get_pdos() reads one PDO, takes num_pdos < UCSI_MAX_PDOS as the end of
> the list, and stops. GET_CONNECTOR_STATUS shows the RDO selecting object
> position 5, operating current 2.25 A:
>
> 0x20012 -> 0x0110020001200001538384e1202b5b60
>
> so the contract is 20 V / 2.25 A, but the psy cannot report the voltage,
> because the kernel only has PDO 1.
>
> Questions:
>
> - Would a dev_err()/dev_warn() for the version == 0 case be acceptable? It
> would have saved most of this.
> - For VERSION, is a DMI quirk that assumes 1.0 acceptable, or would you
> rather
> this stays a firmware problem for Lenovo? Mark, is this something that can
> be raised with the BIOS team?
This one really should be fixed in the firmware.
> - For GET_PDOS, would you take a fallback (or a quirk) that reads one PDO at
> a time when a multi-PDO read returns exactly one?
>
> I am happy to test patches on this machine.
And I would be happy to see patches. It sounds like you are capable
and willing to write the code, so just do it. That's how things are
proposed in Linux kernel - with code.
Thanks,
--
heikki
next prev parent reply other threads:[~2026-10-26 13:08 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-20 9:55 ucsi_acpi: ThinkPad X13 Gen 1 (AMD) - VERSION reads 0, and GET_PDOS returns one PDO per command Vlad Mykhailichenko
2026-10-26 13:08 ` Heikki Krogerus [this message]
2026-10-26 13:55 ` Mark Pearson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=at9Q1fBiXFFr92AY@black.igk.intel.com \
--to=heikki.krogerus@linux.intel.com \
--cc=dywedir@gra.red \
--cc=linux-usb@vger.kernel.org \
--cc=mpearson-lenovo@squebb.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox