[PATCH RFC v2 03/14] drm/msm: look for lpac from dts
Anna Maniscalco
anna.maniscalco2000 at gmail.com
Thu Oct 29 06:52:40 PDT 2026
In order to associate the SID used by LPAC to it's own domain and
context bank we need a separate node on the DTS.
Add the code to look up that node on initialization.
Signed-off-by: Anna Maniscalco <anna.maniscalco2000 at gmail.com>
---
drivers/gpu/drm/msm/adreno/adreno_device.c | 10 +++++++++
drivers/gpu/drm/msm/adreno/adreno_gpu.c | 36 ++++++++++++++++++++++++++----
drivers/gpu/drm/msm/msm_gpu.c | 6 +++++
drivers/gpu/drm/msm/msm_gpu.h | 1 +
4 files changed, 49 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 7f20320ef66a..4d22223c3323 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -6,6 +6,8 @@
* Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
*/
+#include <linux/of_platform.h>
+
#include "adreno_gpu.h"
bool hang_debug = false;
@@ -271,6 +273,12 @@ static const struct component_ops a3xx_ops = {
static int adreno_probe(struct platform_device *pdev)
{
+ int ret = 0;
+
+ ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+ if (ret)
+ return ret;
+
if (of_device_is_compatible(pdev->dev.of_node, "amd,imageon") ||
msm_gpu_no_components())
return msm_gpu_probe(pdev, &a3xx_ops);
@@ -282,6 +290,8 @@ static void adreno_remove(struct platform_device *pdev)
{
struct msm_drm_private *priv = platform_get_drvdata(pdev);
+ of_platform_depopulate(&pdev->dev);
+
if (priv->kms_init)
component_del(&pdev->dev, &a3xx_ops);
else
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index f3fc7032fadc..1dedeb19946e 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -11,6 +11,8 @@
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/kernel.h>
#include <linux/of_reserved_mem.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
#include <linux/pm_opp.h>
#include <linux/slab.h>
#include <linux/soc/qcom/mdt_loader.h>
@@ -201,7 +203,9 @@ adreno_iommu_create_vm(struct msm_gpu *gpu,
struct drm_gpuvm *vm;
u64 start, size;
- mmu = msm_iommu_gpu_new(&pdev->dev, NULL, gpu, quirks);
+ mmu = msm_iommu_gpu_new(&pdev->dev,
+ gpu->lpac_pdev ? &gpu->lpac_pdev->dev : NULL,
+ gpu, quirks);
if (IS_ERR(mmu))
return ERR_CAST(mmu);
@@ -1187,6 +1191,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
const struct adreno_gpu_funcs *funcs, int nr_rings)
{
struct device *dev = &pdev->dev;
+ struct device_node *lpac_node;
struct adreno_platform_config *config = dev->platform_data;
struct msm_gpu_config adreno_gpu_config = { 0 };
struct msm_gpu *gpu = &adreno_gpu->base;
@@ -1200,6 +1205,18 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
gpu->allow_relocs = config->info->family < ADRENO_6XX_GEN1;
gpu->pdev = pdev;
+ lpac_node = of_get_compatible_child(pdev->dev.of_node, "qcom,lpac");
+ if (lpac_node)
+ gpu->lpac_pdev = of_find_device_by_node(lpac_node);
+ if (gpu->lpac_pdev) {
+ pm_runtime_enable(&gpu->lpac_pdev->dev);
+ if (!device_link_add(&pdev->dev, &gpu->lpac_pdev->dev,
+ DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER))
+ dev_err(&gpu->lpac_pdev->dev, "failed to link to lpac device\n");
+ }
+ if (lpac_node)
+ of_node_put(lpac_node);
+
/* Only handle the core clock when GMU is not in use (or is absent). */
if (adreno_has_gmu_wrapper(adreno_gpu) ||
adreno_has_rgmu(adreno_gpu) ||
@@ -1221,8 +1238,10 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
gpu_name = devm_kasprintf(dev, GFP_KERNEL, "%"ADRENO_CHIPID_FMT,
ADRENO_CHIPID_ARGS(config->chip_id));
- if (!gpu_name)
- return -ENOMEM;
+ if (!gpu_name) {
+ ret = -ENOMEM;
+ goto err_put_lpac_pdev;
+ }
adreno_gpu_config.ioname = "kgsl_3d0_reg_memory";
@@ -1230,7 +1249,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
ret = adreno_get_pwrlevels(dev, gpu);
if (ret)
- return ret;
+ goto err_put_lpac_pdev;
init_completion(&adreno_gpu->fault_coredump_done);
complete_all(&adreno_gpu->fault_coredump_done);
@@ -1241,6 +1260,10 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
gpu_name, &adreno_gpu_config);
+err_put_lpac_pdev:
+ if (gpu->lpac_pdev)
+ put_device(&gpu->lpac_pdev->dev);
+ return ret;
}
void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
@@ -1256,4 +1279,9 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
pm_runtime_disable(&priv->gpu_pdev->dev);
msm_gpu_cleanup(&adreno_gpu->base);
+
+ if (gpu->lpac_pdev) {
+ pm_runtime_disable(&gpu->lpac_pdev->dev);
+ put_device(&gpu->lpac_pdev->dev);
+ }
}
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 18ed00e5f143..20581be10ca7 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -963,6 +963,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
gpu->gpu_cx = NULL;
platform_set_drvdata(pdev, &gpu->adreno_smmu);
+ if (gpu->lpac_pdev)
+ platform_set_drvdata(gpu->lpac_pdev, &gpu->lpac_adreno_smmu);
msm_devfreq_init(gpu);
@@ -1032,6 +1034,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
msm_gem_kernel_put(gpu->memptrs_bo, gpu->vm);
platform_set_drvdata(pdev, NULL);
+ if (gpu->lpac_pdev)
+ platform_set_drvdata(gpu->lpac_pdev, NULL);
return ret;
}
@@ -1062,4 +1066,6 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
msm_perfcntr_cleanup(gpu);
platform_set_drvdata(gpu->pdev, NULL);
+ if (gpu->lpac_pdev)
+ platform_set_drvdata(gpu->lpac_pdev, NULL);
}
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index e2291dfe3ca8..271956e7f870 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -172,6 +172,7 @@ struct msm_gpu {
const char *name;
struct drm_device *dev;
struct platform_device *pdev;
+ struct platform_device *lpac_pdev;
const struct msm_gpu_funcs *funcs;
struct adreno_smmu_priv adreno_smmu;
--
2.56.0
More information about the linux-arm-kernel
mailing list