162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/device.h> 762306a36Sopenharmony_ci#include <linux/firmware/qcom/qcom_scm.h> 862306a36Sopenharmony_ci#include <linux/ratelimit.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "arm-smmu.h" 1162306a36Sopenharmony_ci#include "arm-smmu-qcom.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_civoid qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu) 1462306a36Sopenharmony_ci{ 1562306a36Sopenharmony_ci int ret; 1662306a36Sopenharmony_ci u32 tbu_pwr_status, sync_inv_ack, sync_inv_progress; 1762306a36Sopenharmony_ci struct qcom_smmu *qsmmu = container_of(smmu, struct qcom_smmu, smmu); 1862306a36Sopenharmony_ci const struct qcom_smmu_config *cfg; 1962306a36Sopenharmony_ci static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, 2062306a36Sopenharmony_ci DEFAULT_RATELIMIT_BURST); 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci if (__ratelimit(&rs)) { 2362306a36Sopenharmony_ci dev_err(smmu->dev, "TLB sync timed out -- SMMU may be deadlocked\n"); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci cfg = qsmmu->cfg; 2662306a36Sopenharmony_ci if (!cfg) 2762306a36Sopenharmony_ci return; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci ret = qcom_scm_io_readl(smmu->ioaddr + cfg->reg_offset[QCOM_SMMU_TBU_PWR_STATUS], 3062306a36Sopenharmony_ci &tbu_pwr_status); 3162306a36Sopenharmony_ci if (ret) 3262306a36Sopenharmony_ci dev_err(smmu->dev, 3362306a36Sopenharmony_ci "Failed to read TBU power status: %d\n", ret); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci ret = qcom_scm_io_readl(smmu->ioaddr + cfg->reg_offset[QCOM_SMMU_STATS_SYNC_INV_TBU_ACK], 3662306a36Sopenharmony_ci &sync_inv_ack); 3762306a36Sopenharmony_ci if (ret) 3862306a36Sopenharmony_ci dev_err(smmu->dev, 3962306a36Sopenharmony_ci "Failed to read TBU sync/inv ack status: %d\n", ret); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci ret = qcom_scm_io_readl(smmu->ioaddr + cfg->reg_offset[QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR], 4262306a36Sopenharmony_ci &sync_inv_progress); 4362306a36Sopenharmony_ci if (ret) 4462306a36Sopenharmony_ci dev_err(smmu->dev, 4562306a36Sopenharmony_ci "Failed to read TCU syn/inv progress: %d\n", ret); 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci dev_err(smmu->dev, 4862306a36Sopenharmony_ci "TBU: power_status %#x sync_inv_ack %#x sync_inv_progress %#x\n", 4962306a36Sopenharmony_ci tbu_pwr_status, sync_inv_ack, sync_inv_progress); 5062306a36Sopenharmony_ci } 5162306a36Sopenharmony_ci} 52