Loading drivers/gpu/msm/adreno.c +3 −12 Original line number Diff line number Diff line Loading @@ -1404,6 +1404,9 @@ static int adreno_probe(struct platform_device *pdev) device->pwrctrl.bus_width = adreno_dev->gpucore->bus_width; device->mmu.secured = (IS_ENABLED(CONFIG_QCOM_SECURE_BUFFER) && ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)); status = kgsl_device_platform_probe(device); if (status) { device->pdev = NULL; Loading @@ -1419,18 +1422,6 @@ static int adreno_probe(struct platform_device *pdev) adreno_rscc_probe(device); adreno_isense_probe(device); /* * qcom,iommu-secure-id is used to identify MMUs that can handle secure * content but that is only part of the story - the GPU also has to be * able to handle secure content. Unfortunately in a classic catch-22 * we cannot identify the GPU until after the DT is parsed. tl;dr - * check the GPU capabilities here and modify mmu->secured accordingly */ #if IS_ENABLED(CONFIG_QCOM_SECURE_BUFFER) if (!ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)) device->mmu.secured = false; #endif if (ADRENO_FEATURE(adreno_dev, ADRENO_IOCOHERENT)) device->mmu.features |= KGSL_MMU_IO_COHERENT; Loading drivers/gpu/msm/kgsl_iommu.c +54 −69 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ static void _detach_pt(struct kgsl_iommu_pt *iommu_pt, struct kgsl_iommu_context *ctx) { if (iommu_pt->attached) { iommu_detach_device(iommu_pt->domain, ctx->dev); iommu_detach_device(iommu_pt->domain, &ctx->pdev->dev); iommu_pt->attached = false; } } Loading @@ -148,7 +148,7 @@ static int _attach_pt(struct kgsl_iommu_pt *iommu_pt, if (iommu_pt->attached) return 0; ret = iommu_attach_device(iommu_pt->domain, ctx->dev); ret = iommu_attach_device(iommu_pt->domain, &ctx->pdev->dev); if (ret == 0) iommu_pt->attached = true; Loading Loading @@ -935,7 +935,7 @@ static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; iommu_pt = _alloc_pt(ctx->dev, mmu, pt); iommu_pt = _alloc_pt(&ctx->pdev->dev, mmu, pt); if (IS_ERR(iommu_pt)) return PTR_ERR(iommu_pt); Loading Loading @@ -1016,7 +1016,7 @@ static int _init_secure_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) if (!mmu->secured) return -EPERM; iommu_pt = _alloc_pt(ctx->dev, mmu, pt); iommu_pt = _alloc_pt(&ctx->pdev->dev, mmu, pt); if (IS_ERR(iommu_pt)) return PTR_ERR(iommu_pt); Loading Loading @@ -1058,7 +1058,7 @@ static int _init_per_process_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) int dynamic = 1; unsigned int cb_num = ctx->cb_num; iommu_pt = _alloc_pt(ctx->dev, mmu, pt); iommu_pt = _alloc_pt(&ctx->pdev->dev, mmu, pt); if (IS_ERR(iommu_pt)) return PTR_ERR(iommu_pt); Loading Loading @@ -1165,6 +1165,9 @@ static void _detach_context(struct kgsl_iommu_context *ctx) _detach_pt(iommu_pt, ctx); ctx->default_pt = NULL; platform_device_put(ctx->pdev); ctx->pdev = NULL; } static void kgsl_iommu_close(struct kgsl_mmu *mmu) Loading Loading @@ -1196,6 +1199,9 @@ static void kgsl_iommu_close(struct kgsl_mmu *mmu) __free_page(kgsl_dummy_page); kgsl_dummy_page = NULL; } of_platform_depopulate(&iommu->pdev->dev); platform_device_put(iommu->pdev); } static int kgsl_iommu_init(struct kgsl_mmu *mmu) Loading Loading @@ -1332,7 +1338,7 @@ static int _setup_secure_context(struct kgsl_mmu *mmu) struct kgsl_iommu_pt *iommu_pt; if (ctx->dev == NULL || !mmu->secured) if (!ctx->pdev || !mmu->secured) return 0; if (mmu->securepagetable == NULL) Loading Loading @@ -2229,65 +2235,37 @@ static bool kgsl_iommu_addr_in_range(struct kgsl_pagetable *pagetable, return false; } static const struct { int id; char *name; } kgsl_iommu_cbs[] = { { KGSL_IOMMU_CONTEXT_USER, "gfx3d_user", }, { KGSL_IOMMU_CONTEXT_SECURE, "gfx3d_secure" }, { KGSL_IOMMU_CONTEXT_SECURE, "gfx3d_secure_alt" }, }; static int _kgsl_iommu_cb_probe(struct kgsl_device *device, struct kgsl_iommu *iommu, struct device_node *node) static int kgsl_iommu_probe_child(struct kgsl_device *device, struct device_node *parent, int id, const char *name) { struct platform_device *pdev = of_find_device_by_node(node); struct kgsl_iommu_context *ctx = NULL; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int i; struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); struct device_node *node = of_find_node_by_name(parent, name); struct platform_device *pdev; struct device_node *phandle; for (i = 0; i < ARRAY_SIZE(kgsl_iommu_cbs); i++) { if (!strcmp(node->name, kgsl_iommu_cbs[i].name)) { int id = kgsl_iommu_cbs[i].id; if (!node) return -ENOENT; if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_MMU_SECURE_CB_ALT)) { if (!strcmp(node->name, "gfx3d_secure")) continue; } else if (!strcmp(node->name, "gfx3d_secure_alt")) continue; pdev = of_find_device_by_node(node); ctx = &iommu->ctx[id]; ctx->id = id; ctx->cb_num = -1; ctx->name = kgsl_iommu_cbs[i].name; iommu->ctx[id].id = id; iommu->ctx[id].cb_num = -1; iommu->ctx[id].name = name; break; } } iommu->ctx[id].kgsldev = device; if (ctx == NULL) { dev_info(device->dev, "dt: Unused context label %s\n", node->name); return 0; } iommu->ctx[id].pdev = pdev; if (ctx->id == KGSL_IOMMU_CONTEXT_SECURE) device->mmu.secured = true; phandle = of_parse_phandle(node, "iommus", 0); ctx->kgsldev = device; if (phandle && of_device_is_compatible(phandle, "qcom,qsmmu-v500")) device->mmu.subtype = KGSL_IOMMU_SMMU_V500; /* arm-smmu driver we'll have the right device pointer here. */ if (of_find_property(node, "iommus", NULL)) { ctx->dev = &pdev->dev; } else { ctx->dev = kgsl_mmu_get_ctx(ctx->name); of_node_put(phandle); if (IS_ERR(ctx->dev)) return PTR_ERR(ctx->dev); } of_dma_configure(&pdev->dev, node, true); of_dma_configure(ctx->dev, node, true); of_node_put(node); return 0; } Loading @@ -2305,13 +2283,15 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, const char *cname; struct property *prop; u32 reg_val[2]; int i = 0; int i = 0, ret; struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); struct device_node *child, *iommu_node = NULL; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct platform_device *pdev = of_find_device_by_node(node); memset(iommu, 0, sizeof(*iommu)); iommu->pdev = pdev; if (of_property_read_u32_array(node, "reg", reg_val, 2)) { dev_err(device->dev, "dt: Unable to read KGSL IOMMU register range\n"); Loading @@ -2326,10 +2306,12 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, if (IS_ERR(c)) { dev_err(device->dev, "dt: Couldn't get clock: %s\n", cname); platform_device_put(pdev); return -ENODEV; } if (i >= KGSL_IOMMU_MAX_CLKS) { dev_err(device->dev, "dt: too many clocks defined.\n"); platform_device_put(pdev); return -EINVAL; } Loading @@ -2345,25 +2327,28 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, /* Fill out the rest of the devices in the node */ of_platform_populate(node, NULL, NULL, &pdev->dev); for_each_child_of_node(node, child) { int ret; /* The "user" device always needs to be present */ ret = kgsl_iommu_probe_child(device, node, KGSL_IOMMU_CONTEXT_USER, "gfx3d_user"); if (!of_device_is_compatible(child, "qcom,smmu-kgsl-cb")) continue; if (!ret && device->mmu.secured) { const char *name = "gfx3d_secure"; ret = _kgsl_iommu_cb_probe(device, iommu, child); if (ret) return ret; if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_MMU_SECURE_CB_ALT)) name = "gfx3d_secure_alt"; if (!iommu_node) iommu_node = of_parse_phandle(child, "iommus", 0); /* Secure context bank devices are optional */ if (kgsl_iommu_probe_child(device, node, KGSL_IOMMU_CONTEXT_SECURE, name)) device->mmu.secured = false; } if (iommu_node && of_device_is_compatible(iommu_node, "qcom,qsmmu-v500")) device->mmu.subtype = KGSL_IOMMU_SMMU_V500; if (ret) { of_platform_depopulate(&pdev->dev); platform_device_put(pdev); } return 0; return ret; } static const struct { Loading drivers/gpu/msm/kgsl_iommu.h +4 −2 Original line number Diff line number Diff line Loading @@ -80,7 +80,7 @@ enum kgsl_iommu_context_id { /* * struct kgsl_iommu_context - Structure holding data about an iommu context * bank * @dev: pointer to the iommu context's device * @pdev: pointer to the iommu context's platform device * @name: context name * @id: The id of the context, used for deciding how it is used. * @cb_num: The hardware context bank number, used for calculating register Loading @@ -92,7 +92,7 @@ enum kgsl_iommu_context_id { * it may be changed by self programming. */ struct kgsl_iommu_context { struct device *dev; struct platform_device *pdev; const char *name; enum kgsl_iommu_context_id id; unsigned int cb_num; Loading Loading @@ -122,6 +122,8 @@ struct kgsl_iommu { atomic_t clk_enable_count; struct clk *clks[KGSL_IOMMU_MAX_CLKS]; struct kgsl_memdesc *smmu_info; /** @pdev: Pointer to the platform device for the IOMMU device */ struct platform_device *pdev; }; /* Loading drivers/gpu/msm/kgsl_mmu.h +0 −5 Original line number Diff line number Diff line Loading @@ -344,9 +344,4 @@ kgsl_mmu_pagetable_get_contextidr(struct kgsl_pagetable *pagetable) */ u64 kgsl_mmu_get_global_base(struct kgsl_device *device); static inline struct device *kgsl_mmu_get_ctx(const char *name) { return ERR_PTR(-ENODEV); } #endif /* __KGSL_MMU_H */ Loading
drivers/gpu/msm/adreno.c +3 −12 Original line number Diff line number Diff line Loading @@ -1404,6 +1404,9 @@ static int adreno_probe(struct platform_device *pdev) device->pwrctrl.bus_width = adreno_dev->gpucore->bus_width; device->mmu.secured = (IS_ENABLED(CONFIG_QCOM_SECURE_BUFFER) && ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)); status = kgsl_device_platform_probe(device); if (status) { device->pdev = NULL; Loading @@ -1419,18 +1422,6 @@ static int adreno_probe(struct platform_device *pdev) adreno_rscc_probe(device); adreno_isense_probe(device); /* * qcom,iommu-secure-id is used to identify MMUs that can handle secure * content but that is only part of the story - the GPU also has to be * able to handle secure content. Unfortunately in a classic catch-22 * we cannot identify the GPU until after the DT is parsed. tl;dr - * check the GPU capabilities here and modify mmu->secured accordingly */ #if IS_ENABLED(CONFIG_QCOM_SECURE_BUFFER) if (!ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)) device->mmu.secured = false; #endif if (ADRENO_FEATURE(adreno_dev, ADRENO_IOCOHERENT)) device->mmu.features |= KGSL_MMU_IO_COHERENT; Loading
drivers/gpu/msm/kgsl_iommu.c +54 −69 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ static void _detach_pt(struct kgsl_iommu_pt *iommu_pt, struct kgsl_iommu_context *ctx) { if (iommu_pt->attached) { iommu_detach_device(iommu_pt->domain, ctx->dev); iommu_detach_device(iommu_pt->domain, &ctx->pdev->dev); iommu_pt->attached = false; } } Loading @@ -148,7 +148,7 @@ static int _attach_pt(struct kgsl_iommu_pt *iommu_pt, if (iommu_pt->attached) return 0; ret = iommu_attach_device(iommu_pt->domain, ctx->dev); ret = iommu_attach_device(iommu_pt->domain, &ctx->pdev->dev); if (ret == 0) iommu_pt->attached = true; Loading Loading @@ -935,7 +935,7 @@ static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; iommu_pt = _alloc_pt(ctx->dev, mmu, pt); iommu_pt = _alloc_pt(&ctx->pdev->dev, mmu, pt); if (IS_ERR(iommu_pt)) return PTR_ERR(iommu_pt); Loading Loading @@ -1016,7 +1016,7 @@ static int _init_secure_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) if (!mmu->secured) return -EPERM; iommu_pt = _alloc_pt(ctx->dev, mmu, pt); iommu_pt = _alloc_pt(&ctx->pdev->dev, mmu, pt); if (IS_ERR(iommu_pt)) return PTR_ERR(iommu_pt); Loading Loading @@ -1058,7 +1058,7 @@ static int _init_per_process_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt) int dynamic = 1; unsigned int cb_num = ctx->cb_num; iommu_pt = _alloc_pt(ctx->dev, mmu, pt); iommu_pt = _alloc_pt(&ctx->pdev->dev, mmu, pt); if (IS_ERR(iommu_pt)) return PTR_ERR(iommu_pt); Loading Loading @@ -1165,6 +1165,9 @@ static void _detach_context(struct kgsl_iommu_context *ctx) _detach_pt(iommu_pt, ctx); ctx->default_pt = NULL; platform_device_put(ctx->pdev); ctx->pdev = NULL; } static void kgsl_iommu_close(struct kgsl_mmu *mmu) Loading Loading @@ -1196,6 +1199,9 @@ static void kgsl_iommu_close(struct kgsl_mmu *mmu) __free_page(kgsl_dummy_page); kgsl_dummy_page = NULL; } of_platform_depopulate(&iommu->pdev->dev); platform_device_put(iommu->pdev); } static int kgsl_iommu_init(struct kgsl_mmu *mmu) Loading Loading @@ -1332,7 +1338,7 @@ static int _setup_secure_context(struct kgsl_mmu *mmu) struct kgsl_iommu_pt *iommu_pt; if (ctx->dev == NULL || !mmu->secured) if (!ctx->pdev || !mmu->secured) return 0; if (mmu->securepagetable == NULL) Loading Loading @@ -2229,65 +2235,37 @@ static bool kgsl_iommu_addr_in_range(struct kgsl_pagetable *pagetable, return false; } static const struct { int id; char *name; } kgsl_iommu_cbs[] = { { KGSL_IOMMU_CONTEXT_USER, "gfx3d_user", }, { KGSL_IOMMU_CONTEXT_SECURE, "gfx3d_secure" }, { KGSL_IOMMU_CONTEXT_SECURE, "gfx3d_secure_alt" }, }; static int _kgsl_iommu_cb_probe(struct kgsl_device *device, struct kgsl_iommu *iommu, struct device_node *node) static int kgsl_iommu_probe_child(struct kgsl_device *device, struct device_node *parent, int id, const char *name) { struct platform_device *pdev = of_find_device_by_node(node); struct kgsl_iommu_context *ctx = NULL; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int i; struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); struct device_node *node = of_find_node_by_name(parent, name); struct platform_device *pdev; struct device_node *phandle; for (i = 0; i < ARRAY_SIZE(kgsl_iommu_cbs); i++) { if (!strcmp(node->name, kgsl_iommu_cbs[i].name)) { int id = kgsl_iommu_cbs[i].id; if (!node) return -ENOENT; if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_MMU_SECURE_CB_ALT)) { if (!strcmp(node->name, "gfx3d_secure")) continue; } else if (!strcmp(node->name, "gfx3d_secure_alt")) continue; pdev = of_find_device_by_node(node); ctx = &iommu->ctx[id]; ctx->id = id; ctx->cb_num = -1; ctx->name = kgsl_iommu_cbs[i].name; iommu->ctx[id].id = id; iommu->ctx[id].cb_num = -1; iommu->ctx[id].name = name; break; } } iommu->ctx[id].kgsldev = device; if (ctx == NULL) { dev_info(device->dev, "dt: Unused context label %s\n", node->name); return 0; } iommu->ctx[id].pdev = pdev; if (ctx->id == KGSL_IOMMU_CONTEXT_SECURE) device->mmu.secured = true; phandle = of_parse_phandle(node, "iommus", 0); ctx->kgsldev = device; if (phandle && of_device_is_compatible(phandle, "qcom,qsmmu-v500")) device->mmu.subtype = KGSL_IOMMU_SMMU_V500; /* arm-smmu driver we'll have the right device pointer here. */ if (of_find_property(node, "iommus", NULL)) { ctx->dev = &pdev->dev; } else { ctx->dev = kgsl_mmu_get_ctx(ctx->name); of_node_put(phandle); if (IS_ERR(ctx->dev)) return PTR_ERR(ctx->dev); } of_dma_configure(&pdev->dev, node, true); of_dma_configure(ctx->dev, node, true); of_node_put(node); return 0; } Loading @@ -2305,13 +2283,15 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, const char *cname; struct property *prop; u32 reg_val[2]; int i = 0; int i = 0, ret; struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); struct device_node *child, *iommu_node = NULL; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct platform_device *pdev = of_find_device_by_node(node); memset(iommu, 0, sizeof(*iommu)); iommu->pdev = pdev; if (of_property_read_u32_array(node, "reg", reg_val, 2)) { dev_err(device->dev, "dt: Unable to read KGSL IOMMU register range\n"); Loading @@ -2326,10 +2306,12 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, if (IS_ERR(c)) { dev_err(device->dev, "dt: Couldn't get clock: %s\n", cname); platform_device_put(pdev); return -ENODEV; } if (i >= KGSL_IOMMU_MAX_CLKS) { dev_err(device->dev, "dt: too many clocks defined.\n"); platform_device_put(pdev); return -EINVAL; } Loading @@ -2345,25 +2327,28 @@ static int _kgsl_iommu_probe(struct kgsl_device *device, /* Fill out the rest of the devices in the node */ of_platform_populate(node, NULL, NULL, &pdev->dev); for_each_child_of_node(node, child) { int ret; /* The "user" device always needs to be present */ ret = kgsl_iommu_probe_child(device, node, KGSL_IOMMU_CONTEXT_USER, "gfx3d_user"); if (!of_device_is_compatible(child, "qcom,smmu-kgsl-cb")) continue; if (!ret && device->mmu.secured) { const char *name = "gfx3d_secure"; ret = _kgsl_iommu_cb_probe(device, iommu, child); if (ret) return ret; if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_MMU_SECURE_CB_ALT)) name = "gfx3d_secure_alt"; if (!iommu_node) iommu_node = of_parse_phandle(child, "iommus", 0); /* Secure context bank devices are optional */ if (kgsl_iommu_probe_child(device, node, KGSL_IOMMU_CONTEXT_SECURE, name)) device->mmu.secured = false; } if (iommu_node && of_device_is_compatible(iommu_node, "qcom,qsmmu-v500")) device->mmu.subtype = KGSL_IOMMU_SMMU_V500; if (ret) { of_platform_depopulate(&pdev->dev); platform_device_put(pdev); } return 0; return ret; } static const struct { Loading
drivers/gpu/msm/kgsl_iommu.h +4 −2 Original line number Diff line number Diff line Loading @@ -80,7 +80,7 @@ enum kgsl_iommu_context_id { /* * struct kgsl_iommu_context - Structure holding data about an iommu context * bank * @dev: pointer to the iommu context's device * @pdev: pointer to the iommu context's platform device * @name: context name * @id: The id of the context, used for deciding how it is used. * @cb_num: The hardware context bank number, used for calculating register Loading @@ -92,7 +92,7 @@ enum kgsl_iommu_context_id { * it may be changed by self programming. */ struct kgsl_iommu_context { struct device *dev; struct platform_device *pdev; const char *name; enum kgsl_iommu_context_id id; unsigned int cb_num; Loading Loading @@ -122,6 +122,8 @@ struct kgsl_iommu { atomic_t clk_enable_count; struct clk *clks[KGSL_IOMMU_MAX_CLKS]; struct kgsl_memdesc *smmu_info; /** @pdev: Pointer to the platform device for the IOMMU device */ struct platform_device *pdev; }; /* Loading
drivers/gpu/msm/kgsl_mmu.h +0 −5 Original line number Diff line number Diff line Loading @@ -344,9 +344,4 @@ kgsl_mmu_pagetable_get_contextidr(struct kgsl_pagetable *pagetable) */ u64 kgsl_mmu_get_global_base(struct kgsl_device *device); static inline struct device *kgsl_mmu_get_ctx(const char *name) { return ERR_PTR(-ENODEV); } #endif /* __KGSL_MMU_H */