From df131b2a71acd57e96e23fe2c2bbd4867159cf48 Mon Sep 17 00:00:00 2001 From: Narendra Muppalla Date: Wed, 25 Jan 2017 11:26:46 -0800 Subject: [PATCH] Revert "drm/msm: add smmu handler" This reverts 'commit 29e061e200a7 ("drm/msm: add smmu handler")' This is partial change for display drm driver, that will break drm/sde merge commit. Change-Id: I65034605b1caefe435a37c6fde78d4c52f3439c3 Signed-off-by: Narendra Muppalla --- drivers/gpu/drm/msm/Makefile | 1 - drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 5 +- drivers/gpu/drm/msm/msm_gem.c | 24 +- drivers/gpu/drm/msm/msm_gem.h | 3 +- drivers/gpu/drm/msm/msm_mmu.h | 18 - drivers/gpu/drm/msm/msm_smmu.c | 432 ------------------------ 6 files changed, 11 insertions(+), 472 deletions(-) delete mode 100644 drivers/gpu/drm/msm/msm_smmu.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7b613a55fdc2..f8984d673ff0 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -51,7 +51,6 @@ msm-y := \ msm_gem_submit.o \ msm_gpu.o \ msm_iommu.o \ - msm_smmu.o \ msm_perf.o \ msm_rd.o \ msm_ringbuffer.o diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 210cedb8134d..b532faa8026d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2014, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -595,8 +595,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) mdelay(16); if (config->platform.iommu) { - mmu = msm_smmu_new(&pdev->dev, - MSM_SMMU_DOMAIN_UNSECURE); + mmu = msm_iommu_new(&pdev->dev, config->platform.iommu); if (IS_ERR(mmu)) { ret = PTR_ERR(mmu); dev_err(dev->dev, "failed to init iommu: %d\n", ret); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 6fa56abf0c78..c76cc853b08a 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -295,23 +295,16 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, if (iommu_present(&platform_bus_type)) { struct msm_mmu *mmu = priv->mmus[id]; + uint32_t offset; if (WARN_ON(!mmu)) return -EINVAL; - if (obj->import_attach && mmu->funcs->map_dma_buf) { - ret = mmu->funcs->map_dma_buf(mmu, msm_obj->sgt, - obj->import_attach->dmabuf, - DMA_BIDIRECTIONAL); - if (ret) { - DRM_ERROR("Unable to map dma buf\n"); - return ret; - } - } - msm_obj->domain[id].iova = - sg_dma_address(msm_obj->sgt->sgl); + offset = (uint32_t)mmap_offset(obj); + ret = mmu->funcs->map(mmu, offset, msm_obj->sgt, + obj->size, IOMMU_READ | IOMMU_WRITE); + msm_obj->domain[id].iova = offset; } else { - WARN_ONCE(1, "physical address being used\n"); msm_obj->domain[id].iova = physaddr(obj); } } @@ -531,11 +524,8 @@ void msm_gem_free_object(struct drm_gem_object *obj) for (id = 0; id < ARRAY_SIZE(msm_obj->domain); id++) { struct msm_mmu *mmu = priv->mmus[id]; if (mmu && msm_obj->domain[id].iova) { - if (obj->import_attach && mmu->funcs->unmap_dma_buf) { - mmu->funcs->unmap_dma_buf(mmu, msm_obj->sgt, - obj->import_attach->dmabuf, - DMA_BIDIRECTIONAL); - } + uint32_t offset = msm_obj->domain[id].iova; + mmu->funcs->unmap(mmu, offset, msm_obj->sgt, obj->size); } } diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 2e4ae6b1c5d0..6fc59bfeedeb 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -53,7 +53,8 @@ struct msm_gem_object { void *vaddr; struct { - dma_addr_t iova; + // XXX + uint32_t iova; } domain[NUM_DOMAINS]; /* normally (resv == &_resv) except for imported bo's */ diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h index 6d2f5627bfae..7cd88d9dc155 100644 --- a/drivers/gpu/drm/msm/msm_mmu.h +++ b/drivers/gpu/drm/msm/msm_mmu.h @@ -20,14 +20,6 @@ #include -struct msm_mmu; -struct msm_gpu; - -enum msm_mmu_domain_type { - MSM_SMMU_DOMAIN_UNSECURE, - MSM_SMMU_DOMAIN_MAX, -}; - struct msm_mmu_funcs { int (*attach)(struct msm_mmu *mmu, const char **names, int cnt); void (*detach)(struct msm_mmu *mmu, const char **names, int cnt); @@ -35,14 +27,6 @@ struct msm_mmu_funcs { unsigned len, int prot); int (*unmap)(struct msm_mmu *mmu, uint32_t iova, struct sg_table *sgt, unsigned len); - int (*map_sg)(struct msm_mmu *mmu, struct sg_table *sgt, - enum dma_data_direction dir); - void (*unmap_sg)(struct msm_mmu *mmu, struct sg_table *sgt, - enum dma_data_direction dir); - int (*map_dma_buf)(struct msm_mmu *mmu, struct sg_table *sgt, - struct dma_buf *dma_buf, int dir); - void (*unmap_dma_buf)(struct msm_mmu *mmu, struct sg_table *sgt, - struct dma_buf *dma_buf, int dir); void (*destroy)(struct msm_mmu *mmu); }; @@ -60,7 +44,5 @@ static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev, struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain); struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu); -struct msm_mmu *msm_smmu_new(struct device *dev, - enum msm_mmu_domain_type domain); #endif /* __MSM_MMU_H__ */ diff --git a/drivers/gpu/drm/msm/msm_smmu.c b/drivers/gpu/drm/msm/msm_smmu.c deleted file mode 100644 index d51fbedf90c6..000000000000 --- a/drivers/gpu/drm/msm/msm_smmu.c +++ /dev/null @@ -1,432 +0,0 @@ -/* Copyright (c) 2015-2017, 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 - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include - -#include -#include - -#include "msm_drv.h" -#include "msm_mmu.h" - -struct msm_smmu_client { - struct device *dev; - struct dma_iommu_mapping *mmu_mapping; - bool domain_attached; -}; - -struct msm_smmu { - struct msm_mmu base; - struct device *client_dev; - struct msm_smmu_client client; -}; - -struct msm_smmu_domain { - const char *label; - size_t va_start; - size_t va_size; - bool secure; -}; - -#define to_msm_smmu(x) container_of(x, struct msm_smmu, base) -#define msm_smmu_to_client(smmu) (&smmu->client) - -static int _msm_smmu_create_mapping(struct msm_smmu_client *client, - const struct msm_smmu_domain *domain); - -static int msm_smmu_attach(struct msm_mmu *mmu, const char **names, int cnt) -{ - struct msm_smmu *smmu = to_msm_smmu(mmu); - struct msm_smmu_client *client = msm_smmu_to_client(smmu); - int rc = 0; - - /* domain attach only once */ - if (client->domain_attached) - return 0; - - rc = arm_iommu_attach_device(client->dev, - client->mmu_mapping); - if (rc) { - dev_err(client->dev, "iommu attach dev failed (%d)\n", - rc); - return rc; - } - - client->domain_attached = true; - - dev_dbg(client->dev, "iommu domain attached\n"); - - return 0; -} - -static void msm_smmu_detach(struct msm_mmu *mmu, const char **names, int cnt) -{ - DBG("detaching"); -} - -static int msm_smmu_map(struct msm_mmu *mmu, uint32_t iova, - struct sg_table *sgt, unsigned len, int prot) -{ - 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; - unsigned int da = iova; - unsigned int i, j; - int ret; - - if (!client) - return -ENODEV; - - domain = client->mmu_mapping->domain; - if (!domain || !sgt) - return -EINVAL; - - for_each_sg(sgt->sgl, sg, sgt->nents, i) { - u32 pa = sg_phys(sg) - sg->offset; - size_t bytes = sg->length + sg->offset; - - VERB("map[%d]: %08x %08x(%zx)", i, iova, pa, bytes); - - ret = iommu_map(domain, da, pa, bytes, prot); - if (ret) - goto fail; - - da += bytes; - } - - return 0; - -fail: - da = iova; - - for_each_sg(sgt->sgl, sg, i, j) { - size_t bytes = sg->length + sg->offset; - - iommu_unmap(domain, da, bytes); - da += bytes; - } - return ret; -} - -static int msm_smmu_map_sg(struct msm_mmu *mmu, struct sg_table *sgt, - enum dma_data_direction dir) -{ - struct msm_smmu *smmu = to_msm_smmu(mmu); - struct msm_smmu_client *client = msm_smmu_to_client(smmu); - int ret; - - ret = dma_map_sg(client->dev, sgt->sgl, sgt->nents, dir); - if (ret != sgt->nents) - return -ENOMEM; - - return 0; -} - -static void msm_smmu_unmap_sg(struct msm_mmu *mmu, struct sg_table *sgt, - enum dma_data_direction dir) -{ - struct msm_smmu *smmu = to_msm_smmu(mmu); - struct msm_smmu_client *client = msm_smmu_to_client(smmu); - - dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, dir); -} - -static int msm_smmu_unmap(struct msm_mmu *mmu, uint32_t iova, - struct sg_table *sgt, unsigned len) -{ - 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; - unsigned int da = iova; - int i; - - if (!client) - return -ENODEV; - - domain = client->mmu_mapping->domain; - if (!domain || !sgt) - return -EINVAL; - - for_each_sg(sgt->sgl, sg, sgt->nents, i) { - size_t bytes = sg->length + sg->offset; - size_t unmapped; - - unmapped = iommu_unmap(domain, da, bytes); - if (unmapped < bytes) - return unmapped; - - VERB("unmap[%d]: %08x(%zx)", i, iova, bytes); - - WARN_ON(!PAGE_ALIGNED(bytes)); - - da += bytes; - } - - return 0; -} - -static void msm_smmu_destroy(struct msm_mmu *mmu) -{ - struct msm_smmu *smmu = to_msm_smmu(mmu); - struct platform_device *pdev = to_platform_device(smmu->client_dev); - - platform_device_unregister(pdev); - kfree(smmu); -} - -static int msm_smmu_map_dma_buf(struct msm_mmu *mmu, struct sg_table *sgt, - struct dma_buf *dma_buf, int dir) -{ - struct msm_smmu *smmu = to_msm_smmu(mmu); - struct msm_smmu_client *client = msm_smmu_to_client(smmu); - int ret; - - ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, sgt->nents, dir, - dma_buf); - if (ret != sgt->nents) { - DRM_ERROR("dma map sg failed\n"); - return -ENOMEM; - } - - return 0; -} - - -static void msm_smmu_unmap_dma_buf(struct msm_mmu *mmu, struct sg_table *sgt, - struct dma_buf *dma_buf, int dir) -{ - struct msm_smmu *smmu = to_msm_smmu(mmu); - struct msm_smmu_client *client = msm_smmu_to_client(smmu); - - msm_dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, dir, dma_buf); -} - -static const struct msm_mmu_funcs funcs = { - .attach = msm_smmu_attach, - .detach = msm_smmu_detach, - .map = msm_smmu_map, - .map_sg = msm_smmu_map_sg, - .unmap_sg = msm_smmu_unmap_sg, - .unmap = msm_smmu_unmap, - .map_dma_buf = msm_smmu_map_dma_buf, - .unmap_dma_buf = msm_smmu_unmap_dma_buf, - .destroy = msm_smmu_destroy, -}; - -static struct msm_smmu_domain msm_smmu_domains[MSM_SMMU_DOMAIN_MAX] = { - [MSM_SMMU_DOMAIN_UNSECURE] = { - .label = "mdp_ns", - .va_start = SZ_1M, - .va_size = SZ_2G, - }, -}; - -static const struct of_device_id msm_smmu_dt_match[] = { - { .compatible = "qcom,smmu_mdp_unsec", - .data = &msm_smmu_domains[MSM_SMMU_DOMAIN_UNSECURE] }, - {} -}; -MODULE_DEVICE_TABLE(of, msm_smmu_dt_match); - -static struct device *msm_smmu_device_create(struct device *dev, - enum msm_mmu_domain_type domain, - struct msm_smmu *smmu) -{ - struct device_node *child; - struct platform_device *pdev; - int i; - const char *compat = NULL; - - for (i = 0; i < ARRAY_SIZE(msm_smmu_dt_match); i++) { - if (msm_smmu_dt_match[i].data == &msm_smmu_domains[domain]) { - compat = msm_smmu_dt_match[i].compatible; - break; - } - } - - if (!compat) { - DRM_ERROR("unable to find matching domain for %d\n", domain); - return ERR_PTR(-ENOENT); - } - DRM_INFO("found domain %d compat: %s\n", domain, compat); - - if (domain == MSM_SMMU_DOMAIN_UNSECURE) { - int rc; - - smmu->client.dev = dev; - rc = _msm_smmu_create_mapping(msm_smmu_to_client(smmu), - msm_smmu_dt_match[i].data); - if (rc) - return ERR_PTR(rc); - - return NULL; - } - - child = of_find_compatible_node(dev->of_node, NULL, compat); - if (!child) { - DRM_ERROR("unable to find compatible node for %s\n", compat); - return ERR_PTR(-ENODEV); - } - - pdev = of_platform_device_create(child, NULL, dev); - if (!pdev) { - DRM_ERROR("unable to create smmu platform dev for domain %d\n", - domain); - return ERR_PTR(-ENODEV); - } - - return &pdev->dev; -} - -struct msm_mmu *msm_smmu_new(struct device *dev, - enum msm_mmu_domain_type domain) -{ - struct msm_smmu *smmu; - struct device *client_dev; - - smmu = kzalloc(sizeof(*smmu), GFP_KERNEL); - if (!smmu) - return ERR_PTR(-ENOMEM); - - client_dev = msm_smmu_device_create(dev, domain, smmu); - if (IS_ERR(client_dev)) - return (void *)client_dev ? : ERR_PTR(-ENODEV); - - smmu->client_dev = client_dev; - msm_mmu_init(&smmu->base, dev, &funcs); - - return &smmu->base; -} - -static int _msm_smmu_create_mapping(struct msm_smmu_client *client, - const struct msm_smmu_domain *domain) -{ - int disable_htw = 1; - int rc; - - client->mmu_mapping = arm_iommu_create_mapping(&platform_bus_type, - domain->va_start, domain->va_size); - if (IS_ERR(client->mmu_mapping)) { - dev_err(client->dev, - "iommu create mapping failed for domain=%s\n", - domain->label); - return PTR_ERR(client->mmu_mapping); - } - - if (domain->secure) { - int secure_vmid = VMID_CP_PIXEL; - - rc = iommu_domain_set_attr(client->mmu_mapping->domain, - DOMAIN_ATTR_SECURE_VMID, &secure_vmid); - if (rc) { - dev_err(client->dev, "couldn't set secure pix vmid\n"); - goto error; - } - } - - return 0; - -error: - arm_iommu_release_mapping(client->mmu_mapping); - return rc; -} - -/** - * msm_smmu_probe() - * @pdev: platform device - * - * Each smmu context acts as a separate device and the context banks are - * configured with a VA range. - * Registers the clks as each context bank has its own clks, for which voting - * has to be done everytime before using that context bank. - */ -static int msm_smmu_probe(struct platform_device *pdev) -{ - const struct of_device_id *match; - struct msm_smmu_client *client; - const struct msm_smmu_domain *domain; - int rc; - - match = of_match_device(msm_smmu_dt_match, &pdev->dev); - if (!match || !match->data) { - dev_err(&pdev->dev, "probe failed as match data is invalid\n"); - return -EINVAL; - } - - domain = match->data; - if (!domain) { - dev_err(&pdev->dev, "no matching device found\n"); - return -EINVAL; - } - - DRM_INFO("probing device %s\n", match->compatible); - - client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL); - if (!client) - return -ENOMEM; - - client->dev = &pdev->dev; - - rc = _msm_smmu_create_mapping(client, domain); - platform_set_drvdata(pdev, client); - - return rc; -} - -static int msm_smmu_remove(struct platform_device *pdev) -{ - struct msm_smmu_client *client; - - client = platform_get_drvdata(pdev); - if (client->domain_attached) { - arm_iommu_detach_device(client->dev); - client->domain_attached = false; - } - arm_iommu_release_mapping(client->mmu_mapping); - - return 0; -} - -static struct platform_driver msm_smmu_driver = { - .probe = msm_smmu_probe, - .remove = msm_smmu_remove, - .driver = { - .name = "msmdrm_smmu", - .of_match_table = msm_smmu_dt_match, - }, -}; - -static int __init msm_smmu_driver_init(void) -{ - int ret; - - ret = platform_driver_register(&msm_smmu_driver); - if (ret) - pr_err("mdss_smmu_register_driver() failed!\n"); - - return ret; -} -module_init(msm_smmu_driver_init); - -static void __exit msm_smmu_driver_cleanup(void) -{ - platform_driver_unregister(&msm_smmu_driver); -} -module_exit(msm_smmu_driver_cleanup); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("MSM SMMU driver");