Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da61f2ab authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents 4fb04ec2 dd27df61
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -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);
+1 −16
Original line number Diff line number Diff line
@@ -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
+26 −0
Original line number Diff line number Diff line
/* 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