summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/adreno/adreno_gpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/adreno/adreno_gpu.c')
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c49
1 files changed, 18 insertions, 31 deletions
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 458b5b26d3c2..6cf9975e951e 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -16,6 +16,7 @@
#include <linux/soc/qcom/mdt_loader.h>
#include <soc/qcom/ocmem.h>
#include "adreno_gpu.h"
+#include "a6xx_gpu.h"
#include "msm_gem.h"
#include "msm_mmu.h"
@@ -189,6 +190,9 @@ struct msm_gem_address_space *
adreno_iommu_create_address_space(struct msm_gpu *gpu,
struct platform_device *pdev)
{
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+ struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+ struct io_pgtable_domain_attr pgtbl_cfg;
struct iommu_domain *iommu;
struct msm_mmu *mmu;
struct msm_gem_address_space *aspace;
@@ -198,7 +202,20 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu,
if (!iommu)
return NULL;
+ /*
+ * This allows GPU to set the bus attributes required to use system
+ * cache on behalf of the iommu page table walker.
+ */
+ if (!IS_ERR(a6xx_gpu->htw_llc_slice)) {
+ pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_ARM_OUTER_WBWA;
+ iommu_domain_set_attr(iommu, DOMAIN_ATTR_IO_PGTABLE_CFG, &pgtbl_cfg);
+ }
+
mmu = msm_iommu_new(&pdev->dev, iommu);
+ if (IS_ERR(mmu)) {
+ iommu_domain_free(iommu);
+ return ERR_CAST(mmu);
+ }
/*
* Use the aperture start or SZ_16M, whichever is greater. This will
@@ -899,7 +916,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct adreno_platform_config *config = dev->platform_data;
struct msm_gpu_config adreno_gpu_config = { 0 };
struct msm_gpu *gpu = &adreno_gpu->base;
- int ret;
adreno_gpu->funcs = funcs;
adreno_gpu->info = adreno_info(config->rev);
@@ -918,37 +934,8 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
pm_runtime_use_autosuspend(dev);
pm_runtime_enable(dev);
- ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
+ return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
adreno_gpu->info->name, &adreno_gpu_config);
- if (ret)
- return ret;
-
- /*
- * The legacy case, before "interconnect-names", only has a
- * single interconnect path which is equivalent to "gfx-mem"
- */
- if (!of_find_property(dev->of_node, "interconnect-names", NULL)) {
- gpu->icc_path = of_icc_get(dev, NULL);
- } else {
- gpu->icc_path = of_icc_get(dev, "gfx-mem");
- gpu->ocmem_icc_path = of_icc_get(dev, "ocmem");
- }
-
- if (IS_ERR(gpu->icc_path)) {
- ret = PTR_ERR(gpu->icc_path);
- gpu->icc_path = NULL;
- return ret;
- }
-
- if (IS_ERR(gpu->ocmem_icc_path)) {
- ret = PTR_ERR(gpu->ocmem_icc_path);
- gpu->ocmem_icc_path = NULL;
- /* allow -ENODATA, ocmem icc is optional */
- if (ret != -ENODATA)
- return ret;
- }
-
- return 0;
}
void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)