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

Commit a55b46e4 authored by David Dai's avatar David Dai
Browse files

msm: msm_bus: Add ACV voting



Vote on behalf of clients with requests to ebi_slv as destination,
ACV is one-hot encoded to indicate which master port is actively
requesting bandwidth to the ddr controller. Currently using
DRV voted on as an indicator for ACV coding.

Change-Id: I5e3dc56e34e3d748e73952c65abca739cc62458d
Signed-off-by: default avatarDavid Dai <daidavid1@codeaurora.org>
parent 0e6032e3
Loading
Loading
Loading
Loading
+74 −27
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@

#define MSM_BUS_MAS_ALC			144
#define MSM_BUS_RSC_APPS		8000
#define MSM_BUS_RSC_DISP		8001
#define BCM_TCS_CMD_ACV_APPS		0x8

struct bus_search_type {
	struct list_head link;
@@ -127,16 +129,14 @@ static void bcm_add_bus_req(struct device *dev)
		goto exit_bcm_add_bus_req;
	}

	if (cur_dev->node_info->bcm_req_idx != -1)
		goto exit_bcm_add_bus_req;

	if (!cur_dev->node_info->num_bcm_devs)
		goto exit_bcm_add_bus_req;

	for (i = 0; i < cur_dev->node_info->num_bcm_devs; i++) {
		if (cur_dev->node_info->bcm_req_idx[i] != -1)
			continue;
		bcm_dev = to_msm_bus_node(cur_dev->node_info->bcm_devs[i]);
		max_num_lnodes = bcm_dev->bcmdev->num_bus_devs;

		if (!bcm_dev->num_lnodes) {
			bcm_dev->lnode_list = devm_kzalloc(dev,
				sizeof(struct link_node) * max_num_lnodes,
@@ -183,7 +183,7 @@ static void bcm_add_bus_req(struct device *dev)

		lnode->in_use = 1;
		lnode->bus_dev_id = cur_dev->node_info->id;
		cur_dev->node_info->bcm_req_idx = lnode_idx;
		cur_dev->node_info->bcm_req_idx[i] = lnode_idx;
		memset(lnode->lnode_ib, 0, sizeof(uint64_t) * NUM_CTX);
		memset(lnode->lnode_ab, 0, sizeof(uint64_t) * NUM_CTX);
	}
@@ -483,11 +483,35 @@ static int getpath(struct device *src_dev, int dest, const char *cl_name)
	return first_hop;
}

static void bcm_update_acv_req(struct msm_bus_node_device_type *cur_rsc,
				uint64_t max_ab, uint64_t max_ib,
				uint64_t *vec_a, uint64_t *vec_b,
				uint32_t *acv, int ctx)
{
	uint32_t acv_bmsk = 0;
	/*
	 * Base ACV voting on current RSC until mapping is set up in commanddb
	 * that allows us to vote ACV based on master.
	 */

	if (cur_rsc->node_info->id == MSM_BUS_RSC_APPS)
		acv_bmsk = BCM_TCS_CMD_ACV_APPS;

	if (max_ab == 0 && max_ib == 0)
		*acv = *acv & ~acv_bmsk;
	else
		*acv = *acv | acv_bmsk;
	*vec_a = 0;
	*vec_b = *acv;
}

static void bcm_update_bus_req(struct device *dev, int ctx)
{
	struct msm_bus_node_device_type *cur_dev = NULL;
	struct msm_bus_node_device_type *bcm_dev = NULL;
	int i;
	struct msm_bus_node_device_type *cur_rsc = NULL;

	int i, j;
	uint64_t max_ib = 0;
	uint64_t max_ab = 0;
	int lnode_idx = 0;
@@ -507,7 +531,7 @@ static void bcm_update_bus_req(struct device *dev, int ctx)
		if (!bcm_dev)
			goto exit_bcm_update_bus_req;

		lnode_idx = cur_dev->node_info->bcm_req_idx;
		lnode_idx = cur_dev->node_info->bcm_req_idx[i];
		bcm_dev->lnode_list[lnode_idx].lnode_ib[ctx] =
			msm_bus_div64(cur_dev->node_bw[ctx].max_ib *
					(uint64_t)bcm_dev->bcmdev->width,
@@ -519,19 +543,19 @@ static void bcm_update_bus_req(struct device *dev, int ctx)
				cur_dev->node_info->agg_params.buswidth *
				cur_dev->node_info->agg_params.num_aggports);

		for (i = 0; i < bcm_dev->num_lnodes; i++) {
		for (j = 0; j < bcm_dev->num_lnodes; j++) {
			if (ctx == ACTIVE_CTX) {
				max_ib = max(max_ib,
				max(bcm_dev->lnode_list[i].lnode_ib[ACTIVE_CTX],
				bcm_dev->lnode_list[i].lnode_ib[DUAL_CTX]));
				max(bcm_dev->lnode_list[j].lnode_ib[ACTIVE_CTX],
				bcm_dev->lnode_list[j].lnode_ib[DUAL_CTX]));
				max_ab = max(max_ab,
				bcm_dev->lnode_list[i].lnode_ab[ACTIVE_CTX] +
				bcm_dev->lnode_list[i].lnode_ab[DUAL_CTX]);
				bcm_dev->lnode_list[j].lnode_ab[ACTIVE_CTX] +
				bcm_dev->lnode_list[j].lnode_ab[DUAL_CTX]);
			} else {
				max_ib = max(max_ib,
					bcm_dev->lnode_list[i].lnode_ib[ctx]);
					bcm_dev->lnode_list[j].lnode_ib[ctx]);
				max_ab = max(max_ab,
					bcm_dev->lnode_list[i].lnode_ab[ctx]);
					bcm_dev->lnode_list[j].lnode_ab[ctx]);
			}
		}
		bcm_dev->node_bw[ctx].max_ab = max_ab;
@@ -540,9 +564,19 @@ static void bcm_update_bus_req(struct device *dev, int ctx)
		max_ab = msm_bus_div64(max_ab, bcm_dev->bcmdev->unit_size);
		max_ib = msm_bus_div64(max_ib, bcm_dev->bcmdev->unit_size);

		if (bcm_dev->node_info->id == MSM_BUS_BCM_ACV) {
			cur_rsc = to_msm_bus_node(bcm_dev->node_info->
						rsc_devs[0]);
			bcm_update_acv_req(cur_rsc, max_ab, max_ib,
					&bcm_dev->node_vec[ctx].vec_a,
					&bcm_dev->node_vec[ctx].vec_b,
					&cur_rsc->rscdev->acv[ctx], ctx);

		} else {
			bcm_dev->node_vec[ctx].vec_a = max_ab;
			bcm_dev->node_vec[ctx].vec_b = max_ib;
		}
	}
exit_bcm_update_bus_req:
	return;
}
@@ -551,7 +585,8 @@ static void bcm_query_bus_req(struct device *dev, int ctx)
{
	struct msm_bus_node_device_type *cur_dev = NULL;
	struct msm_bus_node_device_type *bcm_dev = NULL;
	int i;
	struct msm_bus_node_device_type *cur_rsc = NULL;
	int i, j;
	uint64_t max_query_ib = 0;
	uint64_t max_query_ab = 0;
	int lnode_idx = 0;
@@ -571,7 +606,7 @@ static void bcm_query_bus_req(struct device *dev, int ctx)
		if (!bcm_dev)
			goto exit_bcm_query_bus_req;

		lnode_idx = cur_dev->node_info->bcm_req_idx;
		lnode_idx = cur_dev->node_info->bcm_req_idx[i];
		bcm_dev->lnode_list[lnode_idx].lnode_query_ib[ctx] =
			msm_bus_div64(cur_dev->node_bw[ctx].max_query_ib *
					(uint64_t)bcm_dev->bcmdev->width,
@@ -583,25 +618,25 @@ static void bcm_query_bus_req(struct device *dev, int ctx)
				cur_dev->node_info->agg_params.num_aggports *
				cur_dev->node_info->agg_params.buswidth);

		for (i = 0; i < bcm_dev->num_lnodes; i++) {
		for (j = 0; j < bcm_dev->num_lnodes; j++) {
			if (ctx == ACTIVE_CTX) {
				max_query_ib = max(max_query_ib,
				max(bcm_dev->lnode_list[i].
				max(bcm_dev->lnode_list[j].
					lnode_query_ib[ACTIVE_CTX],
				bcm_dev->lnode_list[i].
				bcm_dev->lnode_list[j].
					lnode_query_ib[DUAL_CTX]));

				max_query_ab = max(max_query_ab,
				bcm_dev->lnode_list[i].
				bcm_dev->lnode_list[j].
						lnode_query_ab[ACTIVE_CTX] +
				bcm_dev->lnode_list[i].
				bcm_dev->lnode_list[j].
						lnode_query_ab[DUAL_CTX]);
			} else {
				max_query_ib = max(max_query_ib,
					bcm_dev->lnode_list[i].
					bcm_dev->lnode_list[j].
						lnode_query_ib[ctx]);
				max_query_ab = max(max_query_ab,
					bcm_dev->lnode_list[i].
					bcm_dev->lnode_list[j].
						lnode_query_ab[ctx]);
			}
		}
@@ -611,6 +646,18 @@ static void bcm_query_bus_req(struct device *dev, int ctx)
		max_query_ib = msm_bus_div64(max_query_ib,
						bcm_dev->bcmdev->unit_size);

		if (bcm_dev->node_info->id == MSM_BUS_BCM_ACV) {
			cur_rsc = to_msm_bus_node(bcm_dev->node_info->
						rsc_devs[0]);
			bcm_update_acv_req(cur_rsc, max_query_ab, max_query_ib,
					&bcm_dev->node_vec[ctx].query_vec_a,
					&bcm_dev->node_vec[ctx].query_vec_b,
					&cur_rsc->rscdev->query_acv[ctx], ctx);
		} else {
			bcm_dev->node_vec[ctx].query_vec_a = max_query_ab;
			bcm_dev->node_vec[ctx].query_vec_b = max_query_ib;
		}

		bcm_dev->node_bw[ctx].max_query_ab = max_query_ab;
		bcm_dev->node_bw[ctx].max_query_ib = max_query_ib;
	}
+48 −25
Original line number Diff line number Diff line
@@ -418,8 +418,8 @@ static int tcs_cmd_query_list_gen(struct tcs_cmd *cmdlist_active)
				commit = true;
			}
			tcs_cmd_gen(cur_bcm, &cmdlist_active[k],
				cur_bcm->node_bw[ACTIVE_CTX].max_query_ib,
				cur_bcm->node_bw[ACTIVE_CTX].max_query_ab,
				cur_bcm->node_vec[ACTIVE_CTX].query_vec_a,
				cur_bcm->node_vec[ACTIVE_CTX].query_vec_b,
								commit);
			k++;
		}
@@ -433,19 +433,22 @@ static int bcm_clist_add(struct msm_bus_node_device_type *cur_dev)
{
	int ret = 0;
	int cur_vcd = 0;
	int i = 0;
	struct msm_bus_node_device_type *cur_bcm = NULL;

	if (!cur_dev->node_info->num_bcm_devs)
		goto exit_bcm_clist_add;

	cur_bcm = to_msm_bus_node(cur_dev->node_info->bcm_devs[0]);
	for (i = 0; i < cur_dev->node_info->num_bcm_devs; i++) {
		cur_bcm = to_msm_bus_node(cur_dev->node_info->bcm_devs[i]);
		cur_vcd = cur_bcm->bcmdev->clk_domain;

		if (!cur_bcm->node_info->num_rsc_devs)
			goto exit_bcm_clist_add;

		if (!cur_rsc)
		cur_rsc = to_msm_bus_node(cur_bcm->node_info->rsc_devs[0]);
			cur_rsc = to_msm_bus_node(cur_bcm->node_info->
								rsc_devs[0]);

		if (!cur_bcm->dirty) {
			list_add_tail(&cur_bcm->link,
@@ -453,6 +456,7 @@ static int bcm_clist_add(struct msm_bus_node_device_type *cur_dev)
			cur_bcm->dirty = true;
		}
		cur_bcm->updated = false;
	}

exit_bcm_clist_add:
	return ret;
@@ -462,17 +466,20 @@ static int bcm_query_list_add(struct msm_bus_node_device_type *cur_dev)
{
	int ret = 0;
	int cur_vcd = 0;
	int i = 0;
	struct msm_bus_node_device_type *cur_bcm = NULL;

	if (!cur_dev->node_info->num_bcm_devs)
		goto exit_bcm_query_list_add;

	cur_bcm = to_msm_bus_node(cur_dev->node_info->bcm_devs[0]);
	for (i = 0; i < cur_dev->node_info->num_bcm_devs; i++) {
		cur_bcm = to_msm_bus_node(cur_dev->node_info->bcm_devs[i]);
		cur_vcd = cur_bcm->bcmdev->clk_domain;

		if (!cur_bcm->query_dirty)
			list_add_tail(&cur_bcm->query_link,
					&bcm_query_list_inorder[cur_vcd]);
	}

exit_bcm_query_list_add:
	return ret;
@@ -481,12 +488,14 @@ static int bcm_query_list_add(struct msm_bus_node_device_type *cur_dev)
static int bcm_clist_clean(struct msm_bus_node_device_type *cur_dev)
{
	int ret = 0;
	int i = 0;
	struct msm_bus_node_device_type *cur_bcm = NULL;

	if (!cur_dev->node_info->num_bcm_devs)
		goto exit_bcm_clist_clean;

	cur_bcm = to_msm_bus_node(cur_dev->node_info->bcm_devs[0]);
	for (i = 0; i < cur_dev->node_info->num_bcm_devs; i++) {
		cur_bcm = to_msm_bus_node(cur_dev->node_info->bcm_devs[i]);

		if (cur_bcm->node_vec[DUAL_CTX].vec_a == 0 &&
			cur_bcm->node_vec[ACTIVE_CTX].vec_a == 0 &&
@@ -496,6 +505,7 @@ static int bcm_clist_clean(struct msm_bus_node_device_type *cur_dev)
			cur_bcm->dirty = false;
			list_del_init(&cur_bcm->link);
		}
	}

exit_bcm_clist_clean:
	return ret;
@@ -504,15 +514,18 @@ static int bcm_clist_clean(struct msm_bus_node_device_type *cur_dev)
static int bcm_query_list_clean(struct msm_bus_node_device_type *cur_dev)
{
	int ret = 0;
	int i = 0;
	struct msm_bus_node_device_type *cur_bcm = NULL;

	if (!cur_dev->node_info->num_bcm_devs)
		goto exit_bcm_clist_add;

	cur_bcm = to_msm_bus_node(cur_dev->node_info->bcm_devs[0]);
	for (i = 0; i < cur_dev->node_info->num_bcm_devs; i++) {
		cur_bcm = to_msm_bus_node(cur_dev->node_info->bcm_devs[i]);

		cur_bcm->query_dirty = false;
		list_del_init(&cur_bcm->query_link);
	}

exit_bcm_clist_add:
	return ret;
@@ -1081,7 +1094,7 @@ static int msm_bus_init_clk(struct device *bus_dev,
static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata,
				struct device *bus_dev)
{
	int ret = 0;
	int ret = 0, i = 0;
	struct msm_bus_node_info_type *node_info = NULL;
	struct msm_bus_node_info_type *pdata_node_info = NULL;
	struct msm_bus_node_device_type *bus_node = NULL;
@@ -1100,7 +1113,17 @@ static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata,

	node_info->name = pdata_node_info->name;
	node_info->id =  pdata_node_info->id;
	node_info->bcm_req_idx = -1;
	node_info->bcm_req_idx = devm_kzalloc(bus_dev,
			sizeof(int) * pdata_node_info->num_bcm_devs,
			GFP_KERNEL);
	if (!node_info->bcm_req_idx) {
		ret = -ENOMEM;
		goto exit_copy_node_info;
	}

	for (i = 0; i < pdata_node_info->num_bcm_devs; i++)
		node_info->bcm_req_idx[i] = -1;

	node_info->bus_device_id = pdata_node_info->bus_device_id;
	node_info->mas_rpm_id = pdata_node_info->mas_rpm_id;
	node_info->slv_rpm_id = pdata_node_info->slv_rpm_id;
+5 −1
Original line number Diff line number Diff line
@@ -71,12 +71,16 @@ struct nodebw {
struct nodevector {
	uint64_t vec_a;
	uint64_t vec_b;
	uint64_t query_vec_a;
	uint64_t query_vec_b;
};

struct msm_bus_rsc_device_type {
	struct rpmh_client *mbox;
	struct list_head bcm_clist[VCD_MAX_CNT];
	int req_state;
	uint32_t acv[NUM_CTX];
	uint32_t query_acv[NUM_CTX];
};

struct msm_bus_bcm_device_type {
@@ -157,7 +161,7 @@ struct msm_bus_node_info_type {
	struct device **black_connections;
	struct device **bcm_devs;
	struct device **rsc_devs;
	int bcm_req_idx;
	int *bcm_req_idx;
	unsigned int bus_device_id;
	struct device *bus_device;
	struct rule_update_path_info rule;