# DF-4667 — phm_wait_on_indirect_register: value/mask arguments swapped (latent, Info)

**File:** `sys/dev/drm/amd/powerplay/hwmgr/smu_helper.c:136-149`

`phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
uint32_t value, uint32_t mask)` — documented "(index, value, mask)".

`phm_wait_on_indirect_register` (smu_helper.c:148) calls:

```c
return phm_wait_on_register(hwmgr, indirect_port + 1, mask, value);
```

i.e. **mask is passed as `value` and value as `mask`** — provable by
comparing with the sibling `phm_wait_for_indirect_register_unequal`
(smu_helper.c:185-186), which passes `(value, mask)` correctly for the same
callee shape. With the swap, the wait condition becomes
`(cur & value) == (mask & value)` instead of `(cur & mask) == (value & mask)`:
when `value & mask == 0` the wait returns success **immediately regardless of
the register state**; otherwise it can spuriously time out.

**Current impact: none.** The sole caller,
`smu7_check_fw_load_finish` (smumgr/smu7_smumgr.c:449-452), passes
`value = fw_type, mask = fw_type` — identical values, so the swap is
currently harmless. Any future caller with `value & mask == 0` (e.g. waiting
for a bit to CLEAR: value=0) would silently skip the firmware-ready handshake
and race the SMC during clock/voltage programming.

Not PoC-verified (Info severity; the defect is directly readable in the
source and current callers are provably insensitive to it).

## Suggested fix

```diff
--- a/sys/dev/drm/amd/powerplay/hwmgr/smu_helper.c
+++ b/sys/dev/drm/amd/powerplay/hwmgr/smu_helper.c
@@ -145,7 +145,7 @@ int phm_wait_on_indirect_register(struct pp
 	cgs_write_register(hwmgr->device, indirect_port, index);
-	return phm_wait_on_register(hwmgr, indirect_port + 1, mask, value);
+	return phm_wait_on_register(hwmgr, indirect_port + 1, value, mask);
 }
```
