Skip to content

--test-retimer on Laptop 12 leaves PD controller 0 stuck in retimer update mode after every warm reboot (USB-A card dead until battery disconnect) #375

Description

@fdnt7

Summary

On a Framework Laptop 12, running sudo framework_tool --test-retimer once put PD controller 0 into a persistent bad state. From then on, every warm reboot brought controller 0 up reporting retimer FW update mode (EC_CMD_BB_RETIMER_CONTROL status 0x01). The USB-A Expansion Card on that controller got VBUS but no USB data. The state survived EC reboots and shutdowns. Only BIOS Battery Disconnect with AC unplugged cleared it permanently.

The tool's own notes say the Laptop 12 has "No Retimer, only retimer for both left ports (no firmware)" (mod.rs#L2348-L2349). Even so, --test-retimer runs there and drives the enter/exit cycle.

Environment

  • Framework Laptop 12 (13th Gen Intel Core), mainboard revision MassProduction
  • BIOS 03.04 (06/23/2025)
  • EC: sunflower-3.0.4-fa46a90 2025-06-23 (current image: RO)
  • PD controllers: Right (01) 0.0.12, Left (23) 0.0.12 (MainFw)
  • framework_tool 0.6.6 (NixOS), Linux 7.2.8
  • Expansion cards: USB-A (on PD 0, port 1), HDMI (fw 3.0.10.06A), USB-C for charging

Steps to reproduce

  1. sudo framework_tool --test-retimer. Output of a later run (the first run's output wasn't kept, but it had the same shape and ended in the same error):
    Retimer Self-Test
      Retimers on PD Controller 0
        In update mode: true
          Disabling it to start test.
        Enabling update mode
    [ERROR] Failed to set retimer update mode to: true
        In update mode: false
        Disabling update mode
        In update mode: false
      Failed: DeviceError("Failed to set retimer update mode to: true")
    
    The self-test aborts after PD 0 and never reaches PD 1.
  2. reboot (warm reboot). The USB-A card is dead: nothing enumerates on it.

Across roughly 20 warm reboots before the first --test-retimer run, the device in the USB-A card enumerated at boot every time. After the run, 0 of 4 warm reboots did. The BIOS/EC firmware didn't change, and fwupd flashed nothing. Changing the kernel made no difference: 7.2.8 booted with USB-A working after a fix.

Observed behaviour after the first run

Action Result
Warm reboot USB-A dead; PD 0 retimer status 0x01
shutdown -> power on, starting from broken Still dead
shutdown -> power on, starting from fixed Stays working
--test-retimer (again) Fixes it until the next warm reboot
--reboot-ec reboot Fixes it until the next warm reboot
--host-command 15882 0 0 2 (BB_EXIT_FW_UPDATE_MODE on PD 0 only) Fixes it until the next warm reboot
BIOS Battery Disconnect with AC unplugged, then AC back Fixed permanently: status 0x00 and USB-A working after two warm reboots

Diagnostics

Retimer status (--host-command 15882 0 <ctrl> 128, i.e. BB_CHECK_STATUS):

Broken (after warm reboot) After BB_EXIT_FW_UPDATE_MODE After battery disconnect + 2 warm reboots
PD 0 01 00 00
PD 1 00 00 n/a

--pdports is identical in the broken and fixed states. Port 1 (the USB-A card) shows Source / Dfp / 5 V 1500 mA / no PD contract in both. Power and roles are fine; only the data path is missing.

EC console right after sending BB_EXIT_FW_UPDATE_MODE to PD 0 in the broken state:

[2033.574700 HC 0x3e0a]
[2033.588500 TYPE_C_ERROR_RECOVERY]
[2033.602300 TYPE_C_ERROR_RECOVERY]
[2034.025500 CYPD_RESPONSE_PORT_CONNECT 1]

The kernel enumerated the USB device on the card immediately afterwards.

Why only warm reboots are affected (EC side)

This is from reading the EC source at fa46a90 (fwk-sunflower-26784), which is the exact build running on this machine:

  • EC_CMD_BB_RETIMER_CONTROL (board_host_command.c#L463) on CCG6 writes the CCG6 user registers 0x40 / 0x46, and the status check reads 0x42 (cypd_ccg6.c#L471-L513). This is volatile PD controller state, and the EC never resets the PD controller in normal operation. Only the cypd reset console command does.
  • On a transition into S0 from S5/G3, update_system_power_state() calls perform_error_recovery() on every port (cypd_ccg6.c#L406-L417; CONFIG_PD_CCG6_ERROR_RECOVERY=y in sunflower/project.conf#L61). So a cold boot always reconnects the ports.
  • A warm reboot never leaves S0 from the EC's point of view, and chipset_reset() is empty (sunflower/src/power_sequence.c#L249-L252). The EC does nothing to the PD controllers on a warm reset.

Why the CCG6 re-enters the update-mode state on each platform reset once it's in this condition is inside the PD firmware, which I can't see. The fact that only a full power removal clears it points to latched state in the controller.

Suggestions

  1. Make --test-retimer refuse to run on Laptop 12, or at least require --force with a warning. Per the tool's own platform notes, there is no retimer with firmware on this platform.
  2. Document the recovery: BIOS Battery Disconnect with AC unplugged. As a temporary workaround until the next warm reboot: framework_tool --host-command 15882 0 0 2 (BB_EXIT_FW_UPDATE_MODE on PD 0).
  3. EC/PD side (may belong in the EC tracker): PD controller 0 shouldn't be able to latch into a state that returns on every warm reset and only clears on G3. Alternatively, the EC could clear retimer update mode on platform reset.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions