Skip to content

Commit 894abb6

Browse files
committed
QCLINUX: drm/msm: Auto-detect separate GPU KMS mode based on HW topology
On platforms with multiple display subsystems, such as SA8775P, the GPU binds to the first display subsystem that probes. This implicit binding prevents subsequent display subsystems from probing successfully, breaking multi-display support. Use the tristate separate_gpu_kms module parameter with the default value set to auto (-1). In auto mode, the driver selects the binding behavior based on the number of GPUs and display subsystems. This allows display subsystems to probe independently when required, while preserving the existing single-card behavior on simpler systems. The separate_gpu_kms module parameter has the following semantics: -1 (auto, default): Select the binding mode based on hardware topology. If exactly one GPU and one display subsystem are present, bind them together to form a single DRM device. Otherwise, expose the GPU and display subsystems as separate DRM devices. 0: Always bind the GPU and display together to form a single DRM device. 1: Always expose the GPU and display subsystems as separate DRM devices. This ensures correct probing on multi-display platforms without affecting single-display, single-GPU systems. Signed-off-by: Mahadevan P <mahap@qti.qualcomm.com> Signed-off-by: Nabige Aala <naala@qti.qualcomm.com>
1 parent ae68d8c commit 894abb6

File tree

4 files changed

+58
-9
lines changed

4 files changed

+58
-9
lines changed

drivers/gpu/drm/msm/adreno/adreno_device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ static const struct component_ops a3xx_ops = {
270270
static int adreno_probe(struct platform_device *pdev)
271271
{
272272
if (of_device_is_compatible(pdev->dev.of_node, "amd,imageon") ||
273-
msm_gpu_no_components())
273+
msm_seperate_gpu_kms_components())
274274
return msm_gpu_probe(pdev, &a3xx_ops);
275275

276276
return component_add(&pdev->dev, &a3xx_ops);

drivers/gpu/drm/msm/msm_drv.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,48 @@ static bool modeset = true;
5454
MODULE_PARM_DESC(modeset, "Use kernel modesetting [KMS] (1=on (default), 0=disable)");
5555
module_param(modeset, bool, 0600);
5656

57-
static bool separate_gpu_kms;
58-
MODULE_PARM_DESC(separate_gpu_drm, "Use separate DRM device for the GPU (0=single DRM device for both GPU and display (default), 1=two DRM devices)");
59-
module_param(separate_gpu_kms, bool, 0400);
57+
static int separate_gpu_kms = -1;
58+
MODULE_PARM_DESC(separate_gpu_kms,
59+
"Use separate DRM device for the GPU "
60+
"(-1=auto (default), 0=single DRM device, 1=separate DRM devices)");
61+
module_param(separate_gpu_kms, int, 0400);
6062

6163
DECLARE_FAULT_ATTR(fail_gem_alloc);
6264
DECLARE_FAULT_ATTR(fail_gem_iova);
6365

64-
bool msm_gpu_no_components(void)
66+
static const struct of_device_id msm_gpu_match[];
67+
68+
static int msm_count_gpus(void)
69+
{
70+
struct device_node *np;
71+
int count = 0;
72+
73+
for_each_matching_node(np, msm_gpu_match) {
74+
if (of_device_is_available(np) && adreno_has_gpu(np))
75+
count++;
76+
}
77+
78+
return count;
79+
}
80+
81+
static bool msm_separate_gpu_kms_auto(void)
82+
{
83+
int gpus = msm_count_gpus();
84+
int mdss = msm_mdss_count_masters();
85+
86+
if (mdss == 2 && gpus == 1)
87+
return true;
88+
89+
return false;
90+
}
91+
92+
bool msm_seperate_gpu_kms_components(void)
6593
{
66-
return separate_gpu_kms;
94+
if (separate_gpu_kms == 1)
95+
return true;
96+
if (separate_gpu_kms == 0)
97+
return false;
98+
return msm_separate_gpu_kms_auto();
6799
}
68100

69101
static int msm_drm_uninit(struct device *dev, const struct component_ops *gpu_ops)
@@ -1018,7 +1050,7 @@ static int add_gpu_components(struct device *dev,
10181050
static int msm_drm_bind(struct device *dev)
10191051
{
10201052
return msm_drm_init(dev,
1021-
msm_gpu_no_components() ?
1053+
msm_seperate_gpu_kms_components() ?
10221054
&msm_kms_driver :
10231055
&msm_driver,
10241056
NULL);
@@ -1057,7 +1089,7 @@ int msm_drv_probe(struct device *master_dev,
10571089
return ret;
10581090
}
10591091

1060-
if (!msm_gpu_no_components()) {
1092+
if (!msm_seperate_gpu_kms_components()) {
10611093
ret = add_gpu_components(master_dev, &match);
10621094
if (ret)
10631095
return ret;

drivers/gpu/drm/msm/msm_drv.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,8 @@ void msm_kms_shutdown(struct platform_device *pdev);
555555

556556
bool msm_disp_drv_should_bind(struct device *dev, bool dpu_driver);
557557

558-
bool msm_gpu_no_components(void);
558+
bool msm_seperate_gpu_kms_components(void);
559+
560+
int msm_mdss_count_masters(void);
559561

560562
#endif /* __MSM_DRV_H__ */

drivers/gpu/drm/msm/msm_mdss.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,21 @@ static int msm_mdss_parse_data_bus_icc_path(struct device *dev,
7373
return 0;
7474
}
7575

76+
static const struct of_device_id mdss_dt_match[];
77+
78+
int msm_mdss_count_masters(void)
79+
{
80+
struct device_node *np;
81+
int count = 0;
82+
83+
for_each_matching_node(np, mdss_dt_match) {
84+
if (of_device_is_available(np))
85+
count++;
86+
}
87+
88+
return count;
89+
}
90+
7691
static void msm_mdss_irq(struct irq_desc *desc)
7792
{
7893
struct msm_mdss *msm_mdss = irq_desc_get_handler_data(desc);

0 commit comments

Comments
 (0)