@@ -682,7 +682,7 @@ static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_n
682
682
static int drm_dp_mst_assign_payload_id (struct drm_dp_mst_topology_mgr * mgr ,
683
683
struct drm_dp_vcpi * vcpi )
684
684
{
685
- int ret ;
685
+ int ret , vcpi_ret ;
686
686
687
687
mutex_lock (& mgr -> payload_lock );
688
688
ret = find_first_zero_bit (& mgr -> payload_mask , mgr -> max_payloads + 1 );
@@ -692,24 +692,40 @@ static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
692
692
goto out_unlock ;
693
693
}
694
694
695
+ vcpi_ret = find_first_zero_bit (& mgr -> vcpi_mask , mgr -> max_payloads + 1 );
696
+ if (vcpi_ret > mgr -> max_payloads ) {
697
+ ret = - EINVAL ;
698
+ DRM_DEBUG_KMS ("out of vcpi ids %d\n" , ret );
699
+ goto out_unlock ;
700
+ }
701
+
695
702
set_bit (ret , & mgr -> payload_mask );
696
- vcpi -> vcpi = ret ;
703
+ set_bit (vcpi_ret , & mgr -> vcpi_mask );
704
+ vcpi -> vcpi = vcpi_ret + 1 ;
697
705
mgr -> proposed_vcpis [ret - 1 ] = vcpi ;
698
706
out_unlock :
699
707
mutex_unlock (& mgr -> payload_lock );
700
708
return ret ;
701
709
}
702
710
703
711
static void drm_dp_mst_put_payload_id (struct drm_dp_mst_topology_mgr * mgr ,
704
- int id )
712
+ int vcpi )
705
713
{
706
- if (id == 0 )
714
+ int i ;
715
+ if (vcpi == 0 )
707
716
return ;
708
717
709
718
mutex_lock (& mgr -> payload_lock );
710
- DRM_DEBUG_KMS ("putting payload %d\n" , id );
711
- clear_bit (id , & mgr -> payload_mask );
712
- mgr -> proposed_vcpis [id - 1 ] = NULL ;
719
+ DRM_DEBUG_KMS ("putting payload %d\n" , vcpi );
720
+ clear_bit (vcpi - 1 , & mgr -> vcpi_mask );
721
+
722
+ for (i = 0 ; i < mgr -> max_payloads ; i ++ ) {
723
+ if (mgr -> proposed_vcpis [i ])
724
+ if (mgr -> proposed_vcpis [i ]-> vcpi == vcpi ) {
725
+ mgr -> proposed_vcpis [i ] = NULL ;
726
+ clear_bit (i + 1 , & mgr -> payload_mask );
727
+ }
728
+ }
713
729
mutex_unlock (& mgr -> payload_lock );
714
730
}
715
731
@@ -1563,7 +1579,7 @@ static int drm_dp_destroy_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
1563
1579
}
1564
1580
1565
1581
drm_dp_dpcd_write_payload (mgr , id , payload );
1566
- payload -> payload_state = 0 ;
1582
+ payload -> payload_state = DP_PAYLOAD_DELETE_LOCAL ;
1567
1583
return 0 ;
1568
1584
}
1569
1585
@@ -1590,7 +1606,7 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
1590
1606
*/
1591
1607
int drm_dp_update_payload_part1 (struct drm_dp_mst_topology_mgr * mgr )
1592
1608
{
1593
- int i ;
1609
+ int i , j ;
1594
1610
int cur_slots = 1 ;
1595
1611
struct drm_dp_payload req_payload ;
1596
1612
struct drm_dp_mst_port * port ;
@@ -1607,26 +1623,46 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
1607
1623
port = NULL ;
1608
1624
req_payload .num_slots = 0 ;
1609
1625
}
1626
+
1627
+ if (mgr -> payloads [i ].start_slot != req_payload .start_slot ) {
1628
+ mgr -> payloads [i ].start_slot = req_payload .start_slot ;
1629
+ }
1610
1630
/* work out what is required to happen with this payload */
1611
- if (mgr -> payloads [i ].start_slot != req_payload .start_slot ||
1612
- mgr -> payloads [i ].num_slots != req_payload .num_slots ) {
1631
+ if (mgr -> payloads [i ].num_slots != req_payload .num_slots ) {
1613
1632
1614
1633
/* need to push an update for this payload */
1615
1634
if (req_payload .num_slots ) {
1616
- drm_dp_create_payload_step1 (mgr , i + 1 , & req_payload );
1635
+ drm_dp_create_payload_step1 (mgr , mgr -> proposed_vcpis [ i ] -> vcpi , & req_payload );
1617
1636
mgr -> payloads [i ].num_slots = req_payload .num_slots ;
1618
1637
} else if (mgr -> payloads [i ].num_slots ) {
1619
1638
mgr -> payloads [i ].num_slots = 0 ;
1620
- drm_dp_destroy_payload_step1 (mgr , port , i + 1 , & mgr -> payloads [i ]);
1639
+ drm_dp_destroy_payload_step1 (mgr , port , port -> vcpi . vcpi , & mgr -> payloads [i ]);
1621
1640
req_payload .payload_state = mgr -> payloads [i ].payload_state ;
1622
- } else
1623
- req_payload .payload_state = 0 ;
1624
-
1625
- mgr -> payloads [i ].start_slot = req_payload .start_slot ;
1641
+ mgr -> payloads [i ].start_slot = 0 ;
1642
+ }
1626
1643
mgr -> payloads [i ].payload_state = req_payload .payload_state ;
1627
1644
}
1628
1645
cur_slots += req_payload .num_slots ;
1629
1646
}
1647
+
1648
+ for (i = 0 ; i < mgr -> max_payloads ; i ++ ) {
1649
+ if (mgr -> payloads [i ].payload_state == DP_PAYLOAD_DELETE_LOCAL ) {
1650
+ DRM_DEBUG_KMS ("removing payload %d\n" , i );
1651
+ for (j = i ; j < mgr -> max_payloads - 1 ; j ++ ) {
1652
+ memcpy (& mgr -> payloads [j ], & mgr -> payloads [j + 1 ], sizeof (struct drm_dp_payload ));
1653
+ mgr -> proposed_vcpis [j ] = mgr -> proposed_vcpis [j + 1 ];
1654
+ if (mgr -> proposed_vcpis [j ] && mgr -> proposed_vcpis [j ]-> num_slots ) {
1655
+ set_bit (j + 1 , & mgr -> payload_mask );
1656
+ } else {
1657
+ clear_bit (j + 1 , & mgr -> payload_mask );
1658
+ }
1659
+ }
1660
+ memset (& mgr -> payloads [mgr -> max_payloads - 1 ], 0 , sizeof (struct drm_dp_payload ));
1661
+ mgr -> proposed_vcpis [mgr -> max_payloads - 1 ] = NULL ;
1662
+ clear_bit (mgr -> max_payloads , & mgr -> payload_mask );
1663
+
1664
+ }
1665
+ }
1630
1666
mutex_unlock (& mgr -> payload_lock );
1631
1667
1632
1668
return 0 ;
@@ -1657,9 +1693,9 @@ int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr)
1657
1693
1658
1694
DRM_DEBUG_KMS ("payload %d %d\n" , i , mgr -> payloads [i ].payload_state );
1659
1695
if (mgr -> payloads [i ].payload_state == DP_PAYLOAD_LOCAL ) {
1660
- ret = drm_dp_create_payload_step2 (mgr , port , i + 1 , & mgr -> payloads [i ]);
1696
+ ret = drm_dp_create_payload_step2 (mgr , port , mgr -> proposed_vcpis [ i ] -> vcpi , & mgr -> payloads [i ]);
1661
1697
} else if (mgr -> payloads [i ].payload_state == DP_PAYLOAD_DELETE_LOCAL ) {
1662
- ret = drm_dp_destroy_payload_step2 (mgr , i + 1 , & mgr -> payloads [i ]);
1698
+ ret = drm_dp_destroy_payload_step2 (mgr , mgr -> proposed_vcpis [ i ] -> vcpi , & mgr -> payloads [i ]);
1663
1699
}
1664
1700
if (ret ) {
1665
1701
mutex_unlock (& mgr -> payload_lock );
@@ -1861,6 +1897,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
1861
1897
memset (mgr -> payloads , 0 , mgr -> max_payloads * sizeof (struct drm_dp_payload ));
1862
1898
mgr -> payload_mask = 0 ;
1863
1899
set_bit (0 , & mgr -> payload_mask );
1900
+ mgr -> vcpi_mask = 0 ;
1864
1901
}
1865
1902
1866
1903
out_unlock :
@@ -2475,7 +2512,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
2475
2512
mutex_unlock (& mgr -> lock );
2476
2513
2477
2514
mutex_lock (& mgr -> payload_lock );
2478
- seq_printf (m , "vcpi: %lx\n" , mgr -> payload_mask );
2515
+ seq_printf (m , "vcpi: %lx %lx \n" , mgr -> payload_mask , mgr -> vcpi_mask );
2479
2516
2480
2517
for (i = 0 ; i < mgr -> max_payloads ; i ++ ) {
2481
2518
if (mgr -> proposed_vcpis [i ]) {
0 commit comments