mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH RFT 0/5] drm/msm: Attach a driver to GMU
@ 2026-05-12 20:52 Akhil P Oommen
  2026-05-12 20:52 ` [PATCH RFT 1/5] drm/msm/adreno/a6xx: Mark cxpd device_link as stateless Akhil P Oommen
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Akhil P Oommen @ 2026-05-12 20:52 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Akhil P Oommen

With the introduction of sync_state in the genpd framework, any consumer
device of GCC and GPUCC which is not bound to a driver will result in
bootup warnings like below:

[   24.362666] gcc-kaanapali 100000.clock-controller: sync_state() pending due to 3d37000.gmu
[   24.371210] gxclkctl-kaanapali 3d64000.clock-controller: sync_state() pending due to 3d37000.gmu
[   24.380268] gpucc-kaanapali 3d90000.clock-controller: sync_state() pending due to 3d37000.gmu

To silence these warnings and also to have a proper state in driver core,
attach a driver to the GMU and set it up as a component device for the drm
master device.

The first few patches are preparatory fixes and refactorings. And the
final patch introduces a driver for GMU devices.

Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
Akhil P Oommen (5):
      drm/msm/adreno/a6xx: Mark cxpd device_link as stateless
      drm/msm: Centralize the standalone drm device check for GPU
      drm/msm/adreno: Fix invalid drvdata typecast in adreno_remove()
      drm/msm: Always use component model for standalone GPU
      drm/msm: Attach a driver to the GMU

 drivers/gpu/drm/msm/adreno/a6xx_gmu.c      | 76 ++++++++++++++++++++++++++++--
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c      | 30 +++++-------
 drivers/gpu/drm/msm/adreno/a6xx_gpu.h      |  3 --
 drivers/gpu/drm/msm/adreno/adreno_device.c | 27 +++++++----
 drivers/gpu/drm/msm/adreno/adreno_gpu.h    |  3 +-
 drivers/gpu/drm/msm/msm_drv.c              | 49 ++++++++++++++-----
 drivers/gpu/drm/msm/msm_drv.h              |  8 ++--
 7 files changed, 143 insertions(+), 53 deletions(-)
---
base-commit: bb1459368dd795c43380057523f571d5eb0ddded
change-id: 20260511-gmu-sync-state-fix-bc6b2d809371

Best regards,
-- 
Akhil P Oommen <akhilpo@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH RFT 1/5] drm/msm/adreno/a6xx: Mark cxpd device_link as stateless
  2026-05-12 20:52 [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Akhil P Oommen
@ 2026-05-12 20:52 ` Akhil P Oommen
  2026-05-13  0:56   ` Dmitry Baryshkov
  2026-05-12 20:52 ` [PATCH RFT 2/5] drm/msm: Centralize the standalone drm device check for GPU Akhil P Oommen
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Akhil P Oommen @ 2026-05-12 20:52 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Akhil P Oommen

Since the cxpd virtual device is a driverless device, it has no real
struct device_driver bound it the way a normal platform device does. So,
the managed lifecycle doesn't map cleanly onto it. Since the lifecycle of
this device_link is managed by the msm driver, pass DL_FLAG_STATELESS
together with the existing DL_FLAG_PM_RUNTIME flag.

This fix is required to avoid the below splat when a driver is attached to
the GMU:

[    9.624509] WARNING: drivers/base/core.c:1383 at dvice_links_driver_bound+0x178/0x330, CPU#6: (udev-worker)/354e
[    9.781167] pc : device_links_driver_bound+0x178/0x330
[    9.786456] lr : device_links_driver_bound+0x158/0x330
[    9.798622] sp : ffff8000827bb820
[    9.802042] x29: ffff8000827bb820 x28: ffff000808915800 x27: 0000000000000044
[    9.809573] x26: ffffb7caf3f983d0 x25: 0000000000000003 x24: ffffb7caf41645a0
[    9.816920] x23: ffffb7caf3f982d8 x22: ffff000801239cb8 x21: ffff000801239c10
[    9.816921] x20: ffff00080b3a8c00 x19: ffff000801239c98 x18: 00000000ffffffff
[    9.816922] x17: 736d5b2073706f5f x16: ffffb7caf1eb5940 x15: ffff8001027bb3b7
[    9.816922] x14: 0000000000000026 x13: ffff00080084c110 x12: 0000000000000000
[    9.816923] x11: ffff0008004a5828 x10: ffff0008004a56d0 x9 : ffffb7caf2227870
[    9.816924] x8 : ffff0008004a56f8 x7 : 0000000000000001 x6 : 0000000000001000ocket.
[    9.816925] x5 : 00000000001a7fbf x4 : ffff0008004a56e8 x3 : ffff000801238cc8
[    9.816926] x2 : ffffb7caf4164000 x1 : ffff000801239c10 x0 : 0000000000000000
[    9.816927] Call trace:
[    9.816927]  device_links_driver_bound+0x178/0x330 (P)
[    9.893492]  driver_bound+0x7c/0xd0
[    9.893493]  really_probe+0x208/0x2a8
[    9.893495]  __driver_probe_device+0x88/0x170
[    9.893496]  driver_probe_device+0x44/0x178
[    9.909639]  __driver_attach+0x9c/0x1b8
[    9.913592]  bus_for_each_dev+0x7c/0xe8System Message Bus Socket.
[    9.925839]  driver_attach+0x2c/0x40
[    9.929733]  bus_add_driver+0xec/0x218
[    9.933609]  driver_register+0x68/0x138
[    9.937555]  __platform_driver_register+0x2c/0x40
[    9.937556]  adreno_gmu_register+0x2c/0x40 [msm]
[    9.947141]  adreno_register+0x3c/0x50 [msm]
[    9.951544]  msm_drm_register+0x50/0x78 [msm]for the API...
[    9.962813]  do_one_initcall+0x4c/0x3e0
[    9.966975]  do_init_module+0x60/0x280
[    9.970849]  load_module+0x1c70/0x1fa0
[    9.974708]  init_module_from_file+0xdc/0x100
[    9.979188]  __arm64_sys_finit_module+0x1c0/0x2e0
[    9.984026]  invoke_syscall+0x5c/0x120
[    9.987882]  el0_svc_common.constprop.0+0xd0/0xf8
[    9.992715]  do_el0_svc+0x28/0x40
[    9.995243] qcom_q6v5_pas 6800000.remoteproc: Handover signaled, but it already happened
[    9.996128]  el0_svc+0x38/0x148
[   10.007672]  el0t_64_sync_handler+0xa0/0xe8
[   10.011975]  el0t_64_sync+0x198/0x1a0

Fixes: ead5d3e5eb37 ("drm/msm/a6xx: Vote for cx gdsc from gpu driver")
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 1b44b9e21ad8..ec13b27feee7 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -2196,7 +2196,8 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 		goto err_mmio;
 	}
 
-	if (!device_link_add(gmu->dev, gmu->cxpd, DL_FLAG_PM_RUNTIME)) {
+	if (!device_link_add(gmu->dev, gmu->cxpd,
+			     DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS)) {
 		ret = -ENODEV;
 		goto detach_cxpd;
 	}
@@ -2377,7 +2378,8 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 		goto err_mmio;
 	}
 
-	link = device_link_add(gmu->dev, gmu->cxpd, DL_FLAG_PM_RUNTIME);
+	link = device_link_add(gmu->dev, gmu->cxpd,
+			       DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
 	if (!link) {
 		ret = -ENODEV;
 		goto detach_cxpd;

-- 
2.51.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH RFT 2/5] drm/msm: Centralize the standalone drm device check for GPU
  2026-05-12 20:52 [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Akhil P Oommen
  2026-05-12 20:52 ` [PATCH RFT 1/5] drm/msm/adreno/a6xx: Mark cxpd device_link as stateless Akhil P Oommen
@ 2026-05-12 20:52 ` Akhil P Oommen
  2026-05-13  5:41   ` Dmitry Baryshkov
  2026-05-12 20:52 ` [PATCH RFT 3/5] drm/msm/adreno: Fix invalid drvdata typecast in adreno_remove() Akhil P Oommen
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Akhil P Oommen @ 2026-05-12 20:52 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Akhil P Oommen

Replace msm_gpu_no_components() with msm_gpu_use_separate_drm_dev() and
move the platform-specific check for "amd,imageon" into the helper so the
policy is centralized and reused by both the core driver and adreno probe
path. No functional change intended.

Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 drivers/gpu/drm/msm/adreno/adreno_device.c |  3 +--
 drivers/gpu/drm/msm/msm_drv.c              | 11 +++++++----
 drivers/gpu/drm/msm/msm_drv.h              |  2 +-
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 4edfe80c5be7..3052f3e36de0 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -271,8 +271,7 @@ static const struct component_ops a3xx_ops = {
 
 static int adreno_probe(struct platform_device *pdev)
 {
-	if (of_device_is_compatible(pdev->dev.of_node, "amd,imageon") ||
-	    msm_gpu_no_components())
+	if (msm_gpu_use_separate_drm_dev(pdev))
 		return msm_gpu_probe(pdev, &a3xx_ops);
 
 	return component_add(&pdev->dev, &a3xx_ops);
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 195f40e331e5..b61deafd02c3 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -61,9 +61,12 @@ module_param(separate_gpu_kms, bool, 0400);
 DECLARE_FAULT_ATTR(fail_gem_alloc);
 DECLARE_FAULT_ATTR(fail_gem_iova);
 
-bool msm_gpu_no_components(void)
+bool msm_gpu_use_separate_drm_dev(struct platform_device *pdev)
 {
-	return separate_gpu_kms;
+	if (!pdev)
+		return separate_gpu_kms;
+
+	return of_device_is_compatible(pdev->dev.of_node, "amd,imageon") || separate_gpu_kms;
 }
 
 static int msm_drm_uninit(struct device *dev, const struct component_ops *gpu_ops)
@@ -1035,7 +1038,7 @@ static int add_gpu_components(struct device *dev,
 static int msm_drm_bind(struct device *dev)
 {
 	return msm_drm_init(dev,
-			    msm_gpu_no_components() ?
+			    msm_gpu_use_separate_drm_dev(NULL) ?
 				    &msm_kms_driver :
 				    &msm_driver,
 			    NULL);
@@ -1074,7 +1077,7 @@ int msm_drv_probe(struct device *master_dev,
 			return ret;
 	}
 
-	if (!msm_gpu_no_components()) {
+	if (!msm_gpu_use_separate_drm_dev(NULL)) {
 		ret = add_gpu_components(master_dev, &match);
 		if (ret)
 			return ret;
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 6d847d593f1a..6fcb696ceb7c 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -555,6 +555,6 @@ void msm_kms_shutdown(struct platform_device *pdev);
 
 bool msm_disp_drv_should_bind(struct device *dev, bool dpu_driver);
 
-bool msm_gpu_no_components(void);
+bool msm_gpu_use_separate_drm_dev(struct platform_device *pdev);
 
 #endif /* __MSM_DRV_H__ */

-- 
2.51.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH RFT 3/5] drm/msm/adreno: Fix invalid drvdata typecast in adreno_remove()
  2026-05-12 20:52 [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Akhil P Oommen
  2026-05-12 20:52 ` [PATCH RFT 1/5] drm/msm/adreno/a6xx: Mark cxpd device_link as stateless Akhil P Oommen
  2026-05-12 20:52 ` [PATCH RFT 2/5] drm/msm: Centralize the standalone drm device check for GPU Akhil P Oommen
@ 2026-05-12 20:52 ` Akhil P Oommen
  2026-05-13  5:39   ` Dmitry Baryshkov
  2026-05-12 20:52 ` [PATCH RFT 4/5] drm/msm: Always use component model for standalone GPU Akhil P Oommen
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Akhil P Oommen @ 2026-05-12 20:52 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Akhil P Oommen

adreno_remove() decides between component_del() and msm_gpu_remove()
based on platform_get_drvdata(pdev), interpreted as a struct
msm_drm_private *. That dereference is wrong because msm_gpu_init()
overwrites the GPU pdev's drvdata with adreno_smmu_priv pointer.

Fix this by using msm_gpu_use_separate_drm_dev() instead of relying on
drvdata.

Fixes: 643515a9cd09 ("drm/msm: rework binding of Imageon GPUs")
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 3052f3e36de0..66953e551d86 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -279,12 +279,10 @@ static int adreno_probe(struct platform_device *pdev)
 
 static void adreno_remove(struct platform_device *pdev)
 {
-	struct msm_drm_private *priv = platform_get_drvdata(pdev);
-
-	if (priv->kms_init)
-		component_del(&pdev->dev, &a3xx_ops);
-	else
+	if (msm_gpu_use_separate_drm_dev(pdev))
 		msm_gpu_remove(pdev, &a3xx_ops);
+	else
+		component_del(&pdev->dev, &a3xx_ops);
 }
 
 static void adreno_shutdown(struct platform_device *pdev)

-- 
2.51.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH RFT 4/5] drm/msm: Always use component model for standalone GPU
  2026-05-12 20:52 [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Akhil P Oommen
                   ` (2 preceding siblings ...)
  2026-05-12 20:52 ` [PATCH RFT 3/5] drm/msm/adreno: Fix invalid drvdata typecast in adreno_remove() Akhil P Oommen
@ 2026-05-12 20:52 ` Akhil P Oommen
  2026-05-13 11:43   ` Dmitry Baryshkov
  2026-05-12 20:53 ` [PATCH RFT 5/5] drm/msm: Attach a driver to the GMU Akhil P Oommen
  2026-07-26  5:22 ` [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Val Packett
  5 siblings, 1 reply; 15+ messages in thread
From: Akhil P Oommen @ 2026-05-12 20:52 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Akhil P Oommen

When separate_gpu_kms=1 (or the device is compatible with "amd,imageon"),
msm_gpu_no_components() evaluates true and adreno_probe() bypasses the
component framework by calling msm_gpu_probe() directly. In this case,
we skip creating components and directly bind the GPU.

That shortcut makes it impossible to add a second sibling on the GPU
master without introducing ad-hoc plumbing. To prepare for adding the
GMU as a peer component on this master, turn the GPU pdev into both a
component master and the sole component of itself in this path. A follow
up patch will introduce GMU as a component device.

Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 drivers/gpu/drm/msm/adreno/adreno_device.c | 20 ++++++++++++-----
 drivers/gpu/drm/msm/msm_drv.c              | 35 +++++++++++++++++++++++++-----
 drivers/gpu/drm/msm/msm_drv.h              |  6 ++---
 3 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 66953e551d86..67686424f3a1 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -271,18 +271,26 @@ static const struct component_ops a3xx_ops = {
 
 static int adreno_probe(struct platform_device *pdev)
 {
-	if (msm_gpu_use_separate_drm_dev(pdev))
-		return msm_gpu_probe(pdev, &a3xx_ops);
+	int ret;
 
-	return component_add(&pdev->dev, &a3xx_ops);
+	if (msm_gpu_use_separate_drm_dev(pdev)) {
+		ret = msm_gpu_probe(pdev);
+		if (ret)
+			return ret;
+	}
+
+	ret = component_add(&pdev->dev, &a3xx_ops);
+	if (ret && msm_gpu_use_separate_drm_dev(pdev))
+		msm_gpu_remove(pdev);
+
+	return ret;
 }
 
 static void adreno_remove(struct platform_device *pdev)
 {
+	component_del(&pdev->dev, &a3xx_ops);
 	if (msm_gpu_use_separate_drm_dev(pdev))
-		msm_gpu_remove(pdev, &a3xx_ops);
-	else
-		component_del(&pdev->dev, &a3xx_ops);
+		msm_gpu_remove(pdev);
 }
 
 static void adreno_shutdown(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index b61deafd02c3..af5aa7ff6179 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1097,10 +1097,25 @@ int msm_drv_probe(struct device *master_dev,
 	return 0;
 }
 
-int msm_gpu_probe(struct platform_device *pdev,
-		  const struct component_ops *ops)
+static int msm_gpu_drm_bind(struct device *dev)
+{
+	return msm_drm_init(dev, &msm_gpu_driver, NULL);
+}
+
+static void msm_gpu_drm_unbind(struct device *dev)
+{
+	msm_drm_uninit(dev, NULL);
+}
+
+static const struct component_master_ops msm_gpu_drm_ops = {
+	.bind = msm_gpu_drm_bind,
+	.unbind = msm_gpu_drm_unbind,
+};
+
+int msm_gpu_probe(struct platform_device *pdev)
 {
 	struct msm_drm_private *priv;
+	struct component_match *match = NULL;
 	int ret;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -1116,13 +1131,21 @@ int msm_gpu_probe(struct platform_device *pdev,
 	if (ret)
 		return ret;
 
-	return msm_drm_init(&pdev->dev, &msm_gpu_driver, ops);
+	/*
+	 * The GPU pdev acts as both the component master and the sole
+	 * component (added by adreno_probe()). Future patches add the
+	 * GMU node as a second component on this same master.
+	 */
+	drm_of_component_match_add(&pdev->dev, &match,
+				   component_compare_of, pdev->dev.of_node);
+
+	return component_master_add_with_match(&pdev->dev, &msm_gpu_drm_ops,
+					       match);
 }
 
-void msm_gpu_remove(struct platform_device *pdev,
-		    const struct component_ops *ops)
+void msm_gpu_remove(struct platform_device *pdev)
 {
-	msm_drm_uninit(&pdev->dev, ops);
+	component_master_del(&pdev->dev, &msm_gpu_drm_ops);
 }
 
 static int __init msm_drm_register(void)
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 6fcb696ceb7c..6264ff27496f 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -544,10 +544,8 @@ extern const struct component_master_ops msm_drm_ops;
 int msm_kms_pm_prepare(struct device *dev);
 void msm_kms_pm_complete(struct device *dev);
 
-int msm_gpu_probe(struct platform_device *pdev,
-		  const struct component_ops *ops);
-void msm_gpu_remove(struct platform_device *pdev,
-		    const struct component_ops *ops);
+int msm_gpu_probe(struct platform_device *pdev);
+void msm_gpu_remove(struct platform_device *pdev);
 int msm_drv_probe(struct device *dev,
 	int (*kms_init)(struct drm_device *dev),
 	struct msm_kms *kms);

-- 
2.51.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH RFT 5/5] drm/msm: Attach a driver to the GMU
  2026-05-12 20:52 [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Akhil P Oommen
                   ` (3 preceding siblings ...)
  2026-05-12 20:52 ` [PATCH RFT 4/5] drm/msm: Always use component model for standalone GPU Akhil P Oommen
@ 2026-05-12 20:53 ` Akhil P Oommen
  2026-05-13 11:46   ` Dmitry Baryshkov
  2026-07-26  5:22 ` [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Val Packett
  5 siblings, 1 reply; 15+ messages in thread
From: Akhil P Oommen @ 2026-05-12 20:53 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Akhil P Oommen

With the introduction of sync_state in the genpd framework, any consumer
device of GCC and GPUCC which is not bound to a driver will result in
bootup warnings like below:

[   24.362666] gcc-kaanapali 100000.clock-controller: sync_state() pending due to 3d37000.gmu
[   24.371210] gxclkctl-kaanapali 3d64000.clock-controller: sync_state() pending due to 3d37000.gmu
[   24.380268] gpucc-kaanapali 3d90000.clock-controller: sync_state() pending due to 3d37000.gmu

To silence these warnings and also to have a proper state in driver core,
attach a driver to the GMU and set it up as a component device for the drm
master device.

Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c      | 70 ++++++++++++++++++++++++++++--
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c      | 30 +++++--------
 drivers/gpu/drm/msm/adreno/a6xx_gpu.h      |  3 --
 drivers/gpu/drm/msm/adreno/adreno_device.c |  2 +
 drivers/gpu/drm/msm/adreno/adreno_gpu.h    |  3 +-
 drivers/gpu/drm/msm/msm_drv.c              | 17 ++++----
 6 files changed, 92 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index ec13b27feee7..71bb621b01f3 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -2063,7 +2063,7 @@ void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu)
 	pm_runtime_put(&gpu->pdev->dev);
 }
 
-void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
+static void a6xx_gmu_destroy(struct a6xx_gpu *a6xx_gpu)
 {
 	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
 	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
@@ -2143,7 +2143,7 @@ static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev, resource_si
 	return ret;
 }
 
-int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
+static int a6xx_gmu_wrapper_pdev_bind(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 {
 	struct platform_device *pdev = of_find_device_by_node(node);
 	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
@@ -2213,6 +2213,8 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 		goto err_mmio;
 	}
 
+	mutex_init(&gmu->lock);
+
 	gmu->initialized = true;
 
 	return 0;
@@ -2230,7 +2232,7 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 	return ret;
 }
 
-int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
+static int a6xx_gmu_pdev_bind(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 {
 	struct platform_device *pdev = of_find_device_by_node(node);
 	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
@@ -2415,6 +2417,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 	/* Initialize RPMh */
 	a6xx_gmu_rpmh_init(gmu);
 
+	mutex_init(&gmu->lock);
 	gmu->initialized = true;
 
 	return 0;
@@ -2444,3 +2447,64 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
 
 	return ret;
 }
+
+static int a6xx_gmu_bind(struct device *dev, struct device *master, void *data)
+{
+	int (*bind)(struct a6xx_gpu *gpu, struct device_node *node) = of_device_get_match_data(dev);
+	struct a6xx_gpu *a6xx_gpu = dev_get_drvdata(dev);
+
+	if (WARN_ON(!a6xx_gpu))
+		return -ENODEV;
+
+	return bind(a6xx_gpu, dev->of_node);
+}
+
+static void a6xx_gmu_unbind(struct device *dev, struct device *master, void *data)
+{
+	struct a6xx_gpu *a6xx_gpu = dev_get_drvdata(dev);
+
+	a6xx_gmu_destroy(a6xx_gpu);
+	dev_set_drvdata(dev, NULL);
+}
+
+static const struct component_ops a6xx_gmu_bind_ops = {
+	.bind   = a6xx_gmu_bind,
+	.unbind = a6xx_gmu_unbind,
+};
+
+static int a6xx_gmu_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &a6xx_gmu_bind_ops);
+}
+
+static void a6xx_gmu_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &a6xx_gmu_bind_ops);
+}
+
+static const struct of_device_id a6xx_gmu_dt_match[] = {
+	{ .compatible = "qcom,adreno-gmu", .data = a6xx_gmu_pdev_bind },
+	{ .compatible = "qcom,adreno-rgmu", .data = a6xx_gmu_wrapper_pdev_bind },
+	{ .compatible = "qcom,adreno-gmu-wrapper", .data = a6xx_gmu_wrapper_pdev_bind },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, a6xx_gmu_dt_match);
+
+static struct platform_driver adreno_gmu_driver = {
+	.probe = a6xx_gmu_probe,
+	.remove = a6xx_gmu_remove,
+	.driver = {
+		.name = "adreno_gmu",
+		.of_match_table = a6xx_gmu_dt_match,
+	},
+};
+
+void __init adreno_gmu_register(void)
+{
+	platform_driver_register(&adreno_gmu_driver);
+}
+
+void __exit adreno_gmu_unregister(void)
+{
+	platform_driver_unregister(&adreno_gmu_driver);
+}
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index d5aba072f44c..b4ae38e1a3d8 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -10,6 +10,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/devfreq.h>
+#include <linux/of_platform.h>
 #include <linux/pm_domain.h>
 #include <linux/soc/qcom/llcc-qcom.h>
 
@@ -2409,8 +2410,6 @@ static void a6xx_destroy(struct msm_gpu *gpu)
 
 	a6xx_llc_slices_destroy(a6xx_gpu);
 
-	a6xx_gmu_remove(a6xx_gpu);
-
 	adreno_gpu_cleanup(adreno_gpu);
 
 	kfree(a6xx_gpu);
@@ -2622,6 +2621,7 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
 	struct adreno_platform_config *config = pdev->dev.platform_data;
 	const struct adreno_info *info = config->info;
 	struct device_node *node;
+	struct platform_device *gmu_pdev;
 	struct a6xx_gpu *a6xx_gpu;
 	struct adreno_gpu *adreno_gpu;
 	struct msm_gpu *gpu;
@@ -2637,17 +2637,14 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
 	adreno_gpu = &a6xx_gpu->base;
 	gpu = &adreno_gpu->base;
 
-	mutex_init(&a6xx_gpu->gmu.lock);
 	spin_lock_init(&a6xx_gpu->aperture_lock);
 
 	adreno_gpu->registers = NULL;
 
-	/* Check if there is a GMU phandle and set it up */
 	node = of_parse_phandle(pdev->dev.of_node, "qcom,gmu", 0);
-	/* FIXME: How do we gracefully handle this? */
-	BUG_ON(!node);
-
-	adreno_gpu->gmu_is_wrapper = of_device_is_compatible(node, "qcom,adreno-gmu-wrapper");
+	WARN_ON(!node);
+	adreno_gpu->gmu_is_wrapper = of_device_is_compatible(node,
+							     "qcom,adreno-gmu-wrapper");
 
 	adreno_gpu->base.hw_apriv =
 		!!(info->quirks & ADRENO_QUIRK_HAS_HW_APRIV);
@@ -2686,16 +2683,6 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
 	if (adreno_is_a618(adreno_gpu) || adreno_is_7c3(adreno_gpu))
 		priv->gpu_clamp_to_idle = true;
 
-	if (adreno_has_gmu_wrapper(adreno_gpu) || adreno_has_rgmu(adreno_gpu))
-		ret = a6xx_gmu_wrapper_init(a6xx_gpu, node);
-	else
-		ret = a6xx_gmu_init(a6xx_gpu, node);
-	of_node_put(node);
-	if (ret) {
-		a6xx_destroy(&(a6xx_gpu->base.base));
-		return ERR_PTR(ret);
-	}
-
 	adreno_gpu->uche_trap_base = 0x1fffffffff000ull;
 
 	msm_mmu_set_fault_handler(to_msm_vm(gpu->vm)->mmu, gpu,
@@ -2710,6 +2697,13 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
 	/* Set up the preemption specific bits and pieces for each ringbuffer */
 	a6xx_preempt_init(gpu);
 
+	gmu_pdev = of_find_device_by_node(node);
+	of_node_put(node);
+	if (gmu_pdev) {
+		platform_set_drvdata(gmu_pdev, a6xx_gpu);
+		put_device(&gmu_pdev->dev);
+	}
+
 	return gpu;
 }
 
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
index eb431e5e00b1..fe8d68df9944 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
@@ -268,9 +268,6 @@ bool a6xx_gmu_isidle(struct a6xx_gmu *gmu);
 int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state);
 void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state);
 
-int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
-int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
-void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu);
 void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu);
 
 void a6xx_preempt_init(struct msm_gpu *gpu);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 67686424f3a1..d70f98e283d5 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -423,6 +423,7 @@ void __init adreno_register(void)
 		return;
 
 	platform_driver_register(&adreno_driver);
+	adreno_gmu_register();
 }
 
 void __exit adreno_unregister(void)
@@ -430,5 +431,6 @@ void __exit adreno_unregister(void)
 	if (skip_gpu)
 		return;
 
+	adreno_gmu_unregister();
 	platform_driver_unregister(&adreno_driver);
 }
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index ec643b84646b..3a05cd98d215 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -642,7 +642,8 @@ int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state);
 int adreno_gpu_state_put(struct msm_gpu_state *state);
 void adreno_show_object(struct drm_printer *p, void **ptr, int len,
 		bool *encoded);
-
+void adreno_gmu_register(void);
+void adreno_gmu_unregister(void);
 /*
  * Common helper function to initialize the default address space for arm-smmu
  * attached targets
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index af5aa7ff6179..426255fd0801 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1021,7 +1021,7 @@ static const struct of_device_id msm_gpu_match[] = {
 static int add_gpu_components(struct device *dev,
 			      struct component_match **matchptr)
 {
-	struct device_node *np;
+	struct device_node *np, *gmu_np;
 
 	np = of_find_matching_node(NULL, msm_gpu_match);
 	if (!np)
@@ -1030,6 +1030,11 @@ static int add_gpu_components(struct device *dev,
 	if (of_device_is_available(np) && adreno_has_gpu(np))
 		drm_of_component_match_add(dev, matchptr, component_compare_of, np);
 
+	gmu_np = of_parse_phandle(np, "qcom,gmu", 0);
+	if (of_device_is_available(gmu_np))
+		drm_of_component_match_add(dev, matchptr, component_compare_of, gmu_np);
+
+	of_node_put(gmu_np);
 	of_node_put(np);
 
 	return 0;
@@ -1131,13 +1136,9 @@ int msm_gpu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	/*
-	 * The GPU pdev acts as both the component master and the sole
-	 * component (added by adreno_probe()). Future patches add the
-	 * GMU node as a second component on this same master.
-	 */
-	drm_of_component_match_add(&pdev->dev, &match,
-				   component_compare_of, pdev->dev.of_node);
+	ret = add_gpu_components(&pdev->dev, &match);
+	if (ret)
+		return ret;
 
 	return component_master_add_with_match(&pdev->dev, &msm_gpu_drm_ops,
 					       match);

-- 
2.51.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFT 1/5] drm/msm/adreno/a6xx: Mark cxpd device_link as stateless
  2026-05-12 20:52 ` [PATCH RFT 1/5] drm/msm/adreno/a6xx: Mark cxpd device_link as stateless Akhil P Oommen
@ 2026-05-13  0:56   ` Dmitry Baryshkov
  0 siblings, 0 replies; 15+ messages in thread
From: Dmitry Baryshkov @ 2026-05-13  0:56 UTC (permalink / raw)
  To: Akhil P Oommen
  Cc: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On Wed, May 13, 2026 at 02:22:56AM +0530, Akhil P Oommen wrote:
> Since the cxpd virtual device is a driverless device, it has no real
> struct device_driver bound it the way a normal platform device does. So,
> the managed lifecycle doesn't map cleanly onto it. Since the lifecycle of
> this device_link is managed by the msm driver, pass DL_FLAG_STATELESS
> together with the existing DL_FLAG_PM_RUNTIME flag.
> 
> This fix is required to avoid the below splat when a driver is attached to
> the GMU:
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>


-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFT 3/5] drm/msm/adreno: Fix invalid drvdata typecast in adreno_remove()
  2026-05-12 20:52 ` [PATCH RFT 3/5] drm/msm/adreno: Fix invalid drvdata typecast in adreno_remove() Akhil P Oommen
@ 2026-05-13  5:39   ` Dmitry Baryshkov
  0 siblings, 0 replies; 15+ messages in thread
From: Dmitry Baryshkov @ 2026-05-13  5:39 UTC (permalink / raw)
  To: Akhil P Oommen
  Cc: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On Wed, May 13, 2026 at 02:22:58AM +0530, Akhil P Oommen wrote:
> adreno_remove() decides between component_del() and msm_gpu_remove()
> based on platform_get_drvdata(pdev), interpreted as a struct
> msm_drm_private *. That dereference is wrong because msm_gpu_init()
> overwrites the GPU pdev's drvdata with adreno_smmu_priv pointer.
> 
> Fix this by using msm_gpu_use_separate_drm_dev() instead of relying on
> drvdata.
> 
> Fixes: 643515a9cd09 ("drm/msm: rework binding of Imageon GPUs")
> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
> ---
>  drivers/gpu/drm/msm/adreno/adreno_device.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFT 2/5] drm/msm: Centralize the standalone drm device check for GPU
  2026-05-12 20:52 ` [PATCH RFT 2/5] drm/msm: Centralize the standalone drm device check for GPU Akhil P Oommen
@ 2026-05-13  5:41   ` Dmitry Baryshkov
  2026-05-13 21:10     ` Akhil P Oommen
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry Baryshkov @ 2026-05-13  5:41 UTC (permalink / raw)
  To: Akhil P Oommen
  Cc: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On Wed, May 13, 2026 at 02:22:57AM +0530, Akhil P Oommen wrote:
> Replace msm_gpu_no_components() with msm_gpu_use_separate_drm_dev() and
> move the platform-specific check for "amd,imageon" into the helper so the
> policy is centralized and reused by both the core driver and adreno probe
> path. No functional change intended.
> 
> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
> ---
>  drivers/gpu/drm/msm/adreno/adreno_device.c |  3 +--
>  drivers/gpu/drm/msm/msm_drv.c              | 11 +++++++----
>  drivers/gpu/drm/msm/msm_drv.h              |  2 +-
>  3 files changed, 9 insertions(+), 7 deletions(-)

For the next iteration please swap this and the next patches (yes,
introducing some code duplication). It's generally not recommended to
have fixes which depend on a non-fix patches.


-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFT 4/5] drm/msm: Always use component model for standalone GPU
  2026-05-12 20:52 ` [PATCH RFT 4/5] drm/msm: Always use component model for standalone GPU Akhil P Oommen
@ 2026-05-13 11:43   ` Dmitry Baryshkov
  2026-05-13 21:09     ` Akhil P Oommen
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry Baryshkov @ 2026-05-13 11:43 UTC (permalink / raw)
  To: Akhil P Oommen
  Cc: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On Wed, May 13, 2026 at 02:22:59AM +0530, Akhil P Oommen wrote:
> When separate_gpu_kms=1 (or the device is compatible with "amd,imageon"),
> msm_gpu_no_components() evaluates true and adreno_probe() bypasses the
> component framework by calling msm_gpu_probe() directly. In this case,
> we skip creating components and directly bind the GPU.
> 
> That shortcut makes it impossible to add a second sibling on the GPU
> master without introducing ad-hoc plumbing. To prepare for adding the
> GMU as a peer component on this master, turn the GPU pdev into both a
> component master and the sole component of itself in this path. A follow
> up patch will introduce GMU as a component device.
> 
> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
> ---
>  drivers/gpu/drm/msm/adreno/adreno_device.c | 20 ++++++++++++-----
>  drivers/gpu/drm/msm/msm_drv.c              | 35 +++++++++++++++++++++++++-----
>  drivers/gpu/drm/msm/msm_drv.h              |  6 ++---
>  3 files changed, 45 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
> index 66953e551d86..67686424f3a1 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
> @@ -271,18 +271,26 @@ static const struct component_ops a3xx_ops = {
>  
>  static int adreno_probe(struct platform_device *pdev)
>  {
> -	if (msm_gpu_use_separate_drm_dev(pdev))
> -		return msm_gpu_probe(pdev, &a3xx_ops);
> +	int ret;
>  
> -	return component_add(&pdev->dev, &a3xx_ops);
> +	if (msm_gpu_use_separate_drm_dev(pdev)) {
> +		ret = msm_gpu_probe(pdev);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	ret = component_add(&pdev->dev, &a3xx_ops);
> +	if (ret && msm_gpu_use_separate_drm_dev(pdev))
> +		msm_gpu_remove(pdev);

What about making it more clear:

	if (!msm_gpu_use_separate_drm_dev(pdev))
		return component_add(&pdev->dev, &a3xx_ops);

	ret = msm_gpu_probe(pdev);
	if (ret)
		return ret;

	ret = component_add(&pdev->dev, &a3xx_ops);

	if (ret)
		msm_gpu_remove(pdev);

	return ret;

However with this patch in place, maybe it's easier to use the main
msm_drv_probe()? It would need some fixes to handle !kms case as the
GPU-only, but it looks very similar to your new functions.


> +
> +	return ret;
>  }
>  
>  static void adreno_remove(struct platform_device *pdev)
>  {
> +	component_del(&pdev->dev, &a3xx_ops);
>  	if (msm_gpu_use_separate_drm_dev(pdev))
> -		msm_gpu_remove(pdev, &a3xx_ops);
> -	else
> -		component_del(&pdev->dev, &a3xx_ops);
> +		msm_gpu_remove(pdev);
>  }
>  
>  static void adreno_shutdown(struct platform_device *pdev)
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index b61deafd02c3..af5aa7ff6179 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -1097,10 +1097,25 @@ int msm_drv_probe(struct device *master_dev,
>  	return 0;
>  }
>  
> -int msm_gpu_probe(struct platform_device *pdev,
> -		  const struct component_ops *ops)
> +static int msm_gpu_drm_bind(struct device *dev)
> +{
> +	return msm_drm_init(dev, &msm_gpu_driver, NULL);

With this patch in place, we can remove the ops argument from
msm_drm_init() and msm_drm_uninit().

> +}
> +
> +static void msm_gpu_drm_unbind(struct device *dev)
> +{
> +	msm_drm_uninit(dev, NULL);
> +}
> +
> +static const struct component_master_ops msm_gpu_drm_ops = {
> +	.bind = msm_gpu_drm_bind,
> +	.unbind = msm_gpu_drm_unbind,
> +};
> +
> +int msm_gpu_probe(struct platform_device *pdev)
>  {
>  	struct msm_drm_private *priv;
> +	struct component_match *match = NULL;
>  	int ret;
>  
>  	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> @@ -1116,13 +1131,21 @@ int msm_gpu_probe(struct platform_device *pdev,
>  	if (ret)
>  		return ret;
>  
> -	return msm_drm_init(&pdev->dev, &msm_gpu_driver, ops);
> +	/*
> +	 * The GPU pdev acts as both the component master and the sole
> +	 * component (added by adreno_probe()). Future patches add the
> +	 * GMU node as a second component on this same master.
> +	 */
> +	drm_of_component_match_add(&pdev->dev, &match,
> +				   component_compare_of, pdev->dev.of_node);
> +
> +	return component_master_add_with_match(&pdev->dev, &msm_gpu_drm_ops,
> +					       match);
>  }
>  
> -void msm_gpu_remove(struct platform_device *pdev,
> -		    const struct component_ops *ops)
> +void msm_gpu_remove(struct platform_device *pdev)
>  {
> -	msm_drm_uninit(&pdev->dev, ops);
> +	component_master_del(&pdev->dev, &msm_gpu_drm_ops);
>  }
>  
>  static int __init msm_drm_register(void)
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index 6fcb696ceb7c..6264ff27496f 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -544,10 +544,8 @@ extern const struct component_master_ops msm_drm_ops;
>  int msm_kms_pm_prepare(struct device *dev);
>  void msm_kms_pm_complete(struct device *dev);
>  
> -int msm_gpu_probe(struct platform_device *pdev,
> -		  const struct component_ops *ops);
> -void msm_gpu_remove(struct platform_device *pdev,
> -		    const struct component_ops *ops);
> +int msm_gpu_probe(struct platform_device *pdev);
> +void msm_gpu_remove(struct platform_device *pdev);
>  int msm_drv_probe(struct device *dev,
>  	int (*kms_init)(struct drm_device *dev),
>  	struct msm_kms *kms);
> 
> -- 
> 2.51.0
> 

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFT 5/5] drm/msm: Attach a driver to the GMU
  2026-05-12 20:53 ` [PATCH RFT 5/5] drm/msm: Attach a driver to the GMU Akhil P Oommen
@ 2026-05-13 11:46   ` Dmitry Baryshkov
  0 siblings, 0 replies; 15+ messages in thread
From: Dmitry Baryshkov @ 2026-05-13 11:46 UTC (permalink / raw)
  To: Akhil P Oommen
  Cc: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On Wed, May 13, 2026 at 02:23:00AM +0530, Akhil P Oommen wrote:
> With the introduction of sync_state in the genpd framework, any consumer
> device of GCC and GPUCC which is not bound to a driver will result in
> bootup warnings like below:
> 
> [   24.362666] gcc-kaanapali 100000.clock-controller: sync_state() pending due to 3d37000.gmu
> [   24.371210] gxclkctl-kaanapali 3d64000.clock-controller: sync_state() pending due to 3d37000.gmu
> [   24.380268] gpucc-kaanapali 3d90000.clock-controller: sync_state() pending due to 3d37000.gmu
> 
> To silence these warnings and also to have a proper state in driver core,
> attach a driver to the GMU and set it up as a component device for the drm
> master device.
> 
> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.c      | 70 ++++++++++++++++++++++++++++--
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c      | 30 +++++--------
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.h      |  3 --
>  drivers/gpu/drm/msm/adreno/adreno_device.c |  2 +
>  drivers/gpu/drm/msm/adreno/adreno_gpu.h    |  3 +-
>  drivers/gpu/drm/msm/msm_drv.c              | 17 ++++----
>  6 files changed, 92 insertions(+), 33 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>


-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFT 4/5] drm/msm: Always use component model for standalone GPU
  2026-05-13 11:43   ` Dmitry Baryshkov
@ 2026-05-13 21:09     ` Akhil P Oommen
  0 siblings, 0 replies; 15+ messages in thread
From: Akhil P Oommen @ 2026-05-13 21:09 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On 5/13/2026 5:13 PM, Dmitry Baryshkov wrote:
> On Wed, May 13, 2026 at 02:22:59AM +0530, Akhil P Oommen wrote:
>> When separate_gpu_kms=1 (or the device is compatible with "amd,imageon"),
>> msm_gpu_no_components() evaluates true and adreno_probe() bypasses the
>> component framework by calling msm_gpu_probe() directly. In this case,
>> we skip creating components and directly bind the GPU.
>>
>> That shortcut makes it impossible to add a second sibling on the GPU
>> master without introducing ad-hoc plumbing. To prepare for adding the
>> GMU as a peer component on this master, turn the GPU pdev into both a
>> component master and the sole component of itself in this path. A follow
>> up patch will introduce GMU as a component device.
>>
>> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
>> ---
>>  drivers/gpu/drm/msm/adreno/adreno_device.c | 20 ++++++++++++-----
>>  drivers/gpu/drm/msm/msm_drv.c              | 35 +++++++++++++++++++++++++-----
>>  drivers/gpu/drm/msm/msm_drv.h              |  6 ++---
>>  3 files changed, 45 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
>> index 66953e551d86..67686424f3a1 100644
>> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
>> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
>> @@ -271,18 +271,26 @@ static const struct component_ops a3xx_ops = {
>>  
>>  static int adreno_probe(struct platform_device *pdev)
>>  {
>> -	if (msm_gpu_use_separate_drm_dev(pdev))
>> -		return msm_gpu_probe(pdev, &a3xx_ops);
>> +	int ret;
>>  
>> -	return component_add(&pdev->dev, &a3xx_ops);
>> +	if (msm_gpu_use_separate_drm_dev(pdev)) {
>> +		ret = msm_gpu_probe(pdev);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	ret = component_add(&pdev->dev, &a3xx_ops);
>> +	if (ret && msm_gpu_use_separate_drm_dev(pdev))
>> +		msm_gpu_remove(pdev);
> 
> What about making it more clear:
> 
> 	if (!msm_gpu_use_separate_drm_dev(pdev))
> 		return component_add(&pdev->dev, &a3xx_ops);
> 
> 	ret = msm_gpu_probe(pdev);
> 	if (ret)
> 		return ret;
> 
> 	ret = component_add(&pdev->dev, &a3xx_ops);
> 
> 	if (ret)
> 		msm_gpu_remove(pdev);
> 
> 	return ret;

Ack. this is more readable.

> 
> However with this patch in place, maybe it's easier to use the main
> msm_drv_probe()? It would need some fixes to handle !kms case as the
> GPU-only, but it looks very similar to your new functions.
>

Agree. Will do this in a separate patch in the next rev.

> 
>> +
>> +	return ret;
>>  }
>>  
>>  static void adreno_remove(struct platform_device *pdev)
>>  {
>> +	component_del(&pdev->dev, &a3xx_ops);
>>  	if (msm_gpu_use_separate_drm_dev(pdev))
>> -		msm_gpu_remove(pdev, &a3xx_ops);
>> -	else
>> -		component_del(&pdev->dev, &a3xx_ops);
>> +		msm_gpu_remove(pdev);
>>  }
>>  
>>  static void adreno_shutdown(struct platform_device *pdev)
>> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
>> index b61deafd02c3..af5aa7ff6179 100644
>> --- a/drivers/gpu/drm/msm/msm_drv.c
>> +++ b/drivers/gpu/drm/msm/msm_drv.c
>> @@ -1097,10 +1097,25 @@ int msm_drv_probe(struct device *master_dev,
>>  	return 0;
>>  }
>>  
>> -int msm_gpu_probe(struct platform_device *pdev,
>> -		  const struct component_ops *ops)
>> +static int msm_gpu_drm_bind(struct device *dev)
>> +{
>> +	return msm_drm_init(dev, &msm_gpu_driver, NULL);
> 
> With this patch in place, we can remove the ops argument from
> msm_drm_init() and msm_drm_uninit().

I didn't notice this. Will drop the unused arg. Thanks.

-Akhil.

> 
>> +}
>> +
>> +static void msm_gpu_drm_unbind(struct device *dev)
>> +{
>> +	msm_drm_uninit(dev, NULL);
>> +}
>> +
>> +static const struct component_master_ops msm_gpu_drm_ops = {
>> +	.bind = msm_gpu_drm_bind,
>> +	.unbind = msm_gpu_drm_unbind,
>> +};
>> +
>> +int msm_gpu_probe(struct platform_device *pdev)
>>  {
>>  	struct msm_drm_private *priv;
>> +	struct component_match *match = NULL;
>>  	int ret;
>>  
>>  	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>> @@ -1116,13 +1131,21 @@ int msm_gpu_probe(struct platform_device *pdev,
>>  	if (ret)
>>  		return ret;
>>  
>> -	return msm_drm_init(&pdev->dev, &msm_gpu_driver, ops);
>> +	/*
>> +	 * The GPU pdev acts as both the component master and the sole
>> +	 * component (added by adreno_probe()). Future patches add the
>> +	 * GMU node as a second component on this same master.
>> +	 */
>> +	drm_of_component_match_add(&pdev->dev, &match,
>> +				   component_compare_of, pdev->dev.of_node);
>> +
>> +	return component_master_add_with_match(&pdev->dev, &msm_gpu_drm_ops,
>> +					       match);
>>  }
>>  
>> -void msm_gpu_remove(struct platform_device *pdev,
>> -		    const struct component_ops *ops)
>> +void msm_gpu_remove(struct platform_device *pdev)
>>  {
>> -	msm_drm_uninit(&pdev->dev, ops);
>> +	component_master_del(&pdev->dev, &msm_gpu_drm_ops);
>>  }
>>  
>>  static int __init msm_drm_register(void)
>> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
>> index 6fcb696ceb7c..6264ff27496f 100644
>> --- a/drivers/gpu/drm/msm/msm_drv.h
>> +++ b/drivers/gpu/drm/msm/msm_drv.h
>> @@ -544,10 +544,8 @@ extern const struct component_master_ops msm_drm_ops;
>>  int msm_kms_pm_prepare(struct device *dev);
>>  void msm_kms_pm_complete(struct device *dev);
>>  
>> -int msm_gpu_probe(struct platform_device *pdev,
>> -		  const struct component_ops *ops);
>> -void msm_gpu_remove(struct platform_device *pdev,
>> -		    const struct component_ops *ops);
>> +int msm_gpu_probe(struct platform_device *pdev);
>> +void msm_gpu_remove(struct platform_device *pdev);
>>  int msm_drv_probe(struct device *dev,
>>  	int (*kms_init)(struct drm_device *dev),
>>  	struct msm_kms *kms);
>>
>> -- 
>> 2.51.0
>>
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFT 2/5] drm/msm: Centralize the standalone drm device check for GPU
  2026-05-13  5:41   ` Dmitry Baryshkov
@ 2026-05-13 21:10     ` Akhil P Oommen
  0 siblings, 0 replies; 15+ messages in thread
From: Akhil P Oommen @ 2026-05-13 21:10 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Konrad Dybcio, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, David Airlie,
	Simona Vetter, Neil Armstrong, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On 5/13/2026 11:11 AM, Dmitry Baryshkov wrote:
> On Wed, May 13, 2026 at 02:22:57AM +0530, Akhil P Oommen wrote:
>> Replace msm_gpu_no_components() with msm_gpu_use_separate_drm_dev() and
>> move the platform-specific check for "amd,imageon" into the helper so the
>> policy is centralized and reused by both the core driver and adreno probe
>> path. No functional change intended.
>>
>> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
>> ---
>>  drivers/gpu/drm/msm/adreno/adreno_device.c |  3 +--
>>  drivers/gpu/drm/msm/msm_drv.c              | 11 +++++++----
>>  drivers/gpu/drm/msm/msm_drv.h              |  2 +-
>>  3 files changed, 9 insertions(+), 7 deletions(-)
> 
> For the next iteration please swap this and the next patches (yes,
> introducing some code duplication). It's generally not recommended to
> have fixes which depend on a non-fix patches.

Ack.

-Akhil.

> 
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFT 0/5] drm/msm: Attach a driver to GMU
  2026-05-12 20:52 [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Akhil P Oommen
                   ` (4 preceding siblings ...)
  2026-05-12 20:53 ` [PATCH RFT 5/5] drm/msm: Attach a driver to the GMU Akhil P Oommen
@ 2026-07-26  5:22 ` Val Packett
  2026-07-26 16:05   ` Akhil P Oommen
  5 siblings, 1 reply; 15+ messages in thread
From: Val Packett @ 2026-07-26  5:22 UTC (permalink / raw)
  To: Akhil P Oommen, Rob Clark, Sean Paul, Konrad Dybcio,
	Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Marijn Suijten,
	David Airlie, Simona Vetter, Neil Armstrong
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel


On 5/12/26 5:52 PM, Akhil P Oommen wrote:
> With the introduction of sync_state in the genpd framework, any consumer
> device of GCC and GPUCC which is not bound to a driver will result in
> bootup warnings like below:
>
> [   24.362666] gcc-kaanapali 100000.clock-controller: sync_state() pending due to 3d37000.gmu
> [   24.371210] gxclkctl-kaanapali 3d64000.clock-controller: sync_state() pending due to 3d37000.gmu
> [   24.380268] gpucc-kaanapali 3d90000.clock-controller: sync_state() pending due to 3d37000.gmu
>
> To silence these warnings and also to have a proper state in driver core,
> attach a driver to the GMU and set it up as a component device for the drm
> master device.
>
> The first few patches are preparatory fixes and refactorings. And the
> final patch introduces a driver for GMU devices.
>
> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com> [..]

For the series:

Tested-by: Val Packett <val@packett.cool> # x1e80100-dell-latitude-7455

When I first saw this series I didn't think this was important, silence 
warnings whatever, but since a couple months ago deep suspend started 
randomly not completing (bouncing back as soon as everything got 
suspended) and I didn't know what it was… just now in #aarch64-laptops 
this was brought up again and turns out, yeah. It was bouncing back due 
to sync_state not completing for everything. This series actually makes 
suspend reliable again!


Thanks,
~val


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH RFT 0/5] drm/msm: Attach a driver to GMU
  2026-07-26  5:22 ` [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Val Packett
@ 2026-07-26 16:05   ` Akhil P Oommen
  0 siblings, 0 replies; 15+ messages in thread
From: Akhil P Oommen @ 2026-07-26 16:05 UTC (permalink / raw)
  To: Val Packett
  Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Rob Clark,
	Sean Paul, Konrad Dybcio, Dmitry Baryshkov, Abhinav Kumar,
	Jessica Zhang, Marijn Suijten, David Airlie, Simona Vetter,
	Neil Armstrong

On 7/26/2026 10:52 AM, Val Packett wrote:
> 
> On 5/12/26 5:52 PM, Akhil P Oommen wrote:
>> With the introduction of sync_state in the genpd framework, any consumer
>> device of GCC and GPUCC which is not bound to a driver will result in
>> bootup warnings like below:
>>
>> [   24.362666] gcc-kaanapali 100000.clock-controller: sync_state()
>> pending due to 3d37000.gmu
>> [   24.371210] gxclkctl-kaanapali 3d64000.clock-controller:
>> sync_state() pending due to 3d37000.gmu
>> [   24.380268] gpucc-kaanapali 3d90000.clock-controller: sync_state()
>> pending due to 3d37000.gmu
>>
>> To silence these warnings and also to have a proper state in driver core,
>> attach a driver to the GMU and set it up as a component device for the
>> drm
>> master device.
>>
>> The first few patches are preparatory fixes and refactorings. And the
>> final patch introduces a driver for GMU devices.
>>
>> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com> [..]
> 
> For the series:
> 
> Tested-by: Val Packett <val@packett.cool> # x1e80100-dell-latitude-7455
> 
> When I first saw this series I didn't think this was important, silence
> warnings whatever, but since a couple months ago deep suspend started
> randomly not completing (bouncing back as soon as everything got
> suspended) and I didn't know what it was… just now in #aarch64-laptops
> this was brought up again and turns out, yeah. It was bouncing back due
> to sync_state not completing for everything. This series actually makes
> suspend reliable again!

I didn't get a chance to revisit this series after my vacation. I am too
not aware of any impact outside of those dmesg warnings. Any chance this
recent rpmh related fix is helping with the deep sleep instead of this
series:

https://lore.kernel.org/lkml/20260605-assorted-fixes-june-v1-1-2caa04f7287c@oss.qualcomm.com/


I will send a rev 2. Thanks for the T-b tag.

-Akhil.

> 
> 
> Thanks,
> ~val
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-07-26 16:05 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-12 20:52 [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Akhil P Oommen
2026-05-12 20:52 ` [PATCH RFT 1/5] drm/msm/adreno/a6xx: Mark cxpd device_link as stateless Akhil P Oommen
2026-05-13  0:56   ` Dmitry Baryshkov
2026-05-12 20:52 ` [PATCH RFT 2/5] drm/msm: Centralize the standalone drm device check for GPU Akhil P Oommen
2026-05-13  5:41   ` Dmitry Baryshkov
2026-05-13 21:10     ` Akhil P Oommen
2026-05-12 20:52 ` [PATCH RFT 3/5] drm/msm/adreno: Fix invalid drvdata typecast in adreno_remove() Akhil P Oommen
2026-05-13  5:39   ` Dmitry Baryshkov
2026-05-12 20:52 ` [PATCH RFT 4/5] drm/msm: Always use component model for standalone GPU Akhil P Oommen
2026-05-13 11:43   ` Dmitry Baryshkov
2026-05-13 21:09     ` Akhil P Oommen
2026-05-12 20:53 ` [PATCH RFT 5/5] drm/msm: Attach a driver to the GMU Akhil P Oommen
2026-05-13 11:46   ` Dmitry Baryshkov
2026-07-26  5:22 ` [PATCH RFT 0/5] drm/msm: Attach a driver to GMU Val Packett
2026-07-26 16:05   ` Akhil P Oommen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®