mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 13:44:26 -04:00
interconnect: qcom: Set QoS on the first bandwidth request
Move the QoS configuration to happen on the first non-zero bandwidth request from the consumer driver. This allows configuring QoS also for consumers like IPA, which can probe asynchronously and their clock should not be touched until the firmware has completed booting. Change-Id: I2a8e385d99f3c489d920a7c85e9415d540f6df87 Signed-off-by: Georgi Djakov <gdjako@codeaurora.org> Signed-off-by: Mike Tipton <mdtipton@codeaurora.org>
This commit is contained in:
parent
e51f74d2f1
commit
ce50100300
3 changed files with 18 additions and 14 deletions
|
|
@ -6,11 +6,13 @@
|
|||
|
||||
#include <asm/div64.h>
|
||||
#include <dt-bindings/interconnect/qcom,sdm845.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/interconnect.h>
|
||||
#include <linux/interconnect-provider.h>
|
||||
|
||||
#include "icc-rpmh.h"
|
||||
#include "bcm-voter.h"
|
||||
#include "qnoc-qos.h"
|
||||
|
||||
/**
|
||||
* qcom_icc_pre_aggregate - cleans up stale values from prior icc_set
|
||||
|
|
@ -80,6 +82,7 @@ EXPORT_SYMBOL(qcom_icc_aggregate);
|
|||
int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
|
||||
{
|
||||
struct qcom_icc_provider *qp;
|
||||
struct qcom_icc_node *qn;
|
||||
struct icc_node *node;
|
||||
int i;
|
||||
|
||||
|
|
@ -89,10 +92,20 @@ int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
|
|||
node = src;
|
||||
|
||||
qp = to_qcom_provider(node->provider);
|
||||
qn = node->data;
|
||||
|
||||
for (i = 0; i < qp->num_voters; i++)
|
||||
qcom_icc_bcm_voter_commit(qp->voters[i]);
|
||||
|
||||
/* Defer setting QoS until the first non-zero bandwidth request. */
|
||||
if (qn && qn->qosbox && !qn->qosbox->initialized &&
|
||||
(node->avg_bw || node->peak_bw)) {
|
||||
clk_bulk_prepare_enable(qp->num_clks, qp->clks);
|
||||
qn->noc_ops->set_qos(qn);
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->clks);
|
||||
qn->qosbox->initialized = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_icc_set);
|
||||
|
|
|
|||
|
|
@ -991,6 +991,8 @@ err:
|
|||
icc_node_destroy(node->id);
|
||||
}
|
||||
|
||||
clk_bulk_put_all(qp->num_clks, qp->clks);
|
||||
|
||||
icc_provider_del(provider);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1006,6 +1008,8 @@ static int qnoc_remove(struct platform_device *pdev)
|
|||
icc_node_destroy(n->id);
|
||||
}
|
||||
|
||||
clk_bulk_put_all(qp->num_clks, qp->clks);
|
||||
|
||||
return icc_provider_del(provider);
|
||||
}
|
||||
|
||||
|
|
@ -1040,26 +1044,12 @@ static void qnoc_sync_state(struct device *dev)
|
|||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
|
||||
struct icc_provider *provider = &qp->provider;
|
||||
struct qcom_icc_node *qnode;
|
||||
struct qcom_icc_bcm *bcm;
|
||||
struct bcm_voter *voter;
|
||||
struct icc_node *node;
|
||||
|
||||
mutex_lock(&probe_list_lock);
|
||||
probe_count++;
|
||||
|
||||
clk_bulk_prepare_enable(qp->num_clks, qp->clks);
|
||||
|
||||
list_for_each_entry(node, &provider->nodes, node_list) {
|
||||
qnode = node->data;
|
||||
if (qnode && qnode->noc_ops)
|
||||
qnode->noc_ops->set_qos(qnode);
|
||||
}
|
||||
|
||||
clk_bulk_disable_unprepare(qp->num_clks, qp->clks);
|
||||
clk_bulk_put_all(qp->num_clks, qp->clks);
|
||||
|
||||
if (probe_count < ARRAY_SIZE(qnoc_of_match) - 1) {
|
||||
mutex_unlock(&probe_list_lock);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ struct qos_config {
|
|||
struct qcom_icc_qosbox {
|
||||
u32 num_ports;
|
||||
const u8 *regs;
|
||||
bool initialized;
|
||||
struct qos_config *config;
|
||||
u32 offsets[];
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue