On Tue, 18. Feb 11:57, Mark Pearson wrote: > Hi Fedor, > > On Thu, Feb 6, 2025, at 1:43 PM, Fedor Pchelkin wrote: > > It is observed that on some systems an initial PPM reset during the boot > > phase can trigger a timeout: > > > > [ 6.482546] ucsi_acpi USBC000:00: failed to reset PPM! > > [ 6.482551] ucsi_acpi USBC000:00: error -ETIMEDOUT: PPM init failed > > > > Still, increasing the timeout value, albeit being the most straightforward > > solution, eliminates the problem: the initial PPM reset may take up to > > ~8000-10000ms on some Lenovo laptops. When it is reset after the above > > period of time (or even if ucsi_reset_ppm() is not called overall), UCSI > > works as expected. > > > > Moreover, if the ucsi_acpi module is loaded/unloaded manually after the > > system has booted, reading the CCI values and resetting the PPM works > > perfectly, without any timeout. Thus it's only a boot-time issue. > > > > The reason for this behavior is not clear but it may be the consequence > > of some tricks that the firmware performs or be an actual firmware bug. > > As a workaround, increase the timeout to avoid failing the UCSI > > initialization prematurely. > > > > Could you let me know which Lenovo platform(s) you see the issue on? > > I don't have any concerns with the patch below, but if the platform is in > the Linux program I can reach out to the FW team and try to determine if > there's an expected time needed (and how close we are to it). Yep, here. (also at the bottom of the [PATCH RFC 0/2] mail) Please let me know if there's more info needed. Machine: Type: Laptop System: LENOVO product: 21D0 v: ThinkBook 14 G4+ ARA serial: <superuser required> Mobo: LENOVO model: LNVNB161216 v: SDK0T76479 WIN serial: <superuser required> UEFI: LENOVO v: J6CN50WW date: 09/27/2024 Relevant part of the ACPI dump. Scope (\_SB) { Device (UBTC) { Name (_HID, EisaId ("USBC000")) // _HID: Hardware ID Name (_CID, EisaId ("PNP0CA0")) // _CID: Compatible ID Name (_UID, Zero) // _UID: Unique ID Name (_DDN, "USB Type C") // _DDN: DOS Device Name Name (_ADR, Zero) // _ADR: Address Name (_DEP, Package (0x01) // _DEP: Dependencies { \_SB.PCI0.LPC0.EC0 }) Method (_STA, 0, NotSerialized) // _STA: Status { Return (0x0F) } Method (_PS0, 0, Serialized) // _PS0: Power State 0 { Sleep (0x07D0) } Method (_PS3, 0, Serialized) // _PS3: Power State 3 { Sleep (0x07D0) } Method (TPLD, 2, Serialized) { Name (PCKG, Package (0x01) { Buffer (0x10){} }) CreateField (DerefOf (PCKG [Zero]), Zero, 0x07, REV) REV = One CreateField (DerefOf (PCKG [Zero]), 0x40, One, VISI) VISI = Arg0 CreateField (DerefOf (PCKG [Zero]), 0x57, 0x08, GPOS) GPOS = Arg1 CreateField (DerefOf (PCKG [Zero]), 0x4A, 0x04, SHAP) SHAP = One CreateField (DerefOf (PCKG [Zero]), 0x20, 0x10, WID) WID = 0x08 CreateField (DerefOf (PCKG [Zero]), 0x30, 0x10, HGT) HGT = 0x03 Return (PCKG) /* \_SB_.UBTC.TPLD.PCKG */ } Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings { Name (RBUF, ResourceTemplate () { Memory32Fixed (ReadWrite, 0x7AF66000, // Address Base 0x00001000, // Address Length ) }) Return (RBUF) /* \_SB_.UBTC._CRS.RBUF */ } Device (HSP1) { Name (_ADR, One) // _ADR: Address Name (_UPC, Package (0x04) // _UPC: USB Port Capabilities { 0xFF, 0x09, Zero, Zero }) Method (_PLD, 0, NotSerialized) // _PLD: Physical Location of Device { Return (TPLD (One, 0x04)) } } Device (HSP2) { Name (_ADR, One) // _ADR: Address Name (_UPC, Package (0x04) // _UPC: USB Port Capabilities { 0xFF, 0x09, Zero, Zero }) Method (_PLD, 0, NotSerialized) // _PLD: Physical Location of Device { Return (TPLD (One, 0x04)) } } OperationRegion (USBC, SystemMemory, 0x7AF66000, 0x30) Field (USBC, ByteAcc, Lock, Preserve) { VER1, 8, VER2, 8, RSV1, 8, RSV2, 8, CCI0, 8, CCI1, 8, CCI2, 8, CCI3, 8, CTL0, 8, CTL1, 8, CTL2, 8, CTL3, 8, CTL4, 8, CTL5, 8, CTL6, 8, CTL7, 8, MGI0, 8, MGI1, 8, MGI2, 8, MGI3, 8, MGI4, 8, MGI5, 8, MGI6, 8, MGI7, 8, MGI8, 8, MGI9, 8, MGIA, 8, MGIB, 8, MGIC, 8, MGID, 8, MGIE, 8, MGIF, 8, MGO0, 8, MGO1, 8, MGO2, 8, MGO3, 8, MGO4, 8, MGO5, 8, MGO6, 8, MGO7, 8, MGO8, 8, MGO9, 8, MGOA, 8, MGOB, 8, MGOC, 8, MGOD, 8, MGOE, 8, MGOF, 8 } OperationRegion (DBG0, SystemIO, 0x80, One) Field (DBG0, ByteAcc, NoLock, Preserve) { IO80, 8 } Method (NTFY, 0, Serialized) { ECRD () Sleep (One) Notify (\_SB.UBTC, 0x80) // Status Change } Method (ECWR, 0, Serialized) { IO80 = 0xA0 \_SB.PCI0.LPC0.EC0.ECWT (MGO0, RefOf (\_SB.PCI0.LPC0.EC0.MGO0)) \_SB.PCI0.LPC0.EC0.ECWT (MGO1, RefOf (\_SB.PCI0.LPC0.EC0.MGO1)) \_SB.PCI0.LPC0.EC0.ECWT (MGO2, RefOf (\_SB.PCI0.LPC0.EC0.MGO2)) \_SB.PCI0.LPC0.EC0.ECWT (MGO3, RefOf (\_SB.PCI0.LPC0.EC0.MGO3)) \_SB.PCI0.LPC0.EC0.ECWT (MGO4, RefOf (\_SB.PCI0.LPC0.EC0.MGO4)) \_SB.PCI0.LPC0.EC0.ECWT (MGO5, RefOf (\_SB.PCI0.LPC0.EC0.MGO5)) \_SB.PCI0.LPC0.EC0.ECWT (MGO6, RefOf (\_SB.PCI0.LPC0.EC0.MGO6)) \_SB.PCI0.LPC0.EC0.ECWT (MGO7, RefOf (\_SB.PCI0.LPC0.EC0.MGO7)) \_SB.PCI0.LPC0.EC0.ECWT (MGO8, RefOf (\_SB.PCI0.LPC0.EC0.MGO8)) \_SB.PCI0.LPC0.EC0.ECWT (MGO9, RefOf (\_SB.PCI0.LPC0.EC0.MGO9)) \_SB.PCI0.LPC0.EC0.ECWT (MGOA, RefOf (\_SB.PCI0.LPC0.EC0.MGOA)) \_SB.PCI0.LPC0.EC0.ECWT (MGOB, RefOf (\_SB.PCI0.LPC0.EC0.MGOB)) \_SB.PCI0.LPC0.EC0.ECWT (MGOC, RefOf (\_SB.PCI0.LPC0.EC0.MGOC)) \_SB.PCI0.LPC0.EC0.ECWT (MGOD, RefOf (\_SB.PCI0.LPC0.EC0.MGOD)) \_SB.PCI0.LPC0.EC0.ECWT (MGOE, RefOf (\_SB.PCI0.LPC0.EC0.MGOE)) \_SB.PCI0.LPC0.EC0.ECWT (MGOF, RefOf (\_SB.PCI0.LPC0.EC0.MGOF)) \_SB.PCI0.LPC0.EC0.ECWT (CTL0, RefOf (\_SB.PCI0.LPC0.EC0.CTL0)) \_SB.PCI0.LPC0.EC0.ECWT (CTL1, RefOf (\_SB.PCI0.LPC0.EC0.CTL1)) \_SB.PCI0.LPC0.EC0.ECWT (CTL2, RefOf (\_SB.PCI0.LPC0.EC0.CTL2)) \_SB.PCI0.LPC0.EC0.ECWT (CTL3, RefOf (\_SB.PCI0.LPC0.EC0.CTL3)) \_SB.PCI0.LPC0.EC0.ECWT (CTL4, RefOf (\_SB.PCI0.LPC0.EC0.CTL4)) \_SB.PCI0.LPC0.EC0.ECWT (CTL5, RefOf (\_SB.PCI0.LPC0.EC0.CTL5)) \_SB.PCI0.LPC0.EC0.ECWT (CTL6, RefOf (\_SB.PCI0.LPC0.EC0.CTL6)) \_SB.PCI0.LPC0.EC0.ECWT (CTL7, RefOf (\_SB.PCI0.LPC0.EC0.CTL7)) \_SB.PCI0.LPC0.EC0.ECWT (0xE0, RefOf (\_SB.PCI0.LPC0.EC0.USDC)) IO80 = 0xA1 } Method (ECRD, 0, Serialized) { IO80 = 0xA3 MGI0 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI0)) MGI1 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI1)) MGI2 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI2)) MGI3 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI3)) MGI4 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI4)) MGI5 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI5)) MGI6 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI6)) MGI7 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI7)) MGI8 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI8)) MGI9 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGI9)) MGIA = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGIA)) MGIB = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGIB)) MGIC = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGIC)) MGID = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGID)) MGIE = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGIE)) MGIF = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.MGIF)) VER1 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.VER1)) VER2 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.VER2)) RSV1 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.RSV1)) RSV2 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.RSV2)) CCI0 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.CCI0)) CCI1 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.CCI1)) CCI2 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.CCI2)) CCI3 = \_SB.PCI0.LPC0.EC0.ECRD (RefOf (\_SB.PCI0.LPC0.EC0.CCI3)) \_SB.PCI0.LPC0.EC0.ECWT (0xE1, RefOf (\_SB.PCI0.LPC0.EC0.USGC)) IO80 = 0xA4 } Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method { If ((Arg0 == ToUUID ("6f8398c2-7ca4-11e4-ad36-631042b5008f") /* Unknown UUID */)) { If ((ToInteger (Arg2) == Zero)) { Return (Buffer (One) { 0x0F // . }) } ElseIf ((ToInteger (Arg2) == One)) { ECWR () } ElseIf ((ToInteger (Arg2) == 0x02)) { ECRD () } Else { Return (Zero) } } Return (Zero) } } }