@@ -660,7 +660,6 @@ struct nv50_mstm {
660
660
struct nouveau_encoder * outp ;
661
661
662
662
struct drm_dp_mst_topology_mgr mgr ;
663
- struct nv50_msto * msto [4 ];
664
663
665
664
bool modified ;
666
665
bool disabled ;
@@ -726,7 +725,6 @@ nv50_msto_cleanup(struct nv50_msto *msto)
726
725
drm_dp_mst_deallocate_vcpi (& mstm -> mgr , mstc -> port );
727
726
728
727
msto -> mstc = NULL ;
729
- msto -> head = NULL ;
730
728
msto -> disabled = false;
731
729
}
732
730
@@ -872,7 +870,6 @@ nv50_msto_enable(struct drm_encoder *encoder)
872
870
mstm -> outp -> update (mstm -> outp , head -> base .index , armh , proto ,
873
871
nv50_dp_bpc_to_depth (armh -> or .bpc ));
874
872
875
- msto -> head = head ;
876
873
msto -> mstc = mstc ;
877
874
mstm -> modified = true;
878
875
}
@@ -913,45 +910,40 @@ nv50_msto = {
913
910
.destroy = nv50_msto_destroy ,
914
911
};
915
912
916
- static int
917
- nv50_msto_new (struct drm_device * dev , u32 heads , const char * name , int id ,
918
- struct nv50_msto * * pmsto )
913
+ static struct nv50_msto *
914
+ nv50_msto_new (struct drm_device * dev , struct nv50_head * head , int id )
919
915
{
920
916
struct nv50_msto * msto ;
921
917
int ret ;
922
918
923
- if (!(msto = * pmsto = kzalloc (sizeof (* msto ), GFP_KERNEL )))
924
- return - ENOMEM ;
919
+ msto = kzalloc (sizeof (* msto ), GFP_KERNEL );
920
+ if (!msto )
921
+ return ERR_PTR (- ENOMEM );
925
922
926
923
ret = drm_encoder_init (dev , & msto -> encoder , & nv50_msto ,
927
- DRM_MODE_ENCODER_DPMST , "%s- mst-%d" , name , id );
924
+ DRM_MODE_ENCODER_DPMST , "mst-%d" , id );
928
925
if (ret ) {
929
- kfree (* pmsto );
930
- * pmsto = NULL ;
931
- return ret ;
926
+ kfree (msto );
927
+ return ERR_PTR (ret );
932
928
}
933
929
934
930
drm_encoder_helper_add (& msto -> encoder , & nv50_msto_help );
935
- msto -> encoder .possible_crtcs = heads ;
936
- return 0 ;
931
+ msto -> encoder .possible_crtcs = drm_crtc_mask (& head -> base .base );
932
+ msto -> head = head ;
933
+ return msto ;
937
934
}
938
935
939
936
static struct drm_encoder *
940
937
nv50_mstc_atomic_best_encoder (struct drm_connector * connector ,
941
938
struct drm_connector_state * connector_state )
942
939
{
943
- struct nv50_head * head = nv50_head (connector_state -> crtc );
944
940
struct nv50_mstc * mstc = nv50_mstc (connector );
941
+ struct drm_crtc * crtc = connector_state -> crtc ;
945
942
946
- return & mstc -> mstm -> msto [head -> base .index ]-> encoder ;
947
- }
948
-
949
- static struct drm_encoder *
950
- nv50_mstc_best_encoder (struct drm_connector * connector )
951
- {
952
- struct nv50_mstc * mstc = nv50_mstc (connector );
943
+ if (!(mstc -> mstm -> outp -> dcb -> heads & drm_crtc_mask (crtc )))
944
+ return NULL ;
953
945
954
- return & mstc -> mstm -> msto [ 0 ] -> encoder ;
946
+ return & nv50_head ( crtc ) -> msto -> encoder ;
955
947
}
956
948
957
949
static enum drm_mode_status
@@ -1038,7 +1030,6 @@ static const struct drm_connector_helper_funcs
1038
1030
nv50_mstc_help = {
1039
1031
.get_modes = nv50_mstc_get_modes ,
1040
1032
.mode_valid = nv50_mstc_mode_valid ,
1041
- .best_encoder = nv50_mstc_best_encoder ,
1042
1033
.atomic_best_encoder = nv50_mstc_atomic_best_encoder ,
1043
1034
.atomic_check = nv50_mstc_atomic_check ,
1044
1035
.detect_ctx = nv50_mstc_detect ,
@@ -1071,8 +1062,9 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port,
1071
1062
const char * path , struct nv50_mstc * * pmstc )
1072
1063
{
1073
1064
struct drm_device * dev = mstm -> outp -> base .base .dev ;
1065
+ struct drm_crtc * crtc ;
1074
1066
struct nv50_mstc * mstc ;
1075
- int ret , i ;
1067
+ int ret ;
1076
1068
1077
1069
if (!(mstc = * pmstc = kzalloc (sizeof (* mstc ), GFP_KERNEL )))
1078
1070
return - ENOMEM ;
@@ -1092,8 +1084,13 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port,
1092
1084
mstc -> connector .funcs -> reset (& mstc -> connector );
1093
1085
nouveau_conn_attach_properties (& mstc -> connector );
1094
1086
1095
- for (i = 0 ; i < ARRAY_SIZE (mstm -> msto ) && mstm -> msto [i ]; i ++ )
1096
- drm_connector_attach_encoder (& mstc -> connector , & mstm -> msto [i ]-> encoder );
1087
+ drm_for_each_crtc (crtc , dev ) {
1088
+ if (!(mstm -> outp -> dcb -> heads & drm_crtc_mask (crtc )))
1089
+ continue ;
1090
+
1091
+ drm_connector_attach_encoder (& mstc -> connector ,
1092
+ & nv50_head (crtc )-> msto -> encoder );
1093
+ }
1097
1094
1098
1095
drm_object_attach_property (& mstc -> connector .base , dev -> mode_config .path_property , 0 );
1099
1096
drm_object_attach_property (& mstc -> connector .base , dev -> mode_config .tile_property , 0 );
@@ -1367,7 +1364,7 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
1367
1364
const int max_payloads = hweight8 (outp -> dcb -> heads );
1368
1365
struct drm_device * dev = outp -> base .base .dev ;
1369
1366
struct nv50_mstm * mstm ;
1370
- int ret , i ;
1367
+ int ret ;
1371
1368
u8 dpcd ;
1372
1369
1373
1370
/* This is a workaround for some monitors not functioning
@@ -1390,13 +1387,6 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
1390
1387
if (ret )
1391
1388
return ret ;
1392
1389
1393
- for (i = 0 ; i < max_payloads ; i ++ ) {
1394
- ret = nv50_msto_new (dev , outp -> dcb -> heads , outp -> base .base .name ,
1395
- i , & mstm -> msto [i ]);
1396
- if (ret )
1397
- return ret ;
1398
- }
1399
-
1400
1390
return 0 ;
1401
1391
}
1402
1392
@@ -1569,17 +1559,24 @@ nv50_sor_func = {
1569
1559
.destroy = nv50_sor_destroy ,
1570
1560
};
1571
1561
1562
+ static bool nv50_has_mst (struct nouveau_drm * drm )
1563
+ {
1564
+ struct nvkm_bios * bios = nvxx_bios (& drm -> client .device );
1565
+ u32 data ;
1566
+ u8 ver , hdr , cnt , len ;
1567
+
1568
+ data = nvbios_dp_table (bios , & ver , & hdr , & cnt , & len );
1569
+ return data && ver >= 0x40 && (nvbios_rd08 (bios , data + 0x08 ) & 0x04 );
1570
+ }
1571
+
1572
1572
static int
1573
1573
nv50_sor_create (struct drm_connector * connector , struct dcb_output * dcbe )
1574
1574
{
1575
1575
struct nouveau_connector * nv_connector = nouveau_connector (connector );
1576
1576
struct nouveau_drm * drm = nouveau_drm (connector -> dev );
1577
- struct nvkm_bios * bios = nvxx_bios (& drm -> client .device );
1578
1577
struct nvkm_i2c * i2c = nvxx_i2c (& drm -> client .device );
1579
1578
struct nouveau_encoder * nv_encoder ;
1580
1579
struct drm_encoder * encoder ;
1581
- u8 ver , hdr , cnt , len ;
1582
- u32 data ;
1583
1580
int type , ret ;
1584
1581
1585
1582
switch (dcbe -> type ) {
@@ -1624,10 +1621,9 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
1624
1621
}
1625
1622
1626
1623
if (nv_connector -> type != DCB_CONNECTOR_eDP &&
1627
- (data = nvbios_dp_table (bios , & ver , & hdr , & cnt , & len )) &&
1628
- ver >= 0x40 && (nvbios_rd08 (bios , data + 0x08 ) & 0x04 )) {
1629
- ret = nv50_mstm_new (nv_encoder , & nv_connector -> aux , 16 ,
1630
- nv_connector -> base .base .id ,
1624
+ nv50_has_mst (drm )) {
1625
+ ret = nv50_mstm_new (nv_encoder , & nv_connector -> aux ,
1626
+ 16 , nv_connector -> base .base .id ,
1631
1627
& nv_encoder -> dp .mstm );
1632
1628
if (ret )
1633
1629
return ret ;
@@ -2323,6 +2319,7 @@ nv50_display_create(struct drm_device *dev)
2323
2319
struct nv50_disp * disp ;
2324
2320
struct dcb_output * dcbe ;
2325
2321
int crtcs , ret , i ;
2322
+ bool has_mst = nv50_has_mst (drm );
2326
2323
2327
2324
disp = kzalloc (sizeof (* disp ), GFP_KERNEL );
2328
2325
if (!disp )
@@ -2371,11 +2368,37 @@ nv50_display_create(struct drm_device *dev)
2371
2368
crtcs = 0x3 ;
2372
2369
2373
2370
for (i = 0 ; i < fls (crtcs ); i ++ ) {
2371
+ struct nv50_head * head ;
2372
+
2374
2373
if (!(crtcs & (1 << i )))
2375
2374
continue ;
2376
- ret = nv50_head_create (dev , i );
2377
- if (ret )
2375
+
2376
+ head = nv50_head_create (dev , i );
2377
+ if (IS_ERR (head )) {
2378
+ ret = PTR_ERR (head );
2378
2379
goto out ;
2380
+ }
2381
+
2382
+ if (has_mst ) {
2383
+ head -> msto = nv50_msto_new (dev , head , i );
2384
+ if (IS_ERR (head -> msto )) {
2385
+ ret = PTR_ERR (head -> msto );
2386
+ head -> msto = NULL ;
2387
+ goto out ;
2388
+ }
2389
+
2390
+ /*
2391
+ * FIXME: This is a hack to workaround the following
2392
+ * issues:
2393
+ *
2394
+ * https://gitlab.gnome.org/GNOME/mutter/issues/759
2395
+ * https://gitlab.freedesktop.org/xorg/xserver/merge_requests/277
2396
+ *
2397
+ * Once these issues are closed, this should be
2398
+ * removed
2399
+ */
2400
+ head -> msto -> encoder .possible_crtcs = crtcs ;
2401
+ }
2379
2402
}
2380
2403
2381
2404
/* create encoder/connector objects based on VBIOS DCB table */
0 commit comments