Merge "interconnect: qcom: Support bcm-voter-specific TCS wait behavior"

This commit is contained in:
qctecmdr 2020-03-20 09:40:40 -07:00 • committed by Gerrit - the friendly Code Review server
commit da61f2ab29
3 changed files with 42 additions and 26 deletions

View file

@ -26,6 +26,7 @@ static LIST_HEAD(bcm_voters);
* @commit_list: list containing bcms to be committed to hardware
* @ws_list: list containing bcms that have different wake/sleep votes
* @voter_node: list of bcm voters
* @tcs_wait: mask for which buckets require TCS completion
* @init: flag to determine when init has completed.
*/
struct bcm_voter {
@ -35,6 +36,7 @@ struct bcm_voter {
struct list_head commit_list;
struct list_head ws_list;
struct list_head voter_node;
u32 tcs_wait;
bool init;
};
@ -128,11 +130,12 @@ static inline void tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x, u64 vote_y,
cmd->wait = commit;
}
static void tcs_list_gen(struct list_head *bcm_list, int bucket,
static void tcs_list_gen(struct bcm_voter *voter, int bucket,
struct tcs_cmd tcs_list[MAX_VCD],
int n[MAX_VCD])
{
struct qcom_icc_bcm *bcm;
struct list_head *bcm_list = &voter->commit_list;
bool commit;
size_t idx = 0, batch = 0, cur_vcd_size = 0;
@ -144,8 +147,9 @@ static void tcs_list_gen(struct list_head *bcm_list, int bucket,
if ((list_is_last(&bcm->list, bcm_list)) ||
bcm->aux_data.vcd !=
list_next_entry(bcm, list)->aux_data.vcd) {
commit = true;
cur_vcd_size = 0;
if (voter->tcs_wait & BIT(bucket))
commit = true;
}
tcs_cmd_gen(&tcs_list[idx], bcm->vote_x[bucket],
bcm->vote_y[bucket], bcm->addr, commit);
@ -272,9 +276,7 @@ int qcom_icc_bcm_voter_commit(struct bcm_voter *voter)
* Construct the command list based on a pre ordered list of BCMs
* based on VCD.
*/
tcs_list_gen(&voter->commit_list, QCOM_ICC_BUCKET_AMC, cmds,
commit_idx);
tcs_list_gen(voter, QCOM_ICC_BUCKET_AMC, cmds, commit_idx);
if (!commit_idx[0])
goto out;
@ -328,8 +330,7 @@ int qcom_icc_bcm_voter_commit(struct bcm_voter *voter)
list_sort(NULL, &voter->commit_list, cmp_vcd);
tcs_list_gen(&voter->commit_list, QCOM_ICC_BUCKET_WAKE, cmds,
commit_idx);
tcs_list_gen(voter, QCOM_ICC_BUCKET_WAKE, cmds, commit_idx);
ret = rpmh_write_batch(voter->dev, RPMH_WAKE_ONLY_STATE, cmds,
commit_idx);
@ -338,8 +339,7 @@ int qcom_icc_bcm_voter_commit(struct bcm_voter *voter)
goto out;
}
tcs_list_gen(&voter->commit_list, QCOM_ICC_BUCKET_SLEEP, cmds,
commit_idx);
tcs_list_gen(voter, QCOM_ICC_BUCKET_SLEEP, cmds, commit_idx);
ret = rpmh_write_batch(voter->dev, RPMH_SLEEP_STATE, cmds, commit_idx);
if (ret) {
@ -374,6 +374,7 @@ EXPORT_SYMBOL(qcom_icc_bcm_voter_clear_init);
static int qcom_icc_bcm_voter_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct bcm_voter *voter;
voter = devm_kzalloc(&pdev->dev, sizeof(*voter), GFP_KERNEL);
@ -381,8 +382,12 @@ static int qcom_icc_bcm_voter_probe(struct platform_device *pdev)
return -ENOMEM;
voter->dev = &pdev->dev;
voter->np = pdev->dev.of_node;
voter->np = np;
voter->init = true;
if (of_property_read_u32(np, "qcom,tcs-wait", &voter->tcs_wait))
voter->tcs_wait = QCOM_ICC_TAG_ACTIVE_ONLY;
mutex_init(&voter->lock);
INIT_LIST_HEAD(&voter->commit_list);
INIT_LIST_HEAD(&voter->ws_list);

View file

@ -8,6 +8,7 @@
#define __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__
#include <linux/regmap.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#define to_qcom_provider(_provider) \
container_of(_provider, struct qcom_icc_provider, provider)
@ -51,22 +52,6 @@ struct bcm_db {
#define MAX_BCM_PER_NODE 3
#define MAX_VCD 10
/*
* The AMC bucket denotes constraints that are applied to hardware when
* icc_set_bw() completes, whereas the WAKE and SLEEP constraints are applied
* when the execution environment transitions between active and low power mode.
*/
#define QCOM_ICC_BUCKET_AMC 0
#define QCOM_ICC_BUCKET_WAKE 1
#define QCOM_ICC_BUCKET_SLEEP 2
#define QCOM_ICC_NUM_BUCKETS 3
#define QCOM_ICC_TAG_AMC BIT(QCOM_ICC_BUCKET_AMC)
#define QCOM_ICC_TAG_WAKE BIT(QCOM_ICC_BUCKET_WAKE)
#define QCOM_ICC_TAG_SLEEP BIT(QCOM_ICC_BUCKET_SLEEP)
#define QCOM_ICC_TAG_ACTIVE_ONLY (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE)
#define QCOM_ICC_TAG_ALWAYS (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\
QCOM_ICC_TAG_SLEEP)
/**
* struct qcom_icc_node - QTI specific interconnect nodes
* @name: the node name used in debugfs

View file

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_ICC_H
#define __DT_BINDINGS_INTERCONNECT_QCOM_ICC_H
/*
* The AMC bucket denotes constraints that are applied to hardware when
* icc_set_bw() completes, whereas the WAKE and SLEEP constraints are applied
* when the execution environment transitions between active and low power mode.
*/
#define QCOM_ICC_BUCKET_AMC 0
#define QCOM_ICC_BUCKET_WAKE 1
#define QCOM_ICC_BUCKET_SLEEP 2
#define QCOM_ICC_NUM_BUCKETS 3
#define QCOM_ICC_TAG_AMC (1 << QCOM_ICC_BUCKET_AMC)
#define QCOM_ICC_TAG_WAKE (1 << QCOM_ICC_BUCKET_WAKE)
#define QCOM_ICC_TAG_SLEEP (1 << QCOM_ICC_BUCKET_SLEEP)
#define QCOM_ICC_TAG_ACTIVE_ONLY (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE)
#define QCOM_ICC_TAG_ALWAYS (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\
QCOM_ICC_TAG_SLEEP)
#endif