Merge "iommu/arm-smmu: Remove support for qcom,smmu-v2"

This commit is contained in:
qctecmdr Service 2018-11-04 14:52:03 -08:00 committed by Gerrit - the friendly Code Review server
commit 43062a37ef

View file

@ -131,7 +131,6 @@ enum arm_smmu_implementation {
GENERIC_SMMU,
ARM_MMU500,
CAVIUM_SMMUV2,
QCOM_SMMUV2,
QCOM_SMMUV500,
};
@ -3629,166 +3628,6 @@ static struct iommu_ops arm_smmu_ops = {
.iova_to_pte = arm_smmu_iova_to_pte,
};
#define IMPL_DEF1_MICRO_MMU_CTRL 0
#define MICRO_MMU_CTRL_LOCAL_HALT_REQ (1 << 2)
#define MICRO_MMU_CTRL_IDLE (1 << 3)
/* Definitions for implementation-defined registers */
#define ACTLR_QCOM_OSH_SHIFT 28
#define ACTLR_QCOM_OSH 1
#define ACTLR_QCOM_ISH_SHIFT 29
#define ACTLR_QCOM_ISH 1
#define ACTLR_QCOM_NSH_SHIFT 30
#define ACTLR_QCOM_NSH 1
static int qsmmuv2_wait_for_halt(struct arm_smmu_device *smmu)
{
void __iomem *impl_def1_base = ARM_SMMU_IMPL_DEF1(smmu);
u32 tmp;
if (readl_poll_timeout_atomic(impl_def1_base + IMPL_DEF1_MICRO_MMU_CTRL,
tmp, (tmp & MICRO_MMU_CTRL_IDLE),
0, 30000)) {
dev_err(smmu->dev, "Couldn't halt SMMU!\n");
return -EBUSY;
}
return 0;
}
static int __qsmmuv2_halt(struct arm_smmu_device *smmu, bool wait)
{
void __iomem *impl_def1_base = ARM_SMMU_IMPL_DEF1(smmu);
u32 reg;
reg = readl_relaxed(impl_def1_base + IMPL_DEF1_MICRO_MMU_CTRL);
reg |= MICRO_MMU_CTRL_LOCAL_HALT_REQ;
if (arm_smmu_is_static_cb(smmu)) {
phys_addr_t impl_def1_base_phys = impl_def1_base - smmu->base +
smmu->phys_addr;
if (scm_io_write(impl_def1_base_phys +
IMPL_DEF1_MICRO_MMU_CTRL, reg)) {
dev_err(smmu->dev,
"scm_io_write fail. SMMU might not be halted");
return -EINVAL;
}
} else {
writel_relaxed(reg, impl_def1_base + IMPL_DEF1_MICRO_MMU_CTRL);
}
return wait ? qsmmuv2_wait_for_halt(smmu) : 0;
}
static int qsmmuv2_halt(struct arm_smmu_device *smmu)
{
return __qsmmuv2_halt(smmu, true);
}
static int qsmmuv2_halt_nowait(struct arm_smmu_device *smmu)
{
return __qsmmuv2_halt(smmu, false);
}
static void qsmmuv2_resume(struct arm_smmu_device *smmu)
{
void __iomem *impl_def1_base = ARM_SMMU_IMPL_DEF1(smmu);
u32 reg;
reg = readl_relaxed(impl_def1_base + IMPL_DEF1_MICRO_MMU_CTRL);
reg &= ~MICRO_MMU_CTRL_LOCAL_HALT_REQ;
if (arm_smmu_is_static_cb(smmu)) {
phys_addr_t impl_def1_base_phys = impl_def1_base - smmu->base +
smmu->phys_addr;
if (scm_io_write(impl_def1_base_phys +
IMPL_DEF1_MICRO_MMU_CTRL, reg))
dev_err(smmu->dev,
"scm_io_write fail. SMMU might not be resumed");
} else {
writel_relaxed(reg, impl_def1_base + IMPL_DEF1_MICRO_MMU_CTRL);
}
}
static void qsmmuv2_device_reset(struct arm_smmu_device *smmu)
{
int i;
u32 val;
struct arm_smmu_impl_def_reg *regs = smmu->impl_def_attach_registers;
void __iomem *cb_base;
/*
* SCTLR.M must be disabled here per ARM SMMUv2 spec
* to prevent table walks with an inconsistent state.
*/
for (i = 0; i < smmu->num_context_banks; ++i) {
cb_base = ARM_SMMU_CB(smmu, i);
val = ACTLR_QCOM_ISH << ACTLR_QCOM_ISH_SHIFT |
ACTLR_QCOM_OSH << ACTLR_QCOM_OSH_SHIFT |
ACTLR_QCOM_NSH << ACTLR_QCOM_NSH_SHIFT;
writel_relaxed(val, cb_base + ARM_SMMU_CB_ACTLR);
}
/* Program implementation defined registers */
qsmmuv2_halt(smmu);
for (i = 0; i < smmu->num_impl_def_attach_registers; ++i)
writel_relaxed(regs[i].value,
ARM_SMMU_GR0(smmu) + regs[i].offset);
qsmmuv2_resume(smmu);
}
static phys_addr_t qsmmuv2_iova_to_phys_hard(struct iommu_domain *domain,
dma_addr_t iova)
{
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_device *smmu = smmu_domain->smmu;
int ret;
phys_addr_t phys = 0;
unsigned long flags;
u32 sctlr, sctlr_orig, fsr;
void __iomem *cb_base;
ret = arm_smmu_power_on(smmu_domain->smmu->pwr);
if (ret)
return ret;
spin_lock_irqsave(&smmu->atos_lock, flags);
cb_base = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx);
qsmmuv2_halt_nowait(smmu);
writel_relaxed(RESUME_TERMINATE, cb_base + ARM_SMMU_CB_RESUME);
qsmmuv2_wait_for_halt(smmu);
/* clear FSR to allow ATOS to log any faults */
fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR);
writel_relaxed(fsr, cb_base + ARM_SMMU_CB_FSR);
/* disable stall mode momentarily */
sctlr_orig = readl_relaxed(cb_base + ARM_SMMU_CB_SCTLR);
sctlr = sctlr_orig & ~SCTLR_CFCFG;
writel_relaxed(sctlr, cb_base + ARM_SMMU_CB_SCTLR);
phys = __arm_smmu_iova_to_phys_hard(domain, iova);
/* restore SCTLR */
writel_relaxed(sctlr_orig, cb_base + ARM_SMMU_CB_SCTLR);
qsmmuv2_resume(smmu);
spin_unlock_irqrestore(&smmu->atos_lock, flags);
arm_smmu_power_off(smmu_domain->smmu->pwr);
return phys;
}
struct arm_smmu_arch_ops qsmmuv2_arch_ops = {
.device_reset = qsmmuv2_device_reset,
.iova_to_phys_hard = qsmmuv2_iova_to_phys_hard,
};
static void arm_smmu_context_bank_reset(struct arm_smmu_device *smmu)
{
int i;
@ -4446,7 +4285,6 @@ ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU, NULL);
ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, GENERIC_SMMU, NULL);
ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500, NULL);
ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2, NULL);
ARM_SMMU_MATCH_DATA(qcom_smmuv2, ARM_SMMU_V2, QCOM_SMMUV2, &qsmmuv2_arch_ops);
ARM_SMMU_MATCH_DATA(qcom_smmuv500, ARM_SMMU_V2, QCOM_SMMUV500,
&qsmmuv500_arch_ops);
@ -4457,7 +4295,6 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,mmu-401", .data = &arm_mmu401 },
{ .compatible = "arm,mmu-500", .data = &arm_mmu500 },
{ .compatible = "cavium,smmu-v2", .data = &cavium_smmuv2 },
{ .compatible = "qcom,smmu-v2", .data = &qcom_smmuv2 },
{ .compatible = "qcom,qsmmu-v500", .data = &qcom_smmuv500 },
{ },
};