Repository navigation
soundwire: qcom: enumerate in software when hardware auto-enum fails - #1268
Open
nandamajay wants to merge 1 commit into
Open
nandamajay wants to merge 1 commit into
nandamajay wants to merge 1 commit into
Conversation
The v2.0.0 SoundWire controller support added in commit 312355a ("soundwire: qcom: add support for v2.0.0 controller") left the SWRM_INTERRUPT_STATUS_AUTO_ENUM_FAILED (BIT(11)) interrupt without a case in qcom_swrm_irq_handler(); it falls through to the "unknown interrupt" default. On some QCM6490 cold boots the hardware auto-enumerator's one-shot DevID read at ping address 0 breaks mid-transfer: the first byte latches and the rest return zero. The HW enumeration table is left empty, so qcom_swrm_enumerate() assigns no device number, the WCD/WSA codecs never initialise, and the sound card fails to come up ("Initialization not complete", -ETIMEDOUT). The controller signals exactly this condition via AUTO_ENUM_FAILED - which, unhandled, means nothing recovers. The peripheral itself is awake throughout - a command-FIFO read of SCP_DEVID_0..5 at address 0 (qcom_swrm_cmd_fifo_rd_cmd(), which retries and flushes the FIFO between tries) returns the real DevID where the hardware's single-shot read did not. So when AUTO_ENUM_FAILED fires, enumerate the peripheral in software over the command FIFO. Assign the device number in the driver rather than delegating the address-0 program step to the generic sdw_program_device_num(). That helper re-reads the DevID at address 0 with a single raw transfer; on a flaky boot the read underflows, the core finds no matching slave and sdw_slave_add()s a phantom (logging "Slave Entry not found") which is handed the device number the real codec needs. qcom_swrm_match_slave_at_zero() instead reads the DevID with the retrying command-FIFO primitive and matches it against the peripherals this bus declares; qcom_swrm_sw_program_device() then picks a free number with find_first_zero_bit() over bus->assigned (the same way the core does), writes SCP_DEVNUMBER over the command FIFO and records the assignment as qcom_swrm_set_slave_dev_num() does on the hardware path. Status slot 0 is never surfaced to sdw_handle_slave_status() as attached, so the core never reads address 0 and no phantom can be created; the core is invoked only to initialise devices that have re-attached at their new number. On a cold boot the peripheral can take a few hundred milliseconds to answer, so a DevID read that underflows is retried after a bounded settle delay (SWRM_SW_ENUM_ATTEMPTS attempts, SWRM_SW_ENUM_SETTLE_MS apart) rather than giving up; a clean read programs on the first attempt and does not sleep. The fallback runs from the threaded IRQ handler (which may sleep) and is bounded per bring-up by SWRM_SW_ENUM_RETRIES so a dead bus cannot loop forever. Also add a case for SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULL, previously unhandled for the same reason. Fixes: 312355a ("soundwire: qcom: add support for v2.0.0 controller") Signed-off-by: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
soundwire: qcom: enumerate in software when hardware auto-enum fails
Problem
On some QCM6490 cold boots the SoundWire sound card fails to come up
("Initialization not complete",
-ETIMEDOUT). Root cause is a SoundWireenumeration failure: the v2.0.0 controller's hardware auto-enumerator does a
one-shot DevID read at ping address 0 that breaks mid-transfer (first byte
latches, the rest return zero). The HW enumeration table is left empty, so
qcom_swrm_enumerate()assigns no device number, the WCD/WSA codecs neverinitialise, and no card appears.
The controller signals exactly this via
SWRM_INTERRUPT_STATUS_AUTO_ENUM_FAILED(BIT(11)) — but that interrupt has had no case in
qcom_swrm_irq_handler()since it was introduced in commit 312355a ("soundwire: qcom: add support
for v2.0.0 controller"); it falls through to the "unknown interrupt" default and
nothing recovers.
Fix
The peripheral is awake throughout — a command-FIFO read of
SCP_DEVID_0..5(
qcom_swrm_cmd_fifo_rd_cmd(), which retries and flushes the FIFO between tries)returns the real DevID where the hardware's single-shot read did not. So on
AUTO_ENUM_FAILED, enumerate the peripheral in software over the commandFIFO:
qcom_swrm_match_slave_at_zero()reads the DevID with the retrying command-FIFOprimitive and matches it against the peripherals this bus declares.
qcom_swrm_sw_program_device()picks a free number withfind_first_zero_bit()over
bus->assigned(same as the core), writesSCP_DEVNUMBERover the commandFIFO and records the assignment the same way the hardware path does.
address-0 program step to the generic
sdw_program_device_num(), whose singleraw re-read of address 0 would underflow on a flaky boot and mint a phantom
slave (
"Slave Entry not found") that steals the real codec's number.SWRM_SW_ENUM_ATTEMPTS×SWRM_SW_ENUM_SETTLE_MS)covers the few-hundred-ms a cold-boot peripheral can take to answer; a clean
read programs on the first attempt and never sleeps. The whole fallback runs
from the threaded IRQ handler and is bounded per bring-up by
SWRM_SW_ENUM_RETRIES.Also adds the previously-missing
SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULLcase.
Fixes: 312355a ("soundwire: qcom: add support for v2.0.0 controller")
Related issue
Fixes #1251 — the same cold-boot no-soundcard /
enumeration failure.
Validation
The fix was validated on QCM6490-IDP over repeated cold boots: card comes up on
every boot with a clean 4-device slave list (both WSA883x + both WCD937x,
all Attached and bound), no phantom node and no
"Slave Entry not found",with the capture-path (TX) WCD enumerated as well.