Merge tag 'iommu-updates-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/joro...
[sfrench/cifs-2.6.git] / drivers / iommu / arm-smmu-qcom.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
4  */
5
6 #include <linux/qcom_scm.h>
7
8 #include "arm-smmu.h"
9
10 struct qcom_smmu {
11         struct arm_smmu_device smmu;
12 };
13
14 static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
15 {
16         int ret;
17
18         arm_mmu500_reset(smmu);
19
20         /*
21          * To address performance degradation in non-real time clients,
22          * such as USB and UFS, turn off wait-for-safe on sdm845 based boards,
23          * such as MTP and db845, whose firmwares implement secure monitor
24          * call handlers to turn on/off the wait-for-safe logic.
25          */
26         ret = qcom_scm_qsmmu500_wait_safe_toggle(0);
27         if (ret)
28                 dev_warn(smmu->dev, "Failed to turn off SAFE logic\n");
29
30         return ret;
31 }
32
33 static const struct arm_smmu_impl qcom_smmu_impl = {
34         .reset = qcom_sdm845_smmu500_reset,
35 };
36
37 struct arm_smmu_device *qcom_smmu_impl_init(struct arm_smmu_device *smmu)
38 {
39         struct qcom_smmu *qsmmu;
40
41         qsmmu = devm_kzalloc(smmu->dev, sizeof(*qsmmu), GFP_KERNEL);
42         if (!qsmmu)
43                 return ERR_PTR(-ENOMEM);
44
45         qsmmu->smmu = *smmu;
46
47         qsmmu->smmu.impl = &qcom_smmu_impl;
48         devm_kfree(smmu->dev, smmu);
49
50         return &qsmmu->smmu;
51 }