@@ -1538,10 +1538,114 @@ static int dm_hw_fini(void *handle)
1538
1538
return 0 ;
1539
1539
}
1540
1540
1541
+
1542
+ static int dm_enable_vblank (struct drm_crtc * crtc );
1543
+ static void dm_disable_vblank (struct drm_crtc * crtc );
1544
+
1545
+ static void dm_gpureset_toggle_interrupts (struct amdgpu_device * adev ,
1546
+ struct dc_state * state , bool enable )
1547
+ {
1548
+ enum dc_irq_source irq_source ;
1549
+ struct amdgpu_crtc * acrtc ;
1550
+ int rc = - EBUSY ;
1551
+ int i = 0 ;
1552
+
1553
+ for (i = 0 ; i < state -> stream_count ; i ++ ) {
1554
+ acrtc = get_crtc_by_otg_inst (
1555
+ adev , state -> stream_status [i ].primary_otg_inst );
1556
+
1557
+ if (acrtc && state -> stream_status [i ].plane_count != 0 ) {
1558
+ irq_source = IRQ_TYPE_PFLIP + acrtc -> otg_inst ;
1559
+ rc = dc_interrupt_set (adev -> dm .dc , irq_source , enable ) ? 0 : - EBUSY ;
1560
+ DRM_DEBUG ("crtc %d - vupdate irq %sabling: r=%d\n" ,
1561
+ acrtc -> crtc_id , enable ? "en" : "dis" , rc );
1562
+ if (rc )
1563
+ DRM_WARN ("Failed to %s pflip interrupts\n" ,
1564
+ enable ? "enable" : "disable" );
1565
+
1566
+ if (enable ) {
1567
+ rc = dm_enable_vblank (& acrtc -> base );
1568
+ if (rc )
1569
+ DRM_WARN ("Failed to enable vblank interrupts\n" );
1570
+ } else {
1571
+ dm_disable_vblank (& acrtc -> base );
1572
+ }
1573
+
1574
+ }
1575
+ }
1576
+
1577
+ }
1578
+
1579
+ enum dc_status amdgpu_dm_commit_zero_streams (struct dc * dc )
1580
+ {
1581
+ struct dc_state * context = NULL ;
1582
+ enum dc_status res = DC_ERROR_UNEXPECTED ;
1583
+ int i ;
1584
+ struct dc_stream_state * del_streams [MAX_PIPES ];
1585
+ int del_streams_count = 0 ;
1586
+
1587
+ memset (del_streams , 0 , sizeof (del_streams ));
1588
+
1589
+ context = dc_create_state (dc );
1590
+ if (context == NULL )
1591
+ goto context_alloc_fail ;
1592
+
1593
+ dc_resource_state_copy_construct_current (dc , context );
1594
+
1595
+ /* First remove from context all streams */
1596
+ for (i = 0 ; i < context -> stream_count ; i ++ ) {
1597
+ struct dc_stream_state * stream = context -> streams [i ];
1598
+
1599
+ del_streams [del_streams_count ++ ] = stream ;
1600
+ }
1601
+
1602
+ /* Remove all planes for removed streams and then remove the streams */
1603
+ for (i = 0 ; i < del_streams_count ; i ++ ) {
1604
+ if (!dc_rem_all_planes_for_stream (dc , del_streams [i ], context )) {
1605
+ res = DC_FAIL_DETACH_SURFACES ;
1606
+ goto fail ;
1607
+ }
1608
+
1609
+ res = dc_remove_stream_from_ctx (dc , context , del_streams [i ]);
1610
+ if (res != DC_OK )
1611
+ goto fail ;
1612
+ }
1613
+
1614
+
1615
+ res = dc_validate_global_state (dc , context , false);
1616
+
1617
+ if (res != DC_OK ) {
1618
+ DRM_ERROR ("%s:resource validation failed, dc_status:%d\n" , __func__ , res );
1619
+ goto fail ;
1620
+ }
1621
+
1622
+ res = dc_commit_state (dc , context );
1623
+
1624
+ fail :
1625
+ dc_release_state (context );
1626
+
1627
+ context_alloc_fail :
1628
+ return res ;
1629
+ }
1630
+
1541
1631
static int dm_suspend (void * handle )
1542
1632
{
1543
1633
struct amdgpu_device * adev = handle ;
1544
1634
struct amdgpu_display_manager * dm = & adev -> dm ;
1635
+ int ret = 0 ;
1636
+
1637
+ if (adev -> in_gpu_reset ) {
1638
+ mutex_lock (& dm -> dc_lock );
1639
+ dm -> cached_dc_state = dc_copy_state (dm -> dc -> current_state );
1640
+
1641
+ dm_gpureset_toggle_interrupts (adev , dm -> cached_dc_state , false);
1642
+
1643
+ amdgpu_dm_commit_zero_streams (dm -> dc );
1644
+
1645
+ amdgpu_dm_irq_suspend (adev );
1646
+
1647
+ return ret ;
1648
+ }
1545
1649
1546
1650
WARN_ON (adev -> dm .cached_state );
1547
1651
adev -> dm .cached_state = drm_atomic_helper_suspend (adev -> ddev );
@@ -1657,6 +1761,46 @@ static void emulated_link_detect(struct dc_link *link)
1657
1761
1658
1762
}
1659
1763
1764
+ static void dm_gpureset_commit_state (struct dc_state * dc_state ,
1765
+ struct amdgpu_display_manager * dm )
1766
+ {
1767
+ struct {
1768
+ struct dc_surface_update surface_updates [MAX_SURFACES ];
1769
+ struct dc_plane_info plane_infos [MAX_SURFACES ];
1770
+ struct dc_scaling_info scaling_infos [MAX_SURFACES ];
1771
+ struct dc_flip_addrs flip_addrs [MAX_SURFACES ];
1772
+ struct dc_stream_update stream_update ;
1773
+ } * bundle ;
1774
+ int k , m ;
1775
+
1776
+ bundle = kzalloc (sizeof (* bundle ), GFP_KERNEL );
1777
+
1778
+ if (!bundle ) {
1779
+ dm_error ("Failed to allocate update bundle\n" );
1780
+ goto cleanup ;
1781
+ }
1782
+
1783
+ for (k = 0 ; k < dc_state -> stream_count ; k ++ ) {
1784
+ bundle -> stream_update .stream = dc_state -> streams [k ];
1785
+
1786
+ for (m = 0 ; m < dc_state -> stream_status -> plane_count ; m ++ ) {
1787
+ bundle -> surface_updates [m ].surface =
1788
+ dc_state -> stream_status -> plane_states [m ];
1789
+ bundle -> surface_updates [m ].surface -> force_full_update =
1790
+ true;
1791
+ }
1792
+ dc_commit_updates_for_stream (
1793
+ dm -> dc , bundle -> surface_updates ,
1794
+ dc_state -> stream_status -> plane_count ,
1795
+ dc_state -> streams [k ], & bundle -> stream_update , dc_state );
1796
+ }
1797
+
1798
+ cleanup :
1799
+ kfree (bundle );
1800
+
1801
+ return ;
1802
+ }
1803
+
1660
1804
static int dm_resume (void * handle )
1661
1805
{
1662
1806
struct amdgpu_device * adev = handle ;
@@ -1673,8 +1817,44 @@ static int dm_resume(void *handle)
1673
1817
struct dm_plane_state * dm_new_plane_state ;
1674
1818
struct dm_atomic_state * dm_state = to_dm_atomic_state (dm -> atomic_obj .state );
1675
1819
enum dc_connection_type new_connection_type = dc_connection_none ;
1676
- int i , r ;
1820
+ struct dc_state * dc_state ;
1821
+ int i , r , j ;
1822
+
1823
+ if (adev -> in_gpu_reset ) {
1824
+ dc_state = dm -> cached_dc_state ;
1677
1825
1826
+ r = dm_dmub_hw_init (adev );
1827
+ if (r )
1828
+ DRM_ERROR ("DMUB interface failed to initialize: status=%d\n" , r );
1829
+
1830
+ dc_set_power_state (dm -> dc , DC_ACPI_CM_POWER_STATE_D0 );
1831
+ dc_resume (dm -> dc );
1832
+
1833
+ amdgpu_dm_irq_resume_early (adev );
1834
+
1835
+ for (i = 0 ; i < dc_state -> stream_count ; i ++ ) {
1836
+ dc_state -> streams [i ]-> mode_changed = true;
1837
+ for (j = 0 ; j < dc_state -> stream_status -> plane_count ; j ++ ) {
1838
+ dc_state -> stream_status -> plane_states [j ]-> update_flags .raw
1839
+ = 0xffffffff ;
1840
+ }
1841
+ }
1842
+
1843
+ WARN_ON (!dc_commit_state (dm -> dc , dc_state ));
1844
+
1845
+ dm_gpureset_commit_state (dm -> cached_dc_state , dm );
1846
+
1847
+ dm_gpureset_toggle_interrupts (adev , dm -> cached_dc_state , true);
1848
+
1849
+ dc_release_state (dm -> cached_dc_state );
1850
+ dm -> cached_dc_state = NULL ;
1851
+
1852
+ amdgpu_dm_irq_resume_late (adev );
1853
+
1854
+ mutex_unlock (& dm -> dc_lock );
1855
+
1856
+ return 0 ;
1857
+ }
1678
1858
/* Recreate dc_state - DC invalidates it when setting power state to S3. */
1679
1859
dc_release_state (dm_state -> context );
1680
1860
dm_state -> context = dc_create_state (dm -> dc );
0 commit comments