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

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

Merge "drm: smmu: fix smmu map failure"

parents 0d8bfae5 e453eb66
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -46,6 +46,10 @@ struct msm_mmu_funcs {
	void (*destroy)(struct msm_mmu *mmu);
	void (*enable)(struct msm_mmu *mmu);
	void (*disable)(struct msm_mmu *mmu);
	int (*early_splash_map)(struct msm_mmu *mmu, uint64_t iova,
			struct sg_table *sgt, u32 flags);
	void (*early_splash_unmap)(struct msm_mmu *mmu, uint64_t iova,
			struct sg_table *sgt);
	int (*set_property)(struct msm_mmu *mmu,
				enum iommu_attr attr, void *data);
};
+51 −19
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -120,21 +120,11 @@ static int msm_smmu_map(struct msm_mmu *mmu, uint64_t iova,
{
	struct msm_smmu *smmu = to_msm_smmu(mmu);
	struct msm_smmu_client *client = msm_smmu_to_client(smmu);
	struct iommu_domain *domain;
	int ret;

	if (!client || !sgt)
		return -EINVAL;

	if (iova != 0) {
		if (!client->mmu_mapping || !client->mmu_mapping->domain)
			return -EINVAL;

		domain = client->mmu_mapping->domain;

		return iommu_map_sg(domain, iova, sgt->sgl,
				sgt->nents, flags);
	} else {
	if (priv)
		ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl,
				sgt->nents, DMA_BIDIRECTIONAL, priv);
@@ -144,7 +134,6 @@ static int msm_smmu_map(struct msm_mmu *mmu, uint64_t iova,

	return (ret != sgt->nents) ? -ENOMEM : 0;
}
}

static void msm_smmu_unmap(struct msm_mmu *mmu, uint64_t iova,
		struct sg_table *sgt, void *priv)
@@ -160,6 +149,47 @@ static void msm_smmu_unmap(struct msm_mmu *mmu, uint64_t iova,
			DMA_BIDIRECTIONAL);
}

static int msm_smmu_early_splash_map(struct msm_mmu *mmu, uint64_t iova,
		struct sg_table *sgt, u32 flags)
{
	struct msm_smmu *smmu = to_msm_smmu(mmu);
	struct msm_smmu_client *client = msm_smmu_to_client(smmu);
	struct iommu_domain *domain;

	if (!client || !sgt)
		return -EINVAL;

	if (!client->mmu_mapping || !client->mmu_mapping->domain)
		return -EINVAL;

	domain = client->mmu_mapping->domain;

	return iommu_map_sg(domain, iova, sgt->sgl, sgt->nents, flags);
}

static void msm_smmu_early_splash_unmap(struct msm_mmu *mmu, uint64_t iova,
				struct sg_table *sgt)
{
	struct msm_smmu *smmu = to_msm_smmu(mmu);
	struct msm_smmu_client *client = msm_smmu_to_client(smmu);
	struct iommu_domain *domain;
	struct scatterlist *sg;
	size_t len = 0;
	int unmapped, i = 0;

	if (!client || !client->mmu_mapping || !client->mmu_mapping->domain)
		return;

	domain = client->mmu_mapping->domain;

	for_each_sg(sgt->sgl, sg, sgt->nents, i)
		len += sg->length;

	unmapped = iommu_unmap(domain, iova, len);
	if (unmapped < len)
		DRM_ERROR("could not unmap iova@%llx\n", iova);
}

static void msm_smmu_destroy(struct msm_mmu *mmu)
{
	struct msm_smmu *smmu = to_msm_smmu(mmu);
@@ -199,6 +229,8 @@ static const struct msm_mmu_funcs funcs = {
	.map = msm_smmu_map,
	.unmap = msm_smmu_unmap,
	.destroy = msm_smmu_destroy,
	.early_splash_map = msm_smmu_early_splash_map,
	.early_splash_unmap = msm_smmu_early_splash_unmap,
	.set_property = msm_smmu_set_property,
};

+6 −5
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -301,8 +301,8 @@ static int _sde_splash_free_resource(struct msm_mmu *mmu,
		return -EINVAL;

	if (mmu->funcs && mmu->funcs->unmap)
		mmu->funcs->unmap(mmu, sinfo->splash_mem_paddr[conn],
				msm_obj->sgt, NULL);
		mmu->funcs->early_splash_unmap(mmu,
			sinfo->splash_mem_paddr[conn], msm_obj->sgt);

	_sde_splash_free_bootup_memory_to_system(sinfo->splash_mem_paddr[conn],
						sinfo->splash_mem_size[conn]);
@@ -489,8 +489,9 @@ int sde_splash_smmu_map(struct drm_device *dev, struct msm_mmu *mmu,
		msm_obj = to_msm_bo(sinfo->obj[i]);

		if (mmu->funcs && mmu->funcs->map) {
			ret = mmu->funcs->map(mmu, sinfo->splash_mem_paddr[i],
				msm_obj->sgt, IOMMU_READ | IOMMU_NOEXEC, NULL);
			ret = mmu->funcs->early_splash_map(mmu,
				sinfo->splash_mem_paddr[i], msm_obj->sgt,
				IOMMU_READ | IOMMU_NOEXEC);

			if (!ret) {
				SDE_ERROR("Map blk %d @%pK failed.\n",