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

Commit 8b3c5546 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "iommu/arm-smmu: support mapping before enabling S1 translations"

parents cf5d449a 9c3b6e45
Loading
Loading
Loading
Loading
+49 −1
Original line number Diff line number Diff line
@@ -511,6 +511,8 @@ static bool arm_smmu_is_static_cb(struct arm_smmu_device *smmu);
static bool arm_smmu_is_slave_side_secure(struct arm_smmu_domain *smmu_domain);
static bool arm_smmu_has_secure_vmid(struct arm_smmu_domain *smmu_domain);

static int arm_smmu_enable_s1_translations(struct arm_smmu_domain *smmu_domain);

static void parse_driver_options(struct arm_smmu_device *smmu)
{
	int i = 0;
@@ -1486,7 +1488,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
	/* SCTLR */
	reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_EAE_SBOP;

	if (!(smmu_domain->attributes & (1 << DOMAIN_ATTR_S1_BYPASS)) ||
	if ((!(smmu_domain->attributes & (1 << DOMAIN_ATTR_S1_BYPASS)) &&
	     !(smmu_domain->attributes & (1 << DOMAIN_ATTR_EARLY_MAP))) ||
								!stage1)
		reg |= SCTLR_M;
	if (stage1)
@@ -2908,6 +2911,11 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
		ret = 0;
		break;
	}
	case DOMAIN_ATTR_EARLY_MAP:
		*((int *)data) = !!(smmu_domain->attributes
				    & (1 << DOMAIN_ATTR_EARLY_MAP));
		ret = 0;
		break;
	default:
		ret = -ENODEV;
		break;
@@ -3036,6 +3044,24 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
			smmu_domain->attributes |= 1 << DOMAIN_ATTR_FAST;
		ret = 0;
		break;
	case DOMAIN_ATTR_EARLY_MAP: {
		int early_map = *((int *)data);

		ret = 0;
		if (early_map) {
			smmu_domain->attributes |=
						1 << DOMAIN_ATTR_EARLY_MAP;
		} else {
			if (smmu_domain->smmu)
				ret = arm_smmu_enable_s1_translations(
								smmu_domain);

			if (!ret)
				smmu_domain->attributes &=
					~(1 << DOMAIN_ATTR_EARLY_MAP);
		}
		break;
	}
	default:
		ret = -ENODEV;
		break;
@@ -3046,6 +3072,28 @@ out_unlock:
	return ret;
}


static int arm_smmu_enable_s1_translations(struct arm_smmu_domain *smmu_domain)
{
	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
	struct arm_smmu_device *smmu = smmu_domain->smmu;
	void __iomem *cb_base;
	u32 reg;
	int ret;

	cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
	ret = arm_smmu_enable_clocks(smmu);
	if (ret)
		return ret;

	reg = readl_relaxed(cb_base + ARM_SMMU_CB_SCTLR);
	reg |= SCTLR_M;

	writel_relaxed(reg, cb_base + ARM_SMMU_CB_SCTLR);
	arm_smmu_disable_clocks(smmu);
	return ret;
}

static int arm_smmu_dma_supported(struct iommu_domain *domain,
				  struct device *dev, u64 mask)
{
+2 −0
Original line number Diff line number Diff line
@@ -71,6 +71,8 @@ static const char *iommu_debug_attr_to_string(enum iommu_attr attr)
		return "DOMAIN_ATTR_S1_BYPASS";
	case DOMAIN_ATTR_FAST:
		return "DOMAIN_ATTR_FAST";
	case DOMAIN_ATTR_EARLY_MAP:
		return "DOMAIN_ATTR_EARLY_MAP";
	default:
		return "Unknown attr!";
	}
+1 −0
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ enum iommu_attr {
	DOMAIN_ATTR_S1_BYPASS,
	DOMAIN_ATTR_FAST,
	DOMAIN_ATTR_PGTBL_INFO,
	DOMAIN_ATTR_EARLY_MAP,
	DOMAIN_ATTR_MAX,
};