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

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

Merge "drivers: qcom: rpmh-rsc: increase debug verbosity"

parents 9f69e682 02c9f337
Loading
Loading
Loading
Loading
+29 −22
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt) "%s " fmt, KBUILD_MODNAME
@@ -66,6 +66,13 @@
#define RSC_PDC_DRV_DATA		0x38
#define RSC_PDC_DATA_OFFSET		0x08

#define ACCL_TYPE(addr)			((addr >> 16) & 0xF)
#define NR_ACCL_TYPES			3

static const char * const accl_str[] = {
	"", "", "", "CLK", "VREG", "BUS",
};

bool rpmh_standalone;
static struct rsc_drv *__rsc_drv[2];
static int __rsc_count;
@@ -630,11 +637,10 @@ static struct tcs_group *get_tcs_from_index(struct rsc_drv *drv, int tcs_id)
	return NULL;
}

static void print_tcs_info(struct rsc_drv *drv, int tcs_id)
static void print_tcs_info(struct rsc_drv *drv, int tcs_id, unsigned long *accl)
{
	struct tcs_group *tcs_grp = get_tcs_from_index(drv, tcs_id);
	const struct tcs_request *req = get_req_from_tcs(drv, tcs_id);
	struct tcs_cmd *cmd;
	unsigned long cmds_enabled;
	u32 addr, data, msgid, sts, irq_sts;
	bool in_use = test_bit(tcs_id, drv->tcs_in_use);
@@ -658,29 +664,17 @@ static void print_tcs_info(struct rsc_drv *drv, int tcs_id)
		tcs_id, sts ? "IDLE" : "BUSY", data,
		(irq_sts & BIT(tcs_id)) ? "COMPLETED" : "PENDING");

	for (i = 0; i < req->num_cmds; i++) {
		cmd = &req->cmds[i];
		pr_warn("\tREQ=%d [addr=0x%x data=0x%x wait=0x%x]\n",
			i, cmd->addr, cmd->data, cmd->wait);

		if (i < MAX_CMDS_PER_TCS) {
			addr = read_tcs_reg(drv, RSC_DRV_CMD_ADDR, tcs_id, i);
			data = read_tcs_reg(drv, RSC_DRV_CMD_DATA, tcs_id, i);
			msgid = read_tcs_reg(drv, RSC_DRV_CMD_MSGID, tcs_id, i);
			sts = read_tcs_reg(drv, RSC_DRV_CMD_STATUS, tcs_id, i);
			pr_warn("\tCMD=%d [addr=0x%x data=0x%x hdr=0x%x sts=0x%x enabled=%ld]\n",
				i, addr, data, msgid, sts,
				(cmds_enabled & BIT(i)));
		}
	}

	for_each_set_bit_from(i, &cmds_enabled, MAX_CMDS_PER_TCS) {
	for_each_set_bit(i, &cmds_enabled, MAX_CMDS_PER_TCS) {
		addr = read_tcs_reg(drv, RSC_DRV_CMD_ADDR, tcs_id, i);
		data = read_tcs_reg(drv, RSC_DRV_CMD_DATA, tcs_id, i);
		msgid = read_tcs_reg(drv, RSC_DRV_CMD_MSGID, tcs_id, i);
		sts = read_tcs_reg(drv, RSC_DRV_CMD_STATUS, tcs_id, i);
		pr_warn("\tCMD=%d [addr=0x%x data=0x%x hdr=0x%x sts=0x%x enabled=1]\n",
			i, addr, data, msgid, sts);
		if (!(sts & CMD_STATUS_ISSUED))
			continue;
		if (!(sts & CMD_STATUS_COMPL))
			*accl |= BIT(ACCL_TYPE(addr));
	}
}

@@ -690,6 +684,8 @@ void rpmh_rsc_debug(struct rsc_drv *drv)
	bool irq_sts;
	int i;
	int busy = 0;
	unsigned long accl = 0;
	char str[20] = "";

	pr_warn("RSC:%s\n", drv->name);

@@ -697,7 +693,7 @@ void rpmh_rsc_debug(struct rsc_drv *drv)
		if (!test_bit(i, drv->tcs_in_use))
			continue;
		busy++;
		print_tcs_info(drv, i);
		print_tcs_info(drv, i, &accl);
	}

	if (!rsc_irq_data) {
@@ -709,6 +705,17 @@ void rpmh_rsc_debug(struct rsc_drv *drv)
	pr_warn("HW IRQ %lu is %s at GIC\n", rsc_irq_data->hwirq,
		irq_sts ? "PENDING" : "NOT PENDING");

	for_each_set_bit(i, &accl, ARRAY_SIZE(accl_str)) {
		strlcat(str, accl_str[i], sizeof(str));
		strlcat(str, " ", sizeof(str));
	}

	if (busy && !irq_sts)
		pr_warn("ERROR:Accelerator(s) { %s } at AOSS did not respond\n",
			str);
	else if (irq_sts)
		pr_warn("ERROR:Possible lockup in Linux\n");

	/*
	 * The TCS(s) are busy waiting, we have no way to recover from this.
	 * If this debug function is called, we assume it's because timeout
+21 −13
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ void rpmh_tx_done(const struct tcs_request *msg, int r)
	struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request,
						    msg);
	struct completion *compl = rpm_msg->completion;
	bool free = rpm_msg->needs_free;

	rpm_msg->err = r;

@@ -131,7 +132,7 @@ void rpmh_tx_done(const struct tcs_request *msg, int r)
	complete(compl);

exit:
	if (rpm_msg->needs_free)
	if (free)
		kfree(rpm_msg);
}

@@ -400,11 +401,12 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
{
	struct batch_cache_req *req;
	struct rpmh_request *rpm_msgs;
	DECLARE_COMPLETION_ONSTACK(compl);
	struct completion *compls;
	struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
	unsigned long time_left;
	int count = 0;
	int ret, i, j;
	int ret, i;
	void *ptr;

	if (!cmd || !n)
		return -EINVAL;
@@ -421,10 +423,15 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
	if (!count)
		return -EINVAL;

	req = kzalloc(sizeof(*req) + count * sizeof(req->rpm_msgs[0]),
	ptr = kzalloc(sizeof(*req) +
		      count * (sizeof(req->rpm_msgs[0]) + sizeof(*compls)),
		      GFP_ATOMIC);
	if (!req)
	if (!ptr)
		return -ENOMEM;

	req = ptr;
	compls = ptr + sizeof(*req) + count * sizeof(*rpm_msgs);

	req->count = count;
	rpm_msgs = req->rpm_msgs;

@@ -439,25 +446,26 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
	}

	for (i = 0; i < count; i++) {
		rpm_msgs[i].completion = &compl;
		struct completion *compl = &compls[i];

		init_completion(compl);
		rpm_msgs[i].completion = compl;
		ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msgs[i].msg);
		if (ret) {
			pr_err("Error(%d) sending RPMH message addr=%#x\n",
			       ret, rpm_msgs[i].msg.cmds[0].addr);
			for (j = i; j < count; j++)
				rpmh_tx_done(&rpm_msgs[j].msg, ret);
			break;
		}
	}

	time_left = RPMH_TIMEOUT_MS;
	for (i = 0; i < count; i++) {
		time_left = wait_for_completion_timeout(&compl, time_left);
	while (i--) {
		time_left = wait_for_completion_timeout(&compls[i], time_left);
		if (!time_left) {
			/*
			 * Better hope they never finish because they'll signal
			 * the completion on our stack and that's bad once
			 * we've returned from the function.
			 * the completion that we're going to free once
			 * we've returned from this function.
			 */
			rpmh_rsc_debug(ctrlr_to_drv(ctrlr));
			ret = -ETIMEDOUT;
@@ -466,7 +474,7 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
	}

exit:
	kfree(req);
	kfree(ptr);

	return ret;
}