Skip to content

Commit b92902f

Browse files
Mike TiptonGeorgi Djakov
authored andcommitted
interconnect: qcom: Support bcm-voter-specific TCS wait behavior
Currently, all bcm-voters set tcs_cmd::wait=true for the last VCD command in each TCS (AMC, WAKE, and SLEEP). However, some bcm-voters don't need the completion and instead need to optimize for latency. For instance, disabling wait-for-completion in the WAKE set can decrease resume latency and allow for certain operations to occur in parallel with the WAKE TCS triggering. This is only safe in very specific situations. Keep the default behavior of always waiting, but allow it to be overridden in devicetree. Signed-off-by: Mike Tipton <mdtipton@codeaurora.org> Link: https://lore.kernel.org/r/20200903192149.30385-5-mdtipton@codeaurora.org Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
1 parent ad4bedf commit b92902f

1 file changed

Lines changed: 21 additions & 11 deletions

File tree

drivers/interconnect/qcom/bcm-voter.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static DEFINE_MUTEX(bcm_voter_lock);
2727
* @commit_list: list containing bcms to be committed to hardware
2828
* @ws_list: list containing bcms that have different wake/sleep votes
2929
* @voter_node: list of bcm voters
30+
* @tcs_wait: mask for which buckets require TCS completion
3031
*/
3132
struct bcm_voter {
3233
struct device *dev;
@@ -35,6 +36,7 @@ struct bcm_voter {
3536
struct list_head commit_list;
3637
struct list_head ws_list;
3738
struct list_head voter_node;
39+
u32 tcs_wait;
3840
};
3941

4042
static int cmp_vcd(void *priv, struct list_head *a, struct list_head *b)
@@ -100,7 +102,7 @@ static void bcm_aggregate(struct qcom_icc_bcm *bcm)
100102
}
101103

102104
static inline void tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x, u64 vote_y,
103-
u32 addr, bool commit)
105+
u32 addr, bool commit, bool wait)
104106
{
105107
bool valid = true;
106108

@@ -125,15 +127,16 @@ static inline void tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x, u64 vote_y,
125127
* Set the wait for completion flag on command that need to be completed
126128
* before the next command.
127129
*/
128-
cmd->wait = commit;
130+
cmd->wait = wait;
129131
}
130132

131-
static void tcs_list_gen(struct list_head *bcm_list, int bucket,
132-
struct tcs_cmd tcs_list[MAX_BCMS],
133+
static void tcs_list_gen(struct bcm_voter *voter, int bucket,
134+
struct tcs_cmd tcs_list[MAX_VCD],
133135
int n[MAX_VCD + 1])
134136
{
137+
struct list_head *bcm_list = &voter->commit_list;
135138
struct qcom_icc_bcm *bcm;
136-
bool commit;
139+
bool commit, wait;
137140
size_t idx = 0, batch = 0, cur_vcd_size = 0;
138141

139142
memset(n, 0, sizeof(int) * (MAX_VCD + 1));
@@ -146,8 +149,11 @@ static void tcs_list_gen(struct list_head *bcm_list, int bucket,
146149
commit = true;
147150
cur_vcd_size = 0;
148151
}
152+
153+
wait = commit && (voter->tcs_wait & BIT(bucket));
154+
149155
tcs_cmd_gen(&tcs_list[idx], bcm->vote_x[bucket],
150-
bcm->vote_y[bucket], bcm->addr, commit);
156+
bcm->vote_y[bucket], bcm->addr, commit, wait);
151157
idx++;
152158
n[batch]++;
153159
/*
@@ -272,8 +278,7 @@ int qcom_icc_bcm_voter_commit(struct bcm_voter *voter)
272278
* Construct the command list based on a pre ordered list of BCMs
273279
* based on VCD.
274280
*/
275-
tcs_list_gen(&voter->commit_list, QCOM_ICC_BUCKET_AMC, cmds, commit_idx);
276-
281+
tcs_list_gen(voter, QCOM_ICC_BUCKET_AMC, cmds, commit_idx);
277282
if (!commit_idx[0])
278283
goto out;
279284

@@ -309,15 +314,15 @@ int qcom_icc_bcm_voter_commit(struct bcm_voter *voter)
309314

310315
list_sort(NULL, &voter->commit_list, cmp_vcd);
311316

312-
tcs_list_gen(&voter->commit_list, QCOM_ICC_BUCKET_WAKE, cmds, commit_idx);
317+
tcs_list_gen(voter, QCOM_ICC_BUCKET_WAKE, cmds, commit_idx);
313318

314319
ret = rpmh_write_batch(voter->dev, RPMH_WAKE_ONLY_STATE, cmds, commit_idx);
315320
if (ret) {
316321
pr_err("Error sending WAKE RPMH requests (%d)\n", ret);
317322
goto out;
318323
}
319324

320-
tcs_list_gen(&voter->commit_list, QCOM_ICC_BUCKET_SLEEP, cmds, commit_idx);
325+
tcs_list_gen(voter, QCOM_ICC_BUCKET_SLEEP, cmds, commit_idx);
321326

322327
ret = rpmh_write_batch(voter->dev, RPMH_SLEEP_STATE, cmds, commit_idx);
323328
if (ret) {
@@ -336,14 +341,19 @@ EXPORT_SYMBOL_GPL(qcom_icc_bcm_voter_commit);
336341

337342
static int qcom_icc_bcm_voter_probe(struct platform_device *pdev)
338343
{
344+
struct device_node *np = pdev->dev.of_node;
339345
struct bcm_voter *voter;
340346

341347
voter = devm_kzalloc(&pdev->dev, sizeof(*voter), GFP_KERNEL);
342348
if (!voter)
343349
return -ENOMEM;
344350

345351
voter->dev = &pdev->dev;
346-
voter->np = pdev->dev.of_node;
352+
voter->np = np;
353+
354+
if (of_property_read_u32(np, "qcom,tcs-wait", &voter->tcs_wait))
355+
voter->tcs_wait = QCOM_ICC_TAG_ALWAYS;
356+
347357
mutex_init(&voter->lock);
348358
INIT_LIST_HEAD(&voter->commit_list);
349359
INIT_LIST_HEAD(&voter->ws_list);

0 commit comments

Comments
 (0)