Skip to content

Intel SoundWire: Glitch on SDW_CLK causes peripherals to drop off bus during runtime resume #5495

@rfvirgil

Description

@rfvirgil

There is a spurious pulse on the clock line when exiting clock-stop without a bus reset. The peripherals will interpret this as the first bits of a frame and so they are now out-of-sync, and as per the SoundWire spec this will cause them to revert to device 0 and require re-enumeration. However, the SoundWire driver code is expecting that all the devices are still present and enumerated. Many failures then occur.

Critically, unattach_request is not set, so the codec driver runtime_resume will not wait for initialization_complete or enumeration_complete and any attempt to read/write registers will fail until the peripheral is re-enumerated. So the codec driver fails to runtime_resume.

[ 5.898434] SDW: Invalid device for paging :0
[ 5.898507] cs35l56 sdw:0:0:01fa:3556:01:0: Read failed @0x280a1e0:-22

When the SoundWire controller runtime_resumes there is a check in intel_start_bus_after_reset() whether the Cadence controller ever powered-down:

clock_stop0 = sdw_cdns_is_clock_stop(&sdw->cdns);

If this returns TRUE, it passes bus_reset=false to sdw_cdns_clock_restart(), which then calls sdw_bus_exit_clk_stop() expecting all the peripherals to still be enumerated and halted in clock stop 0. Up to this point they are, but the wakeup of the SoundWire host emits a spurious pulse on CLOCK:

Image

Close-up:

Image

It should look like this:

Image

These two spurious edges will cause the peripherals to clock in data bits for the next frame, but this isn't the start of the next frame. They are now out-of-sync with what the host is sending. When they get to where they expect the sync bits to be, they won't have the correct value and so the peripheral will Soft-Reset (as defined in the SoundWire spec). They will stop responding and will revert to not-enumerated. It takes a further 16 frames for the peripherals to acquire sync, and then they will start responding to PINGs as device 0.

The problem here is that the core SoundWire code and the codec drivers have been told that they are doing a normal exit from clock-stop 0, with all peripherals still attached to the bus. The core SoundWire code will report that:

clock stop deprepare failed:-61

but more seriously the codec driver runtime_resumes will fail to read/write registers and so the state of the peripheral doesn't match what the driver expects.

Metadata

Metadata

Assignees

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