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

Commit 6f5cbe7d authored by Charan Teja Reddy's avatar Charan Teja Reddy
Browse files

iommu/arm-smmu: override writel_relaxed



Skip writes to global space of SMMU on targets with slave
side protection where this space was preprogrammed by TZ
that need to be kept intact.

Change-Id: I03f8ba708144ad9846ec8d6b8a89bd53773bdded
Signed-off-by: default avatarCharan Teja Reddy <charante@codeaurora.org>
parent 436b6888
Loading
Loading
Loading
Loading
+34 −2
Original line number Diff line number Diff line
@@ -55,11 +55,10 @@
#include <linux/remote_spinlock.h>
#include <linux/ktime.h>
#include <trace/events/iommu.h>
#include <soc/qcom/msm_tz_smmu.h>
#include <soc/qcom/scm.h>
#include <linux/notifier.h>

#include <linux/amba/bus.h>
#include <soc/qcom/msm_tz_smmu.h>

#include "io-pgtable.h"

@@ -2736,6 +2735,39 @@ static bool arm_smmu_capable(enum iommu_cap cap)
	}
}

#ifdef CONFIG_MSM_TZ_SMMU
static struct arm_smmu_device *arm_smmu_get_by_addr(void __iomem *addr)
{
	struct arm_smmu_device *smmu;
	unsigned long flags;

	spin_lock_irqsave(&arm_smmu_devices_lock, flags);
	list_for_each_entry(smmu, &arm_smmu_devices, list) {
		unsigned long base = (unsigned long)smmu->base;
		unsigned long mask = ~(smmu->size - 1);

		if ((base & mask) == ((unsigned long)addr & mask)) {
			spin_unlock_irqrestore(&arm_smmu_devices_lock, flags);
			return smmu;
		}
	}
	spin_unlock_irqrestore(&arm_smmu_devices_lock, flags);
	return NULL;
}

bool arm_smmu_skip_write(void __iomem *addr)
{
	struct arm_smmu_device *smmu;

	smmu = arm_smmu_get_by_addr(addr);
	if (smmu &&
	    ((unsigned long)addr & (smmu->size - 1)) >= (smmu->size >> 1))
		return false;
	else
		return true;
}
#endif

static struct arm_smmu_device *arm_smmu_get_by_list(struct device_node *np)
{
	struct arm_smmu_device *smmu;
+9 −0
Original line number Diff line number Diff line
@@ -56,6 +56,15 @@ enum tz_smmu_device_id msm_dev_to_device_id(struct device *dev);
int msm_tz_set_cb_format(enum tz_smmu_device_id sec_id, int cbndx);
int msm_iommu_sec_pgtbl_init(void);
int register_iommu_sec_ptbl(void);
bool arm_smmu_skip_write(void __iomem *addr);

/* Donot write to smmu global space with CONFIG_MSM_TZ_SMMU */
#undef writel_relaxed
#define writel_relaxed(v, c)	do {					\
	if (!arm_smmu_skip_write(c))					\
		((void)__raw_writel((__force u32)cpu_to_le32(v), (c)));	\
	} while (0)

#else

static inline int msm_tz_smmu_atos_start(struct device *dev, int cb_num)