Skip to content

drivers: qcom: rpmh/cmd_db: fix completion tracking and remove unused scaffolding - #57

Open
Selvam (zelvam95) wants to merge 4 commits into
qualcomm-linux:qcom-nextfrom
zelvam95:feature/qcom-cmd_db-rpmh-refactor
Open

drivers: qcom: rpmh/cmd_db: fix completion tracking and remove unused scaffolding#57
Selvam (zelvam95) wants to merge 4 commits into
qualcomm-linux:qcom-nextfrom
zelvam95:feature/qcom-cmd_db-rpmh-refactor

Conversation

@zelvam95

@zelvam95 Selvam (zelvam95) commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Title

drivers: qcom: rpmh/cmd_db: fix completion tracking and remove unused scaffolding

Dependencies / stacking

This PR is stacked on: PR #47 (now merged)

Description

The RPMH client has a real completion-tracking bug: the AMC-finished
interrupt status is never cleared around dispatch, and the
per-command completion-wait register is never programmed, so after
the first command of a boot every later completion check can read
stale state instead of a fresh per-command signal. This series fixes
that.

While auditing the surrounding code, it also removes a substantial
amount of driver machinery that has no real caller — a runtime
multi-DRV config table, a per-DRV base-address array, an async
multi-slot TCS state machine, and CMD_DB's paired priority/address
lookup path. rpmh_create_handle() has always accepted only the
secure DRV, and only active-set commands are ever issued through it;
none of the removed code was reachable. In its place, RPMH's register
layout is split into a per-platform header, mirroring QFPROM's
existing structure, and CMD_DB's slave-ID lookup gains a range check
it was missing.

None of this changes behavior for the one real caller (QFPROM's fuse
rail sequencing) beyond fixing the completion-tracking bug itself —
everything else is dead-code removal or a defensive hardening that
was already correct in practice.

Testing

Built qcom-kodiak and qcom-lemans, both with and without
CFG_QFPROM_PROGRAMMING=y CFG_QCOM_QFPROM_FUSEPROV=y, plus a one-off
qcom-lemans build forcing CFG_QCOM_RPMH_CLIENT=y CFG_QCOM_CMD_DB=y
to confirm the new per-platform header resolves correctly there too.
All combinations build clean; scripts/checkpatch.sh is clean on
every commit in the series.

@b49020
Sumit Garg (b49020) force-pushed the qcom-next branch 2 times, most recently from 1a117cb to dab3efd Compare September 7, 2026 07:43
@b49020

Copy link
Copy Markdown
Member

Please rebase this PR to tip of qcom-next.

@zelvam95
Selvam (zelvam95) force-pushed the feature/qcom-cmd_db-rpmh-refactor branch from beb1e8c to 64512ac Compare September 8, 2026 09:40
@zelvam95 Selvam (zelvam95) changed the title qfprom + rpmh + cmd_db refactoring changes drivers: qcom: rpmh/cmd_db: fix completion tracking and remove unused scaffolding Sep 8, 2026
@zelvam95

Copy link
Copy Markdown
Contributor Author

Please rebase this PR to tip of qcom-next.

Rebase done.

@zelvam95

Copy link
Copy Markdown
Contributor Author

Corresponding upstream PR is tracked here: OP-TEE/optee_os#7958

The AMC-finished interrupt status is never cleared, so once it is set
it stays latched "complete" for the rest of the boot: every later
completion check reads that stale bit instead of a fresh per-command
signal, regardless of whether the new command was ever actually
processed. Clear it before triggering a command and after consuming
its completion, so every wait observes a fresh signal.

Also program the per-command completion-wait mask before triggering:
the TCS has a register for it that nothing was writing to, so the
hardware had no way to know which enabled commands actually need an
AOP response before the TCS counts as done.

rpmh_send_command() already waits for completion before returning, so
rpmh_barrier_single()'s second wait on the same request was already
redundant, and would now time out instead of reading a harmless stale
bit. Drop it along with its call sites.

Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com>
Tested by: Naresh Nunna <nnunna@qti.qualcomm.com>
rpmh_create_handle() has always rejected every drv_id but
RSC_DRV_SECURE. Everything around it was built for a broader case
that never occurs: a runtime multi-DRV config table with a single
entry, a per-DRV base-address array and register step, and an async
multi-slot TCS state machine built to walk that table. None of it has
a real caller.

Replace all of it with a single fixed RSC base and a compile-time TCS
layout. The command-dispatch loop is otherwise unchanged: it still
builds a full command array with enable/wait masks, since the TCS
already supports dispatching a batch and there is no reason to narrow
that just because the one real caller only ever submits one command.
Separately, poll the actual TCS_STATUS_CONTROLLER_IDLE hardware bit
before dispatch, replacing a software idle flag that nothing in this
path ever clears back to busy.

Also drop the per-TCS AMC/non-AMC setup that init used to do across
all 4 TCSs. The send path already asserts AMC mode on the one TCS it
ever dispatches through, right before triggering, so priming it at
init was redundant, and the other three TCSs are never touched again
by anything. hal_rpmh_convert_to_amc()/convert_to_tcs() go with it,
since nothing else called them.

Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com>
Tested by: Naresh Nunna <nnunna@qti.qualcomm.com>
cmd_db_get_priority() had exactly one caller, removed from the RPMH
driver in the previous commit, leaving it and the address-lookup path
it depends on unreachable. Remove both and simplify search_entry() to
the resource-ID lookup its only remaining caller uses. entry_header
keeps its own priority[] field, since it mirrors the on-disk layout
the AOP command DB writes.

While touching search_entry(), also skip any slot whose reported
slv_id falls outside the valid range before scanning its entries, so
a slot with a corrupted slv_id but a stray non-zero cnt can't be
walked. It previously relied solely on an unpopulated slot's cnt being
0 to make the inner loop a no-op.

Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com>
Tested by: Naresh Nunna <nnunna@qti.qualcomm.com>
@zelvam95
Selvam (zelvam95) force-pushed the feature/qcom-cmd_db-rpmh-refactor branch from be9929d to a66d510 Compare September 10, 2026 12:28
rpmh_hal.h hardcoded every RSC/TCS register offset and MSGID/ADDR
field value in one file shared by every platform that could ever
enable this driver.

Move the register offsets, control/status bits, and MSGID/ADDR field
shifts and masks into a new rpmh_target.h under each platform
directory.

Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@qti.qualcomm.com>
Tested by: Naresh Nunna <nnunna@qti.qualcomm.com>
@zelvam95
Selvam (zelvam95) force-pushed the feature/qcom-cmd_db-rpmh-refactor branch from a66d510 to 6f26bd1 Compare September 10, 2026 13:17
Comment thread core/drivers/qcom/rpmh/rpmh_client.c
Comment thread core/drivers/qcom/rpmh/rpmh_client.c
Comment thread core/drivers/qcom/rpmh/rpmh_client.c

@IDineshChoudhary IDineshChoudhary left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of review comments (but minor ones), looks good otherwise - approving.

@IDineshChoudhary IDineshChoudhary left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resetting approval based on equivalent upstream change review at OP-TEE/optee_os#7958

@zelvam95

Copy link
Copy Markdown
Contributor Author

resetting approval based on equivalent upstream change review at OP-TEE/optee_os#7958

Thanks Dinesh. I will address the comments provided here as well and push to the upstream PR since active review is happening there. Once the change is merged there, will pull it to qcom-next.

udelay(1);
}

/* Clear the AMC-finished interrupt now that it's been consumed. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need this when we are clearing AMC every time before sending tcs (Line 151-53)?

uint32_t data, uint32_t *req_id);

/* Wait for command completion */
void rpmh_barrier_single(struct rpmh_client *handle, uint32_t req_id);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function may be useful in case we have any Async voting scenario, are we assuming that we will not have any such scenario?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants