Loading drivers/gpu/drm/msm/msm_mmu.h +4 −0 Original line number Diff line number Diff line Loading @@ -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); }; Loading drivers/gpu/drm/msm/msm_smmu.c +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> * Loading Loading @@ -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); Loading @@ -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) Loading @@ -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); Loading Loading @@ -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, }; Loading drivers/gpu/drm/msm/sde/sde_splash.c +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 Loading Loading @@ -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]); Loading Loading @@ -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", Loading Loading
drivers/gpu/drm/msm/msm_mmu.h +4 −0 Original line number Diff line number Diff line Loading @@ -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); }; Loading
drivers/gpu/drm/msm/msm_smmu.c +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> * Loading Loading @@ -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); Loading @@ -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) Loading @@ -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); Loading Loading @@ -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, }; Loading
drivers/gpu/drm/msm/sde/sde_splash.c +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 Loading Loading @@ -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]); Loading Loading @@ -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", Loading