xref: /openbmc/linux/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1b9b721d1SSai Prakash Ranjan // SPDX-License-Identifier: GPL-2.0-only
2b9b721d1SSai Prakash Ranjan /*
3b9b721d1SSai Prakash Ranjan  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4b9b721d1SSai Prakash Ranjan  */
5b9b721d1SSai Prakash Ranjan 
6*d477f603SRob Herring #include <linux/device.h>
73bf90ecaSElliot Berman #include <linux/firmware/qcom/qcom_scm.h>
8b9b721d1SSai Prakash Ranjan #include <linux/ratelimit.h>
9b9b721d1SSai Prakash Ranjan 
10b9b721d1SSai Prakash Ranjan #include "arm-smmu.h"
11b9b721d1SSai Prakash Ranjan #include "arm-smmu-qcom.h"
12b9b721d1SSai Prakash Ranjan 
qcom_smmu_tlb_sync_debug(struct arm_smmu_device * smmu)13b9b721d1SSai Prakash Ranjan void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu)
14b9b721d1SSai Prakash Ranjan {
15b9b721d1SSai Prakash Ranjan 	int ret;
16b9b721d1SSai Prakash Ranjan 	u32 tbu_pwr_status, sync_inv_ack, sync_inv_progress;
17b9b721d1SSai Prakash Ranjan 	struct qcom_smmu *qsmmu = container_of(smmu, struct qcom_smmu, smmu);
18b9b721d1SSai Prakash Ranjan 	const struct qcom_smmu_config *cfg;
19b9b721d1SSai Prakash Ranjan 	static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
20b9b721d1SSai Prakash Ranjan 				      DEFAULT_RATELIMIT_BURST);
21b9b721d1SSai Prakash Ranjan 
22b9b721d1SSai Prakash Ranjan 	if (__ratelimit(&rs)) {
23b9b721d1SSai Prakash Ranjan 		dev_err(smmu->dev, "TLB sync timed out -- SMMU may be deadlocked\n");
24b9b721d1SSai Prakash Ranjan 
25b9b721d1SSai Prakash Ranjan 		cfg = qsmmu->cfg;
26b9b721d1SSai Prakash Ranjan 		if (!cfg)
27b9b721d1SSai Prakash Ranjan 			return;
28b9b721d1SSai Prakash Ranjan 
29b9b721d1SSai Prakash Ranjan 		ret = qcom_scm_io_readl(smmu->ioaddr + cfg->reg_offset[QCOM_SMMU_TBU_PWR_STATUS],
30b9b721d1SSai Prakash Ranjan 					&tbu_pwr_status);
31b9b721d1SSai Prakash Ranjan 		if (ret)
32b9b721d1SSai Prakash Ranjan 			dev_err(smmu->dev,
33b9b721d1SSai Prakash Ranjan 				"Failed to read TBU power status: %d\n", ret);
34b9b721d1SSai Prakash Ranjan 
35b9b721d1SSai Prakash Ranjan 		ret = qcom_scm_io_readl(smmu->ioaddr + cfg->reg_offset[QCOM_SMMU_STATS_SYNC_INV_TBU_ACK],
36b9b721d1SSai Prakash Ranjan 					&sync_inv_ack);
37b9b721d1SSai Prakash Ranjan 		if (ret)
38b9b721d1SSai Prakash Ranjan 			dev_err(smmu->dev,
39b9b721d1SSai Prakash Ranjan 				"Failed to read TBU sync/inv ack status: %d\n", ret);
40b9b721d1SSai Prakash Ranjan 
41b9b721d1SSai Prakash Ranjan 		ret = qcom_scm_io_readl(smmu->ioaddr + cfg->reg_offset[QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR],
42b9b721d1SSai Prakash Ranjan 					&sync_inv_progress);
43b9b721d1SSai Prakash Ranjan 		if (ret)
44b9b721d1SSai Prakash Ranjan 			dev_err(smmu->dev,
45b9b721d1SSai Prakash Ranjan 				"Failed to read TCU syn/inv progress: %d\n", ret);
46b9b721d1SSai Prakash Ranjan 
47b9b721d1SSai Prakash Ranjan 		dev_err(smmu->dev,
48b9b721d1SSai Prakash Ranjan 			"TBU: power_status %#x sync_inv_ack %#x sync_inv_progress %#x\n",
49b9b721d1SSai Prakash Ranjan 			tbu_pwr_status, sync_inv_ack, sync_inv_progress);
50b9b721d1SSai Prakash Ranjan 	}
51b9b721d1SSai Prakash Ranjan }
52