interconnect: qcom: Add sync_state for Lahaina QNOC

Add sync_state functionality to remove threshold held during initial
boot up and clean up any linger proxy resources that were voted for
from bootloaders.

Change-Id: Ib2fe3f3e54775b85c3ee8107c9aafdcd32841017
Signed-off-by: David Dai <daidavid1@codeaurora.org>
This commit is contained in:
David Dai 2020-01-14 17:16:26 -08:00
commit 0850035d43
5 changed files with 72 additions and 10 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
* @init: flag to determine when init has completed.
*/
struct bcm_voter {
struct device *dev;
@ -34,6 +35,7 @@ struct bcm_voter {
struct list_head commit_list;
struct list_head ws_list;
struct list_head voter_node;
bool init;
};
static int cmp_vcd(void *priv, struct list_head *a, struct list_head *b)
@ -51,7 +53,7 @@ static int cmp_vcd(void *priv, struct list_head *a, struct list_head *b)
return 1;
}
static void bcm_aggregate(struct qcom_icc_bcm *bcm)
static void bcm_aggregate(struct qcom_icc_bcm *bcm, bool init)
{
size_t i, bucket;
u64 agg_avg[QCOM_ICC_NUM_BUCKETS] = {0};
@ -82,10 +84,18 @@ static void bcm_aggregate(struct qcom_icc_bcm *bcm)
}
if (bcm->keepalive) {
bcm->vote_x[QCOM_ICC_BUCKET_AMC] = 16000;
bcm->vote_x[QCOM_ICC_BUCKET_WAKE] = 16000;
bcm->vote_y[QCOM_ICC_BUCKET_AMC] = 16000;
bcm->vote_y[QCOM_ICC_BUCKET_WAKE] = 16000;
if (init) {
bcm->vote_x[QCOM_ICC_BUCKET_AMC] = 16000;
bcm->vote_x[QCOM_ICC_BUCKET_WAKE] = 16000;
bcm->vote_y[QCOM_ICC_BUCKET_AMC] = 16000;
bcm->vote_y[QCOM_ICC_BUCKET_WAKE] = 16000;
} else if (bcm->vote_x[QCOM_ICC_BUCKET_AMC] == 0 &&
bcm->vote_y[QCOM_ICC_BUCKET_AMC] == 0) {
bcm->vote_x[QCOM_ICC_BUCKET_AMC] = 1;
bcm->vote_x[QCOM_ICC_BUCKET_WAKE] = 1;
bcm->vote_y[QCOM_ICC_BUCKET_AMC] = 1;
bcm->vote_y[QCOM_ICC_BUCKET_WAKE] = 1;
}
}
}
@ -245,7 +255,7 @@ int qcom_icc_bcm_voter_commit(struct bcm_voter *voter)
mutex_lock(&voter->lock);
list_for_each_entry(bcm, &voter->commit_list, list)
bcm_aggregate(bcm);
bcm_aggregate(bcm, voter->init);
/*
* Pre sort the BCMs based on VCD for ease of generating a command list
@ -334,6 +344,21 @@ out:
}
EXPORT_SYMBOL(qcom_icc_bcm_voter_commit);
/**
* qcom_icc_bcm_voter_clear_init - clear init flag used during boot up
* @voter: voter that we need to clear the init flag for
*/
void qcom_icc_bcm_voter_clear_init(struct bcm_voter *voter)
{
if (!voter)
return;
mutex_lock(&voter->lock);
voter->init = false;
mutex_unlock(&voter->lock);
}
EXPORT_SYMBOL(qcom_icc_bcm_voter_clear_init);
static int qcom_icc_bcm_voter_probe(struct platform_device *pdev)
{
struct bcm_voter *voter;
@ -344,6 +369,7 @@ static int qcom_icc_bcm_voter_probe(struct platform_device *pdev)
voter->dev = &pdev->dev;
voter->np = pdev->dev.of_node;
voter->init = true;
mutex_init(&voter->lock);
INIT_LIST_HEAD(&voter->commit_list);
INIT_LIST_HEAD(&voter->ws_list);

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
*/
@ -24,5 +24,6 @@
struct bcm_voter *of_bcm_voter_get(struct device *dev, const char *name);
void qcom_icc_bcm_voter_add(struct bcm_voter *voter, struct qcom_icc_bcm *bcm);
int qcom_icc_bcm_voter_commit(struct bcm_voter *voter);
void qcom_icc_bcm_voter_clear_init(struct bcm_voter *voter);
#endif

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
*/

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
*/
@ -23,6 +23,7 @@ struct qcom_icc_provider {
struct qcom_icc_bcm **bcms;
size_t num_bcms;
struct bcm_voter *voter;
struct list_head probe_list;
};
/**

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
*/
@ -19,6 +19,11 @@
#include "icc-rpmh.h"
#include "bcm-voter.h"
static LIST_HEAD(qnoc_probe_list);
static DEFINE_MUTEX(probe_list_lock);
static int probe_count;
DEFINE_QNODE(qhm_qspi, MASTER_QSPI_0, 1, 4, 1,
SLAVE_A1NOC_SNOC);
DEFINE_QNODE(qhm_qup1, MASTER_QUP_1, 1, 4, 1,
@ -775,6 +780,10 @@ static int qnoc_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Registered LAHAINA ICC\n");
mutex_lock(&probe_list_lock);
list_add_tail(&qp->probe_list, &qnoc_probe_list);
mutex_unlock(&probe_list_lock);
return ret;
err:
list_for_each_entry(node, &provider->nodes, node_list) {
@ -829,12 +838,37 @@ static const struct of_device_id qnoc_of_match[] = {
};
MODULE_DEVICE_TABLE(of, qnoc_of_match);
static void qnoc_sync_state(struct device *dev)
{
struct qcom_icc_provider *qp;
mutex_lock(&probe_list_lock);
probe_count++;
if (probe_count < ARRAY_SIZE(qnoc_of_match) - 1) {
mutex_unlock(&probe_list_lock);
return;
}
list_for_each_entry(qp, &qnoc_probe_list, probe_list) {
int i;
for (i = 0; i < qp->num_bcms; i++)
qcom_icc_bcm_voter_add(qp->voter, qp->bcms[i]);
qcom_icc_bcm_voter_clear_init(qp->voter);
qcom_icc_bcm_voter_commit(qp->voter);
}
mutex_unlock(&probe_list_lock);
}
static struct platform_driver qnoc_driver = {
.probe = qnoc_probe,
.remove = qnoc_remove,
.driver = {
.name = "qnoc-lahaina",
.of_match_table = qnoc_of_match,
.sync_state = qnoc_sync_state,
},
};