From 44debe7a123cc760fc90ccbe253210798c917fa7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 30 Mar 2016 11:26:35 +0200 Subject: vgacon: dummy implementation for vgacon_text_force MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows us to ditch a ton of ugly #ifdefs from a bunch of drm modeset drivers. v2: Make the dummy function actually return a sane value, spotted by Ville. v3: Because the patch is still in limbo there's no more drivers to convert, noticed by Emil. v4: Rebase once more, because hooray. I'll just go ahead an apply this one later on to drm-misc. Cc: Emil Velikov Cc: Ville Syrjälä Cc: Andrew Morton Cc: Greg Kroah-Hartman Reviewed-by: Emil Velikov Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/radeon/radeon_drv.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index cad25557650f..ad136fc081c8 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -558,12 +558,10 @@ static struct pci_driver radeon_kms_pci_driver = { static int __init radeon_init(void) { -#ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force() && radeon_modeset == -1) { DRM_INFO("VGACON disable radeon kernel modesetting.\n"); radeon_modeset = 0; } -#endif /* set to modesetting by default if not nomodeset */ if (radeon_modeset == -1) radeon_modeset = 1; -- cgit From eba92811f5c7ad9fadf40f021c1b85ad0de3bcc4 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Thu, 14 Apr 2016 10:48:19 -0700 Subject: drm/radeon: use drm_crtc_send_vblank_event() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the legacy drm_send_vblank_event() with the new helper function. Signed-off-by: Gustavo Padovan Reviewed-by: Michel Dänzer Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1460656118-16766-8-git-send-email-gustavo@padovan.org --- drivers/gpu/drm/radeon/radeon_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index fcc7483d3f7b..d596c83ce6aa 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -377,7 +377,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) /* wakeup userspace */ if (work->event) - drm_send_vblank_event(rdev->ddev, crtc_id, work->event); + drm_crtc_send_vblank_event(&radeon_crtc->base, work->event); spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); -- cgit From c91f93683b4eeb5bd2488947c6c581c8cf638650 Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:26 +0100 Subject: drm/radeon: consolidate r600 uvd initialization and startup code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This match the exact same control flow as existing code. It just use goto instead of multiple levels of if/else. It also clarify early initialization failures by clearing rdev->has_uvd doing so does not change end result from hardware point of view, it only avoids printing more error messages down the line and thus only the original error is reported. Acked-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/r600.c | 99 ++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 29 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index f86ab695ee8f..24fa982522ee 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -3035,6 +3035,73 @@ void r600_clear_surface_reg(struct radeon_device *rdev, int reg) /* FIXME: implement */ } +static void r600_uvd_init(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = radeon_uvd_init(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD (%d) init.\n", r); + /* + * At this point rdev->uvd.vcpu_bo is NULL which trickles down + * to early fails uvd_v1_0_resume() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable uvd here. + */ + rdev->has_uvd = 0; + return; + } + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); +} + +static void r600_uvd_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = uvd_v1_0_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; +} + +static void r600_uvd_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) + return; + + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); + if (r) { + dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); + return; + } + r = uvd_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); + return; + } +} + static int r600_startup(struct radeon_device *rdev) { struct radeon_ring *ring; @@ -3070,17 +3137,7 @@ static int r600_startup(struct radeon_device *rdev) return r; } - if (rdev->has_uvd) { - r = uvd_v1_0_resume(rdev); - if (!r) { - r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); - } - } - if (r) - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; - } + r600_uvd_start(rdev); /* Enable IRQ */ if (!rdev->irq.installed) { @@ -3110,17 +3167,7 @@ static int r600_startup(struct radeon_device *rdev) if (r) return r; - if (rdev->has_uvd) { - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - if (ring->ring_size) { - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - RADEON_CP_PACKET2); - if (!r) - r = uvd_v1_0_init(rdev); - if (r) - DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); - } - } + r600_uvd_resume(rdev); r = radeon_ib_pool_init(rdev); if (r) { @@ -3264,13 +3311,7 @@ int r600_init(struct radeon_device *rdev) rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); - if (rdev->has_uvd) { - r = radeon_uvd_init(rdev); - if (!r) { - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; - r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); - } - } + r600_uvd_init(rdev); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); -- cgit From 66ecfcec6b65f3dccaa249ac2a8c0e8673effa05 Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:27 +0100 Subject: drm/radeon: consolidate rv770 uvd initialization and startup code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This match the exact same control flow as existing code. It just use goto instead of multiple levels of if/else. It also clarify early initialization failures by clearing rdev->has_uvd doing so does not change end result from hardware point of view, it only avoids printing more error messages down the line and thus only the original error is reported. Acked-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/rv770.c | 102 ++++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 28 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 01ee96acb398..fa0b03c48227 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1681,6 +1681,73 @@ static int rv770_mc_init(struct radeon_device *rdev) return 0; } +static void rv770_uvd_init(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = radeon_uvd_init(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD (%d) init.\n", r); + /* + * At this point rdev->uvd.vcpu_bo is NULL which trickles down + * to early fails uvd_v2_2_resume() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable uvd here. + */ + rdev->has_uvd = 0; + return; + } + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); +} + +static void rv770_uvd_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = uvd_v2_2_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; +} + +static void rv770_uvd_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) + return; + + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); + if (r) { + dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); + return; + } + r = uvd_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); + return; + } +} + static int rv770_startup(struct radeon_device *rdev) { struct radeon_ring *ring; @@ -1723,16 +1790,7 @@ static int rv770_startup(struct radeon_device *rdev) return r; } - r = uvd_v2_2_resume(rdev); - if (!r) { - r = radeon_fence_driver_start_ring(rdev, - R600_RING_TYPE_UVD_INDEX); - if (r) - dev_err(rdev->dev, "UVD fences init error (%d).\n", r); - } - - if (r) - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; + rv770_uvd_start(rdev); /* Enable IRQ */ if (!rdev->irq.installed) { @@ -1772,16 +1830,7 @@ static int rv770_startup(struct radeon_device *rdev) if (r) return r; - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - if (ring->ring_size) { - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - RADEON_CP_PACKET2); - if (!r) - r = uvd_v1_0_init(rdev); - - if (r) - DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); - } + rv770_uvd_resume(rdev); r = radeon_ib_pool_init(rdev); if (r) { @@ -1831,8 +1880,10 @@ int rv770_suspend(struct radeon_device *rdev) { radeon_pm_suspend(rdev); radeon_audio_fini(rdev); - uvd_v1_0_fini(rdev); - radeon_uvd_suspend(rdev); + if (rdev->has_uvd) { + uvd_v1_0_fini(rdev); + radeon_uvd_suspend(rdev); + } r700_cp_stop(rdev); r600_dma_stop(rdev); r600_irq_suspend(rdev); @@ -1917,12 +1968,7 @@ int rv770_init(struct radeon_device *rdev) rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024); - r = radeon_uvd_init(rdev); - if (!r) { - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; - r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], - 4096); - } + rv770_uvd_init(rdev); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); -- cgit From d78d6f3978ef5f8c365627e2ca2e87583cb74f1e Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:28 +0100 Subject: drm/radeon: consolidate evergreen uvd initialization and startup code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This match the exact same control flow as existing code. It just use goto instead of multiple levels of if/else. It also clarify early initialization failures by clearing rdev->has_uvd doing so does not change end result from hardware point of view, it only avoids printing more error messages down the line and thus only the original error is reported. Acked-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen.c | 102 +++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 28 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 76c4bdf21b20..cc0cf9addf65 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -5363,6 +5363,73 @@ restart_ih: return IRQ_HANDLED; } +static void evergreen_uvd_init(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = radeon_uvd_init(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD (%d) init.\n", r); + /* + * At this point rdev->uvd.vcpu_bo is NULL which trickles down + * to early fails uvd_v2_2_resume() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable uvd here. + */ + rdev->has_uvd = 0; + return; + } + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); +} + +static void evergreen_uvd_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = uvd_v2_2_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; +} + +static void evergreen_uvd_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) + return; + + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); + if (r) { + dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); + return; + } + r = uvd_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); + return; + } +} + static int evergreen_startup(struct radeon_device *rdev) { struct radeon_ring *ring; @@ -5427,16 +5494,7 @@ static int evergreen_startup(struct radeon_device *rdev) return r; } - r = uvd_v2_2_resume(rdev); - if (!r) { - r = radeon_fence_driver_start_ring(rdev, - R600_RING_TYPE_UVD_INDEX); - if (r) - dev_err(rdev->dev, "UVD fences init error (%d).\n", r); - } - - if (r) - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; + evergreen_uvd_start(rdev); /* Enable IRQ */ if (!rdev->irq.installed) { @@ -5475,16 +5533,7 @@ static int evergreen_startup(struct radeon_device *rdev) if (r) return r; - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - if (ring->ring_size) { - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - RADEON_CP_PACKET2); - if (!r) - r = uvd_v1_0_init(rdev); - - if (r) - DRM_ERROR("radeon: error initializing UVD (%d).\n", r); - } + evergreen_uvd_resume(rdev); r = radeon_ib_pool_init(rdev); if (r) { @@ -5539,8 +5588,10 @@ int evergreen_suspend(struct radeon_device *rdev) { radeon_pm_suspend(rdev); radeon_audio_fini(rdev); - uvd_v1_0_fini(rdev); - radeon_uvd_suspend(rdev); + if (rdev->has_uvd) { + uvd_v1_0_fini(rdev); + radeon_uvd_suspend(rdev); + } r700_cp_stop(rdev); r600_dma_stop(rdev); evergreen_irq_suspend(rdev); @@ -5641,12 +5692,7 @@ int evergreen_init(struct radeon_device *rdev) rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024); - r = radeon_uvd_init(rdev); - if (!r) { - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; - r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], - 4096); - } + evergreen_uvd_init(rdev); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); -- cgit From bd42210d4b2006382f54a57eb20a1527f532c516 Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:29 +0100 Subject: drm/radeon: consolidate ni uvd initialization and startup code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This match the exact same control flow as existing code. It just use goto instead of multiple levels of if/else. It also clarify early initialization failures by clearing rdev->has_uvd doing so does not change end result from hardware point of view, it only avoids printing more error messages down the line and thus only the original error is reported. Acked-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ni.c | 100 ++++++++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 26 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index b88d63c9be99..38c39473ebd3 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -2002,6 +2002,73 @@ bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) return radeon_ring_test_lockup(rdev, ring); } +static void cayman_uvd_init(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = radeon_uvd_init(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD (%d) init.\n", r); + /* + * At this point rdev->uvd.vcpu_bo is NULL which trickles down + * to early fails uvd_v2_2_resume() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable uvd here. + */ + rdev->has_uvd = 0; + return; + } + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); +} + +static void cayman_uvd_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = uvd_v2_2_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; +} + +static void cayman_uvd_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) + return; + + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); + if (r) { + dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); + return; + } + r = uvd_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); + return; + } +} + static int cayman_startup(struct radeon_device *rdev) { struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; @@ -2056,15 +2123,7 @@ static int cayman_startup(struct radeon_device *rdev) return r; } - r = uvd_v2_2_resume(rdev); - if (!r) { - r = radeon_fence_driver_start_ring(rdev, - R600_RING_TYPE_UVD_INDEX); - if (r) - dev_err(rdev->dev, "UVD fences init error (%d).\n", r); - } - if (r) - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; + cayman_uvd_start(rdev); if (rdev->family == CHIP_ARUBA) { r = radeon_vce_resume(rdev); @@ -2152,15 +2211,7 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - if (ring->ring_size) { - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - RADEON_CP_PACKET2); - if (!r) - r = uvd_v1_0_init(rdev); - if (r) - DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); - } + cayman_uvd_resume(rdev); if (rdev->family == CHIP_ARUBA) { ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; @@ -2230,8 +2281,10 @@ int cayman_suspend(struct radeon_device *rdev) radeon_vm_manager_fini(rdev); cayman_cp_enable(rdev, false); cayman_dma_stop(rdev); - uvd_v1_0_fini(rdev); - radeon_uvd_suspend(rdev); + if (rdev->has_uvd) { + uvd_v1_0_fini(rdev); + radeon_uvd_suspend(rdev); + } evergreen_irq_suspend(rdev); radeon_wb_disable(rdev); cayman_pcie_gart_disable(rdev); @@ -2325,12 +2378,7 @@ int cayman_init(struct radeon_device *rdev) ring->ring_obj = NULL; r600_ring_init(rdev, ring, 64 * 1024); - r = radeon_uvd_init(rdev); - if (!r) { - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - } + cayman_uvd_init(rdev); if (rdev->family == CHIP_ARUBA) { r = radeon_vce_init(rdev); -- cgit From fa25c22e8fd52dbf97552ab4cdfe30206d9948dd Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:30 +0100 Subject: drm/radeon: consolidate si uvd initialization and startup code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This match the exact same control flow as existing code. It just use goto instead of multiple levels of if/else. It also clarify early initialization failures by clearing rdev->has_uvd doing so does not change end result from hardware point of view, it only avoids printing more error messages down the line and thus only the original error is reported. Acked-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/si.c | 100 +++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index ae21550fe767..6804e7ea3bb5 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -6821,6 +6821,73 @@ restart_ih: /* * startup/shutdown callbacks */ +static void si_uvd_init(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = radeon_uvd_init(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD (%d) init.\n", r); + /* + * At this point rdev->uvd.vcpu_bo is NULL which trickles down + * to early fails uvd_v2_2_resume() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable uvd here. + */ + rdev->has_uvd = 0; + return; + } + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); +} + +static void si_uvd_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = uvd_v2_2_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; +} + +static void si_uvd_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) + return; + + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); + if (r) { + dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); + return; + } + r = uvd_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); + return; + } +} + static int si_startup(struct radeon_device *rdev) { struct radeon_ring *ring; @@ -6899,17 +6966,7 @@ static int si_startup(struct radeon_device *rdev) return r; } - if (rdev->has_uvd) { - r = uvd_v2_2_resume(rdev); - if (!r) { - r = radeon_fence_driver_start_ring(rdev, - R600_RING_TYPE_UVD_INDEX); - if (r) - dev_err(rdev->dev, "UVD fences init error (%d).\n", r); - } - if (r) - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; - } + si_uvd_start(rdev); r = radeon_vce_resume(rdev); if (!r) { @@ -6983,17 +7040,7 @@ static int si_startup(struct radeon_device *rdev) if (r) return r; - if (rdev->has_uvd) { - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - if (ring->ring_size) { - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - RADEON_CP_PACKET2); - if (!r) - r = uvd_v1_0_init(rdev); - if (r) - DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); - } - } + si_uvd_resume(rdev); r = -ENOENT; @@ -7169,14 +7216,7 @@ int si_init(struct radeon_device *rdev) ring->ring_obj = NULL; r600_ring_init(rdev, ring, 64 * 1024); - if (rdev->has_uvd) { - r = radeon_uvd_init(rdev); - if (!r) { - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - } - } + si_uvd_init(rdev); r = radeon_vce_init(rdev); if (!r) { -- cgit From bc48a15a550d32376f7f42b81901588d09bed7af Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:31 +0100 Subject: drm/radeon: consolidate cik uvd initialization and startup code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This match the exact same control flow as existing code. It just use goto instead of multiple levels of if/else. It also clarify early initialization failures by clearing rdev->has_uvd doing so does not change end result from hardware point of view, it only avoids printing more error messages down the line and thus only the original error is reported. Acked-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 108 +++++++++++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 29 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 8ac82df2efde..2307e218914b 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -8137,6 +8137,78 @@ restart_ih: /* * startup/shutdown callbacks */ +static void cik_uvd_init(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = radeon_uvd_init(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD (%d) init.\n", r); + /* + * At this point rdev->uvd.vcpu_bo is NULL which trickles down + * to early fails cik_uvd_start() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable uvd here. + */ + rdev->has_uvd = 0; + return; + } + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); +} + +static void cik_uvd_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = radeon_uvd_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD resume (%d).\n", r); + goto error; + } + r = uvd_v4_2_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD 4.2 resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; +} + +static void cik_uvd_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) + return; + + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); + if (r) { + dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); + return; + } + r = uvd_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); + return; + } +} + /** * cik_startup - program the asic to a functional state * @@ -8239,18 +8311,7 @@ static int cik_startup(struct radeon_device *rdev) return r; } - r = radeon_uvd_resume(rdev); - if (!r) { - r = uvd_v4_2_resume(rdev); - if (!r) { - r = radeon_fence_driver_start_ring(rdev, - R600_RING_TYPE_UVD_INDEX); - if (r) - dev_err(rdev->dev, "UVD fences init error (%d).\n", r); - } - } - if (r) - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; + cik_uvd_start(rdev); r = radeon_vce_resume(rdev); if (!r) { @@ -8342,15 +8403,7 @@ static int cik_startup(struct radeon_device *rdev) if (r) return r; - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - if (ring->ring_size) { - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - RADEON_CP_PACKET2); - if (!r) - r = uvd_v1_0_init(rdev); - if (r) - DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); - } + cik_uvd_resume(rdev); r = -ENOENT; @@ -8443,8 +8496,10 @@ int cik_suspend(struct radeon_device *rdev) radeon_vm_manager_fini(rdev); cik_cp_enable(rdev, false); cik_sdma_enable(rdev, false); - uvd_v1_0_fini(rdev); - radeon_uvd_suspend(rdev); + if (rdev->has_uvd) { + uvd_v1_0_fini(rdev); + radeon_uvd_suspend(rdev); + } radeon_vce_suspend(rdev); cik_fini_pg(rdev); cik_fini_cg(rdev); @@ -8571,12 +8626,7 @@ int cik_init(struct radeon_device *rdev) ring->ring_obj = NULL; r600_ring_init(rdev, ring, 256 * 1024); - r = radeon_uvd_init(rdev); - if (!r) { - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - } + cik_uvd_init(rdev); r = radeon_vce_init(rdev); if (!r) { -- cgit From e3ebfcfa84fa895bb2d583189c239dc9afc9e0d1 Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:32 +0100 Subject: drm/radeon: add a vce flag to know if need to initialize vce or not. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will later on serve for module option to disable vce. Reviewed-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_asic.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 007be29a0020..8ac3e072dcd8 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -2423,6 +2423,7 @@ struct radeon_device { int num_crtc; /* number of crtcs */ struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ bool has_uvd; + bool has_vce; struct r600_audio audio; /* audio stuff */ struct notifier_block acpi_nb; /* only one userspace can use Hyperz features or CMASK at a time */ diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 7d5a36dd5094..46a4ced338a4 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2324,6 +2324,7 @@ int radeon_asic_init(struct radeon_device *rdev) rdev->num_crtc = 2; rdev->has_uvd = false; + rdev->has_vce = false; switch (rdev->family) { case CHIP_R100: @@ -2454,6 +2455,7 @@ int radeon_asic_init(struct radeon_device *rdev) /* set num crtcs */ rdev->num_crtc = 4; rdev->has_uvd = true; + rdev->has_vce = true; rdev->cg_flags = RADEON_CG_SUPPORT_VCE_MGCG; break; @@ -2470,10 +2472,13 @@ int radeon_asic_init(struct radeon_device *rdev) rdev->num_crtc = 2; else rdev->num_crtc = 6; - if (rdev->family == CHIP_HAINAN) + if (rdev->family == CHIP_HAINAN) { rdev->has_uvd = false; - else + rdev->has_vce = false; + } else { rdev->has_uvd = true; + rdev->has_vce = true; + } switch (rdev->family) { case CHIP_TAHITI: rdev->cg_flags = @@ -2578,6 +2583,7 @@ int radeon_asic_init(struct radeon_device *rdev) rdev->asic = &ci_asic; rdev->num_crtc = 6; rdev->has_uvd = true; + rdev->has_vce = true; if (rdev->family == CHIP_BONAIRE) { rdev->cg_flags = RADEON_CG_SUPPORT_GFX_MGCG | @@ -2678,6 +2684,7 @@ int radeon_asic_init(struct radeon_device *rdev) RADEON_PG_SUPPORT_SAMU;*/ } rdev->has_uvd = true; + rdev->has_vce = true; break; default: /* FIXME: not supported yet */ -- cgit From 6c0b1204f34fdc897502c97d03c1a4dfabeb7fdf Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:33 +0100 Subject: drm/radeon: consolidate ni vce initialization and startup code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This match the exact same control flow as existing code. It just use goto instead of multiple levels of if/else. It also clarify early initialization failures by clearing rdev->has_vce doing so does not change end result from hardware point of view, it only avoids printing more error messages down the line and thus only the original error is reported. Acked-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ni.c | 139 +++++++++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 48 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 38c39473ebd3..ec0aac8d455f 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -2069,6 +2069,93 @@ static void cayman_uvd_resume(struct radeon_device *rdev) } } +static void cayman_vce_init(struct radeon_device *rdev) +{ + int r; + + /* Only set for CHIP_ARUBA */ + if (!rdev->has_vce) + return; + + r = radeon_vce_init(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE (%d) init.\n", r); + /* + * At this point rdev->vce.vcpu_bo is NULL which trickles down + * to early fails cayman_vce_start() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable vce here. + */ + rdev->has_vce = 0; + return; + } + rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096); + rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096); +} + +static void cayman_vce_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_vce) + return; + + r = radeon_vce_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE resume (%d).\n", r); + goto error; + } + r = vce_v1_0_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; + rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; +} + +static void cayman_vce_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size) + return; + + ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); + return; + } + ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); + return; + } + r = vce_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing VCE (%d).\n", r); + return; + } +} + static int cayman_startup(struct radeon_device *rdev) { struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; @@ -2124,25 +2211,7 @@ static int cayman_startup(struct radeon_device *rdev) } cayman_uvd_start(rdev); - - if (rdev->family == CHIP_ARUBA) { - r = radeon_vce_resume(rdev); - if (!r) - r = vce_v1_0_resume(rdev); - - if (!r) - r = radeon_fence_driver_start_ring(rdev, - TN_RING_TYPE_VCE1_INDEX); - if (!r) - r = radeon_fence_driver_start_ring(rdev, - TN_RING_TYPE_VCE2_INDEX); - - if (r) { - dev_err(rdev->dev, "VCE init error (%d).\n", r); - rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; - rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; - } - } + cayman_vce_start(rdev); r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX); if (r) { @@ -2212,21 +2281,7 @@ static int cayman_startup(struct radeon_device *rdev) return r; cayman_uvd_resume(rdev); - - if (rdev->family == CHIP_ARUBA) { - ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; - if (ring->ring_size) - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0); - - ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; - if (ring->ring_size) - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0); - - if (!r) - r = vce_v1_0_init(rdev); - if (r) - DRM_ERROR("radeon: failed initializing VCE (%d).\n", r); - } + cayman_vce_resume(rdev); r = radeon_ib_pool_init(rdev); if (r) { @@ -2379,19 +2434,7 @@ int cayman_init(struct radeon_device *rdev) r600_ring_init(rdev, ring, 64 * 1024); cayman_uvd_init(rdev); - - if (rdev->family == CHIP_ARUBA) { - r = radeon_vce_init(rdev); - if (!r) { - ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - - ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - } - } + cayman_vce_init(rdev); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); @@ -2446,7 +2489,7 @@ void cayman_fini(struct radeon_device *rdev) radeon_irq_kms_fini(rdev); uvd_v1_0_fini(rdev); radeon_uvd_fini(rdev); - if (rdev->family == CHIP_ARUBA) + if (rdev->has_vce) radeon_vce_fini(rdev); cayman_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); -- cgit From d18dd7598fc7f5221e835bccfe3b266a2dc53077 Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:34 +0100 Subject: drm/radeon: consolidate si vce initialization and startup code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This match the exact same control flow as existing code. It just use goto instead of multiple levels of if/else. It also clarify early initialization failures by clearing rdev->has_vce doing so does not change end result from hardware point of view, it only avoids printing more error messages down the line and thus only the original error is reported. Acked-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/si.c | 139 +++++++++++++++++++++++++++++--------------- 1 file changed, 93 insertions(+), 46 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 6804e7ea3bb5..9ef41188b814 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -6888,6 +6888,92 @@ static void si_uvd_resume(struct radeon_device *rdev) } } +static void si_vce_init(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_vce) + return; + + r = radeon_vce_init(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE (%d) init.\n", r); + /* + * At this point rdev->vce.vcpu_bo is NULL which trickles down + * to early fails si_vce_start() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable vce here. + */ + rdev->has_vce = 0; + return; + } + rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096); + rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096); +} + +static void si_vce_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_vce) + return; + + r = radeon_vce_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE resume (%d).\n", r); + goto error; + } + r = vce_v1_0_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; + rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; +} + +static void si_vce_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size) + return; + + ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); + return; + } + ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); + return; + } + r = vce_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing VCE (%d).\n", r); + return; + } +} + static int si_startup(struct radeon_device *rdev) { struct radeon_ring *ring; @@ -6967,22 +7053,7 @@ static int si_startup(struct radeon_device *rdev) } si_uvd_start(rdev); - - r = radeon_vce_resume(rdev); - if (!r) { - r = vce_v1_0_resume(rdev); - if (!r) - r = radeon_fence_driver_start_ring(rdev, - TN_RING_TYPE_VCE1_INDEX); - if (!r) - r = radeon_fence_driver_start_ring(rdev, - TN_RING_TYPE_VCE2_INDEX); - } - if (r) { - dev_err(rdev->dev, "VCE init error (%d).\n", r); - rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; - rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; - } + si_vce_start(rdev); /* Enable IRQ */ if (!rdev->irq.installed) { @@ -7041,23 +7112,7 @@ static int si_startup(struct radeon_device *rdev) return r; si_uvd_resume(rdev); - - r = -ENOENT; - - ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; - if (ring->ring_size) - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - VCE_CMD_NO_OP); - - ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; - if (ring->ring_size) - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - VCE_CMD_NO_OP); - - if (!r) - r = vce_v1_0_init(rdev); - else if (r != -ENOENT) - DRM_ERROR("radeon: failed initializing VCE (%d).\n", r); + si_vce_resume(rdev); r = radeon_ib_pool_init(rdev); if (r) { @@ -7117,8 +7172,9 @@ int si_suspend(struct radeon_device *rdev) if (rdev->has_uvd) { uvd_v1_0_fini(rdev); radeon_uvd_suspend(rdev); - radeon_vce_suspend(rdev); } + if (rdev->has_vce) + radeon_vce_suspend(rdev); si_fini_pg(rdev); si_fini_cg(rdev); si_irq_suspend(rdev); @@ -7217,17 +7273,7 @@ int si_init(struct radeon_device *rdev) r600_ring_init(rdev, ring, 64 * 1024); si_uvd_init(rdev); - - r = radeon_vce_init(rdev); - if (!r) { - ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - - ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - } + si_vce_init(rdev); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); @@ -7280,8 +7326,9 @@ void si_fini(struct radeon_device *rdev) if (rdev->has_uvd) { uvd_v1_0_fini(rdev); radeon_uvd_fini(rdev); - radeon_vce_fini(rdev); } + if (rdev->has_vce) + radeon_vce_fini(rdev); si_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); radeon_gem_fini(rdev); -- cgit From cb25f7e022b0fb1caf1bc50e5f85b3d31043b997 Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:35 +0100 Subject: drm/radeon: consolidate cik vce initialization and startup code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This match the exact same control flow as existing code. It just use goto instead of multiple levels of if/else. It also clarify early initialization failures by clearing rdev->has_vce doing so does not change end result from hardware point of view, it only avoids printing more error messages down the line and thus only the original error is reported. Acked-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 136 +++++++++++++++++++++++++++++-------------- 1 file changed, 91 insertions(+), 45 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 2307e218914b..dd1a7b206a48 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -8209,6 +8209,92 @@ static void cik_uvd_resume(struct radeon_device *rdev) } } +static void cik_vce_init(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_vce) + return; + + r = radeon_vce_init(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE (%d) init.\n", r); + /* + * At this point rdev->vce.vcpu_bo is NULL which trickles down + * to early fails cik_vce_start() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable vce here. + */ + rdev->has_vce = 0; + return; + } + rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096); + rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096); +} + +static void cik_vce_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_vce) + return; + + r = radeon_vce_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE resume (%d).\n", r); + goto error; + } + r = vce_v2_0_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; + rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; +} + +static void cik_vce_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size) + return; + + ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); + return; + } + ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); + return; + } + r = vce_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing VCE (%d).\n", r); + return; + } +} + /** * cik_startup - program the asic to a functional state * @@ -8312,22 +8398,7 @@ static int cik_startup(struct radeon_device *rdev) } cik_uvd_start(rdev); - - r = radeon_vce_resume(rdev); - if (!r) { - r = vce_v2_0_resume(rdev); - if (!r) - r = radeon_fence_driver_start_ring(rdev, - TN_RING_TYPE_VCE1_INDEX); - if (!r) - r = radeon_fence_driver_start_ring(rdev, - TN_RING_TYPE_VCE2_INDEX); - } - if (r) { - dev_err(rdev->dev, "VCE init error (%d).\n", r); - rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; - rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; - } + cik_vce_start(rdev); /* Enable IRQ */ if (!rdev->irq.installed) { @@ -8404,23 +8475,7 @@ static int cik_startup(struct radeon_device *rdev) return r; cik_uvd_resume(rdev); - - r = -ENOENT; - - ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; - if (ring->ring_size) - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - VCE_CMD_NO_OP); - - ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; - if (ring->ring_size) - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - VCE_CMD_NO_OP); - - if (!r) - r = vce_v1_0_init(rdev); - else if (r != -ENOENT) - DRM_ERROR("radeon: failed initializing VCE (%d).\n", r); + cik_vce_resume(rdev); r = radeon_ib_pool_init(rdev); if (r) { @@ -8500,7 +8555,8 @@ int cik_suspend(struct radeon_device *rdev) uvd_v1_0_fini(rdev); radeon_uvd_suspend(rdev); } - radeon_vce_suspend(rdev); + if (rdev->has_vce) + radeon_vce_suspend(rdev); cik_fini_pg(rdev); cik_fini_cg(rdev); cik_irq_suspend(rdev); @@ -8627,17 +8683,7 @@ int cik_init(struct radeon_device *rdev) r600_ring_init(rdev, ring, 256 * 1024); cik_uvd_init(rdev); - - r = radeon_vce_init(rdev); - if (!r) { - ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - - ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - } + cik_vce_init(rdev); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); -- cgit From f1a0a67a8aca257fc6d4a2d1753556a91f2186a7 Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:36 +0100 Subject: drm/radeon: add driver option to disable uvd block. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quite few suspend/hibernation bugs are related to this block. Add an option to disable those as a work around. Reviewed-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_asic.c | 3 +++ drivers/gpu/drm/radeon/radeon_drv.c | 4 ++++ 3 files changed, 8 insertions(+) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 8ac3e072dcd8..1b26ceffed24 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -113,6 +113,7 @@ extern int radeon_bapm; extern int radeon_backlight; extern int radeon_auxch; extern int radeon_mst; +extern int radeon_uvd; /* * Copy from radeon_drv.h so we don't have to include both and have conflicting diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 46a4ced338a4..b4810ef06aee 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2696,6 +2696,9 @@ int radeon_asic_init(struct radeon_device *rdev) rdev->asic->pm.set_memory_clock = NULL; } + if (!radeon_uvd) + rdev->has_uvd = false; + return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 5d44ed0d104a..d637828ae53c 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -196,6 +196,7 @@ int radeon_bapm = -1; int radeon_backlight = -1; int radeon_auxch = -1; int radeon_mst = 0; +int radeon_uvd = 1; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -287,6 +288,9 @@ module_param_named(auxch, radeon_auxch, int, 0444); MODULE_PARM_DESC(mst, "DisplayPort MST experimental support (1 = enable, 0 = disable)"); module_param_named(mst, radeon_mst, int, 0444); +MODULE_PARM_DESC(uvd, "uvd enable/disable uvd support (1 = enable, 0 = disable)"); +module_param_named(uvd, radeon_uvd, int, 0444); + static struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; -- cgit From fabb5935871db1f31fcd2684fd154e24de04d917 Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:37 +0100 Subject: drm/radeon: add driver option to disable vce block. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quite few suspend/hibernation bugs are related to this block. Add an option to disable those as a work around. Reviewed-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_asic.c | 2 ++ drivers/gpu/drm/radeon/radeon_drv.c | 4 ++++ 3 files changed, 7 insertions(+) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 1b26ceffed24..91828ecf39cf 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -114,6 +114,7 @@ extern int radeon_backlight; extern int radeon_auxch; extern int radeon_mst; extern int radeon_uvd; +extern int radeon_vce; /* * Copy from radeon_drv.h so we don't have to include both and have conflicting diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index b4810ef06aee..bc5121d1a7bc 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2698,6 +2698,8 @@ int radeon_asic_init(struct radeon_device *rdev) if (!radeon_uvd) rdev->has_uvd = false; + if (!radeon_vce) + rdev->has_vce = false; return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index d637828ae53c..261462e85d1c 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -197,6 +197,7 @@ int radeon_backlight = -1; int radeon_auxch = -1; int radeon_mst = 0; int radeon_uvd = 1; +int radeon_vce = 1; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -291,6 +292,9 @@ module_param_named(mst, radeon_mst, int, 0444); MODULE_PARM_DESC(uvd, "uvd enable/disable uvd support (1 = enable, 0 = disable)"); module_param_named(uvd, radeon_uvd, int, 0444); +MODULE_PARM_DESC(vce, "vce enable/disable vce support (1 = enable, 0 = disable)"); +module_param_named(vce, radeon_vce, int, 0444); + static struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; -- cgit From 71fe289970430fca85c7c8da5a829e65764e081b Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:38 +0100 Subject: drm/radeon: allow to force hard GPU reset. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases, like when freezing for hibernation, we need to be able to force hard reset even if no engine are stuck. This patch add a bool option to current asic reset callback to allow to force hard reset on asic that supports it. Reviewed-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 8 +++++++- drivers/gpu/drm/radeon/evergreen.c | 7 ++++++- drivers/gpu/drm/radeon/ni.c | 7 ++++++- drivers/gpu/drm/radeon/r100.c | 2 +- drivers/gpu/drm/radeon/r300.c | 2 +- drivers/gpu/drm/radeon/r600.c | 7 ++++++- drivers/gpu/drm/radeon/radeon.h | 4 ++-- drivers/gpu/drm/radeon/radeon_asic.h | 16 ++++++++-------- drivers/gpu/drm/radeon/rs600.c | 2 +- drivers/gpu/drm/radeon/si.c | 7 ++++++- 10 files changed, 44 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index dd1a7b206a48..ba192a35c607 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -5261,15 +5261,21 @@ static void cik_gpu_pci_config_reset(struct radeon_device *rdev) * cik_asic_reset - soft reset GPU * * @rdev: radeon_device pointer + * @hard: force hard reset * * Look up which blocks are hung and attempt * to reset them. * Returns 0 for success. */ -int cik_asic_reset(struct radeon_device *rdev) +int cik_asic_reset(struct radeon_device *rdev, bool hard) { u32 reset_mask; + if (hard) { + cik_gpu_pci_config_reset(rdev); + return 0; + } + reset_mask = cik_gpu_check_soft_reset(rdev); if (reset_mask) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index cc0cf9addf65..e483b0752866 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3984,10 +3984,15 @@ void evergreen_gpu_pci_config_reset(struct radeon_device *rdev) } } -int evergreen_asic_reset(struct radeon_device *rdev) +int evergreen_asic_reset(struct radeon_device *rdev, bool hard) { u32 reset_mask; + if (hard) { + evergreen_gpu_pci_config_reset(rdev); + return 0; + } + reset_mask = evergreen_gpu_check_soft_reset(rdev); if (reset_mask) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index ec0aac8d455f..4a3d7cab83f7 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1959,10 +1959,15 @@ static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) evergreen_print_gpu_status_regs(rdev); } -int cayman_asic_reset(struct radeon_device *rdev) +int cayman_asic_reset(struct radeon_device *rdev, bool hard) { u32 reset_mask; + if (hard) { + evergreen_gpu_pci_config_reset(rdev); + return 0; + } + reset_mask = cayman_gpu_check_soft_reset(rdev); if (reset_mask) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 6e478a248628..bbdf15fc9153 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2555,7 +2555,7 @@ void r100_bm_disable(struct radeon_device *rdev) mdelay(1); } -int r100_asic_reset(struct radeon_device *rdev) +int r100_asic_reset(struct radeon_device *rdev, bool hard) { struct r100_mc_save save; u32 status, tmp; diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 718b12b03b57..7e417d8dc733 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -410,7 +410,7 @@ static void r300_gpu_init(struct radeon_device *rdev) rdev->num_gb_pipes, rdev->num_z_pipes); } -int r300_asic_reset(struct radeon_device *rdev) +int r300_asic_reset(struct radeon_device *rdev, bool hard) { struct r100_mc_save save; u32 status, tmp; diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 24fa982522ee..d7896bb553a9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1871,10 +1871,15 @@ static void r600_gpu_pci_config_reset(struct radeon_device *rdev) } } -int r600_asic_reset(struct radeon_device *rdev) +int r600_asic_reset(struct radeon_device *rdev, bool hard) { u32 reset_mask; + if (hard) { + r600_gpu_pci_config_reset(rdev); + return 0; + } + reset_mask = r600_gpu_check_soft_reset(rdev); if (reset_mask) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 91828ecf39cf..1ededd1a86f5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1854,7 +1854,7 @@ struct radeon_asic { int (*resume)(struct radeon_device *rdev); int (*suspend)(struct radeon_device *rdev); void (*vga_set_state)(struct radeon_device *rdev, bool state); - int (*asic_reset)(struct radeon_device *rdev); + int (*asic_reset)(struct radeon_device *rdev, bool hard); /* Flush the HDP cache via MMIO */ void (*mmio_hdp_flush)(struct radeon_device *rdev); /* check if 3D engine is idle */ @@ -2720,7 +2720,7 @@ static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev)) #define radeon_cs_parse(rdev, r, p) (rdev)->asic->ring[(r)]->cs_parse((p)) #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) -#define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) +#define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev), false) #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) #define radeon_gart_get_page_entry(a, f) (rdev)->asic->gart.get_page_entry((a), (f)) #define radeon_gart_set_page(rdev, i, e) (rdev)->asic->gart.set_page((rdev), (i), (e)) diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index e0aa33262eac..7675dfaaa005 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -64,7 +64,7 @@ int r100_suspend(struct radeon_device *rdev); int r100_resume(struct radeon_device *rdev); void r100_vga_set_state(struct radeon_device *rdev, bool state); bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int r100_asic_reset(struct radeon_device *rdev); +int r100_asic_reset(struct radeon_device *rdev, bool hard); u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); void r100_pci_gart_tlb_flush(struct radeon_device *rdev); uint64_t r100_pci_gart_get_page_entry(uint64_t addr, uint32_t flags); @@ -167,7 +167,7 @@ extern int r300_init(struct radeon_device *rdev); extern void r300_fini(struct radeon_device *rdev); extern int r300_suspend(struct radeon_device *rdev); extern int r300_resume(struct radeon_device *rdev); -extern int r300_asic_reset(struct radeon_device *rdev); +extern int r300_asic_reset(struct radeon_device *rdev, bool hard); extern void r300_ring_start(struct radeon_device *rdev, struct radeon_ring *ring); extern void r300_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence); @@ -225,7 +225,7 @@ extern int rs400_mc_wait_for_idle(struct radeon_device *rdev); /* * rs600. */ -extern int rs600_asic_reset(struct radeon_device *rdev); +extern int rs600_asic_reset(struct radeon_device *rdev, bool hard); extern int rs600_init(struct radeon_device *rdev); extern void rs600_fini(struct radeon_device *rdev); extern int rs600_suspend(struct radeon_device *rdev); @@ -334,7 +334,7 @@ bool r600_dma_semaphore_ring_emit(struct radeon_device *rdev, void r600_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); bool r600_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); bool r600_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int r600_asic_reset(struct radeon_device *rdev); +int r600_asic_reset(struct radeon_device *rdev, bool hard); int r600_set_surface_reg(struct radeon_device *rdev, int reg, uint32_t tiling_flags, uint32_t pitch, uint32_t offset, uint32_t obj_size); @@ -513,7 +513,7 @@ int evergreen_suspend(struct radeon_device *rdev); int evergreen_resume(struct radeon_device *rdev); bool evergreen_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); bool evergreen_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int evergreen_asic_reset(struct radeon_device *rdev); +int evergreen_asic_reset(struct radeon_device *rdev, bool hard); void evergreen_bandwidth_update(struct radeon_device *rdev); void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); void evergreen_hpd_init(struct radeon_device *rdev); @@ -606,7 +606,7 @@ int cayman_init(struct radeon_device *rdev); void cayman_fini(struct radeon_device *rdev); int cayman_suspend(struct radeon_device *rdev); int cayman_resume(struct radeon_device *rdev); -int cayman_asic_reset(struct radeon_device *rdev); +int cayman_asic_reset(struct radeon_device *rdev, bool hard); void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int cayman_vm_init(struct radeon_device *rdev); void cayman_vm_fini(struct radeon_device *rdev); @@ -712,7 +712,7 @@ int si_suspend(struct radeon_device *rdev); int si_resume(struct radeon_device *rdev); bool si_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); bool si_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int si_asic_reset(struct radeon_device *rdev); +int si_asic_reset(struct radeon_device *rdev, bool hard); void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int si_irq_set(struct radeon_device *rdev); int si_irq_process(struct radeon_device *rdev); @@ -817,7 +817,7 @@ void cik_fini(struct radeon_device *rdev); int cik_suspend(struct radeon_device *rdev); int cik_resume(struct radeon_device *rdev); bool cik_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int cik_asic_reset(struct radeon_device *rdev); +int cik_asic_reset(struct radeon_device *rdev, bool hard); void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring); int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 6244f4e44e9a..3c250c445bdb 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -444,7 +444,7 @@ void rs600_hpd_fini(struct radeon_device *rdev) radeon_irq_kms_disable_hpd(rdev, disable); } -int rs600_asic_reset(struct radeon_device *rdev) +int rs600_asic_reset(struct radeon_device *rdev, bool hard) { struct rv515_mc_save save; u32 status, tmp; diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 9ef41188b814..7afe825ee561 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -4034,10 +4034,15 @@ static void si_gpu_pci_config_reset(struct radeon_device *rdev) } } -int si_asic_reset(struct radeon_device *rdev) +int si_asic_reset(struct radeon_device *rdev, bool hard) { u32 reset_mask; + if (hard) { + si_gpu_pci_config_reset(rdev); + return 0; + } + reset_mask = si_gpu_check_soft_reset(rdev); if (reset_mask) -- cgit From 274ad65c9d02bdcbee9bae045517864c3521d530 Mon Sep 17 00:00:00 2001 From: Jérome Glisse Date: Fri, 18 Mar 2016 16:58:39 +0100 Subject: drm/radeon: hard reset r600 and newer GPU when hibernating. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some GPU block like UVD and VCE require hard reset to be properly resume if there is no real powerdown of the asic like during various hibernation step. This patch perform such hard reset. Reviewed-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 3 ++- drivers/gpu/drm/radeon/radeon_device.c | 10 +++++++--- drivers/gpu/drm/radeon/radeon_drv.c | 9 +++++---- 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 1ededd1a86f5..8e403be2f2cf 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -2835,7 +2835,8 @@ extern bool radeon_ttm_tt_is_readonly(struct ttm_tt *ttm); extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); extern int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); -extern int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon); +extern int radeon_suspend_kms(struct drm_device *dev, bool suspend, + bool fbcon, bool freeze); extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); extern void radeon_program_register_sequence(struct radeon_device *rdev, const u32 *registers, diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 4fd1a961012d..fd042a831635 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1236,7 +1236,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero printk(KERN_INFO "radeon: switched off\n"); drm_kms_helper_poll_disable(dev); dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - radeon_suspend_kms(dev, true, true); + radeon_suspend_kms(dev, true, true, false); dev->switch_power_state = DRM_SWITCH_POWER_OFF; } } @@ -1561,7 +1561,8 @@ void radeon_device_fini(struct radeon_device *rdev) * Returns 0 for success or an error on failure. * Called at driver suspend. */ -int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) +int radeon_suspend_kms(struct drm_device *dev, bool suspend, + bool fbcon, bool freeze) { struct radeon_device *rdev; struct drm_crtc *crtc; @@ -1636,7 +1637,10 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) radeon_agp_suspend(rdev); pci_save_state(dev->pdev); - if (suspend) { + if (freeze && rdev->family >= CHIP_R600) { + rdev->asic->asic_reset(rdev, true); + pci_restore_state(dev->pdev); + } else if (suspend) { /* Shut down the device */ pci_disable_device(dev->pdev); pci_set_power_state(dev->pdev, PCI_D3hot); diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 261462e85d1c..d2a925ed2346 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -105,7 +105,8 @@ void radeon_driver_postclose_kms(struct drm_device *dev, struct drm_file *file_priv); void radeon_driver_preclose_kms(struct drm_device *dev, struct drm_file *file_priv); -int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon); +int radeon_suspend_kms(struct drm_device *dev, bool suspend, + bool fbcon, bool freeze); int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); @@ -366,7 +367,7 @@ static int radeon_pmops_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); - return radeon_suspend_kms(drm_dev, true, true); + return radeon_suspend_kms(drm_dev, true, true, false); } static int radeon_pmops_resume(struct device *dev) @@ -380,7 +381,7 @@ static int radeon_pmops_freeze(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); - return radeon_suspend_kms(drm_dev, false, true); + return radeon_suspend_kms(drm_dev, false, true, true); } static int radeon_pmops_thaw(struct device *dev) @@ -405,7 +406,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev) drm_kms_helper_poll_disable(drm_dev); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); - ret = radeon_suspend_kms(drm_dev, false, false); + ret = radeon_suspend_kms(drm_dev, false, false, false); pci_save_state(pdev); pci_disable_device(pdev); pci_ignore_hotplug(pdev); -- cgit From 16fae6502d797a95cd40a21664b5715ecacef599 Mon Sep 17 00:00:00 2001 From: Nils Wallménius Date: Sat, 19 Mar 2016 16:12:12 +0100 Subject: drm/radeon: delete unused struct member suspend from radeon_device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nils Wallménius Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 8e403be2f2cf..4192f60df98a 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -2396,7 +2396,6 @@ struct radeon_device { struct radeon_wb wb; struct radeon_dummy_page dummy_page; bool shutdown; - bool suspend; bool need_dma32; bool accel_working; bool fastfb_working; /* IGP feature*/ -- cgit From b2c0cbd657173f024138d6421774007690ceeffd Mon Sep 17 00:00:00 2001 From: Nicolai Stange Date: Tue, 22 Mar 2016 22:05:27 +0100 Subject: drm/radeon: don't include RADEON_HPD_NONE in HPD IRQ enable bitsets The values of all but the RADEON_HPD_NONE members of the radeon_hpd_id enum transform 1:1 into bit positions within the 'enabled' bitset as assembled by evergreen_hpd_init(): enabled |= 1 << radeon_connector->hpd.hpd; However, if ->hpd.hpd happens to equal RADEON_HPD_NONE == 0xff, UBSAN reports UBSAN: Undefined behaviour in drivers/gpu/drm/radeon/evergreen.c:1867:16 shift exponent 255 is too large for 32-bit type 'int' [...] Call Trace: [] dump_stack+0xbc/0x117 [] ? _atomic_dec_and_lock+0x169/0x169 [] ubsan_epilogue+0xd/0x4e [] __ubsan_handle_shift_out_of_bounds+0x1fb/0x254 [] ? atom_execute_table+0x3e/0x50 [radeon] [] ? __ubsan_handle_load_invalid_value+0x158/0x158 [] ? radeon_get_pll_use_mask+0x130/0x130 [radeon] [] ? wake_up_klogd_work_func+0x60/0x60 [] ? vprintk_default+0x3e/0x60 [] evergreen_hpd_init+0x274/0x2d0 [radeon] [] ? evergreen_hpd_init+0x274/0x2d0 [radeon] [] radeon_modeset_init+0x8ce/0x18d0 [radeon] [] radeon_driver_load_kms+0x186/0x350 [radeon] [] drm_dev_register+0xc6/0x100 [drm] [] drm_get_pci_dev+0xe4/0x490 [drm] [] ? kfree+0x220/0x370 [] radeon_pci_probe+0x112/0x140 [radeon] [...] ===================================================================== radeon 0000:01:00.0: No connectors reported connected with modes At least on x86, there should be no user-visible impact as there 1 << 0xff == 1 << (0xff & 31) == 1 << 31 holds and 31 > RADEON_MAX_HPD_PINS. Thus, this patch is a cosmetic one. All of the above applies analogously to evergreen_hpd_fini(), r100_hpd_init(), r100_hpd_fini(), r600_hpd_init(), r600_hpd_fini(), rs600_hpd_init() and rs600_hpd_fini() Silence UBSAN by checking ->hpd.hpd for RADEON_HPD_NONE before oring it into the 'enabled' bitset in the *_init()- or the 'disabled' bitset in the *_fini()-functions respectively. Signed-off-by: Nicolai Stange Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen.c | 6 ++++-- drivers/gpu/drm/radeon/r100.c | 6 ++++-- drivers/gpu/drm/radeon/r600.c | 6 ++++-- drivers/gpu/drm/radeon/rs600.c | 6 ++++-- 4 files changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e483b0752866..501633be8ea2 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1864,7 +1864,8 @@ void evergreen_hpd_init(struct radeon_device *rdev) break; } radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); - enabled |= 1 << radeon_connector->hpd.hpd; + if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) + enabled |= 1 << radeon_connector->hpd.hpd; } radeon_irq_kms_enable_hpd(rdev, enabled); } @@ -1907,7 +1908,8 @@ void evergreen_hpd_fini(struct radeon_device *rdev) default: break; } - disabled |= 1 << radeon_connector->hpd.hpd; + if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) + disabled |= 1 << radeon_connector->hpd.hpd; } radeon_irq_kms_disable_hpd(rdev, disabled); } diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index bbdf15fc9153..af985b951d00 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -592,7 +592,8 @@ void r100_hpd_init(struct radeon_device *rdev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); - enable |= 1 << radeon_connector->hpd.hpd; + if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) + enable |= 1 << radeon_connector->hpd.hpd; radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); } radeon_irq_kms_enable_hpd(rdev, enable); @@ -614,7 +615,8 @@ void r100_hpd_fini(struct radeon_device *rdev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); - disable |= 1 << radeon_connector->hpd.hpd; + if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) + disable |= 1 << radeon_connector->hpd.hpd; } radeon_irq_kms_disable_hpd(rdev, disable); } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index d7896bb553a9..9247e7d207fe 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1002,7 +1002,8 @@ void r600_hpd_init(struct radeon_device *rdev) break; } } - enable |= 1 << radeon_connector->hpd.hpd; + if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) + enable |= 1 << radeon_connector->hpd.hpd; radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); } radeon_irq_kms_enable_hpd(rdev, enable); @@ -1055,7 +1056,8 @@ void r600_hpd_fini(struct radeon_device *rdev) break; } } - disable |= 1 << radeon_connector->hpd.hpd; + if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) + disable |= 1 << radeon_connector->hpd.hpd; } radeon_irq_kms_disable_hpd(rdev, disable); } diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 3c250c445bdb..0051c4288725 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -413,7 +413,8 @@ void rs600_hpd_init(struct radeon_device *rdev) default: break; } - enable |= 1 << radeon_connector->hpd.hpd; + if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) + enable |= 1 << radeon_connector->hpd.hpd; radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); } radeon_irq_kms_enable_hpd(rdev, enable); @@ -439,7 +440,8 @@ void rs600_hpd_fini(struct radeon_device *rdev) default: break; } - disable |= 1 << radeon_connector->hpd.hpd; + if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) + disable |= 1 << radeon_connector->hpd.hpd; } radeon_irq_kms_disable_hpd(rdev, disable); } -- cgit From 71cbf451eb2715865e3dbd0ec55837dac1148d23 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 26 Apr 2016 19:29:56 +0200 Subject: drm/radeon: Use lockless gem BO free callback No dev->struct_mutex anywhere to be seen. Cc: Alex Deucher Signed-off-by: Daniel Vetter Acked-by: Alex Deucher Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1461691808-12414-24-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/radeon/radeon_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 5d44ed0d104a..b9f74e68527e 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -525,7 +525,7 @@ static struct drm_driver kms_driver = { .irq_uninstall = radeon_driver_irq_uninstall_kms, .irq_handler = radeon_driver_irq_handler_kms, .ioctls = radeon_ioctls_kms, - .gem_free_object = radeon_gem_object_free, + .gem_free_object_unlocked = radeon_gem_object_free, .gem_open_object = radeon_gem_object_open, .gem_close_object = radeon_gem_object_close, .dumb_create = radeon_mode_dumb_create, -- cgit From c63dd758589b1f7e8398841d1f443f06ebfbcefc Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Fri, 1 Apr 2016 18:51:34 +0900 Subject: drm/radeon: Support DRM_MODE_PAGE_FLIP_ASYNC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When this flag is set, we program the hardware to execute the flip during horizontal blank (i.e. for the next scanline) instead of during vertical blank (i.e. for the next frame). Currently this is only supported on ASICs which have a page flip completion interrupt (>= R600), and only if the use_pflipirq parameter has value 2 (the default). Reviewed-by: Christian König Signed-off-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_crtc.c | 24 +++++++++++------------- drivers/gpu/drm/radeon/evergreen.c | 5 ++++- drivers/gpu/drm/radeon/r100.c | 2 +- drivers/gpu/drm/radeon/radeon.h | 5 +++-- drivers/gpu/drm/radeon/radeon_asic.h | 9 +++++---- drivers/gpu/drm/radeon/radeon_display.c | 6 +++++- drivers/gpu/drm/radeon/rs600.c | 4 +++- drivers/gpu/drm/radeon/rv770.c | 4 +++- 8 files changed, 35 insertions(+), 24 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index b80b08f71cb4..bdc7b9ee1930 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1375,6 +1375,11 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, break; } + /* Make sure surface address is updated at vertical blank rather than + * horizontal blank + */ + WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, upper_32_bits(fb_location)); WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, @@ -1427,12 +1432,6 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (viewport_w << 16) | viewport_h); - /* pageflip setup */ - /* make sure flip is at vb rather than hb */ - tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; - WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); - /* set pageflip to happen only at start of vblank interval (front porch) */ WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3); @@ -1466,7 +1465,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, uint64_t fb_location; uint32_t fb_format, fb_pitch_pixels, tiling_flags; u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; - u32 tmp, viewport_w, viewport_h; + u32 viewport_w, viewport_h; int r; bool bypass_lut = false; @@ -1581,6 +1580,11 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, else WREG32(AVIVO_D2VGA_CONTROL, 0); + /* Make sure surface address is update at vertical blank rather than + * horizontal blank + */ + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0); + if (rdev->family >= CHIP_RV770) { if (radeon_crtc->crtc_id) { WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); @@ -1627,12 +1631,6 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (viewport_w << 16) | viewport_h); - /* pageflip setup */ - /* make sure flip is at vb rather than hb */ - tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; - WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); - /* set pageflip to happen only at start of vblank interval (front porch) */ WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 501633be8ea2..9217d202e94d 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1407,11 +1407,14 @@ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) * Triggers the actual pageflip by updating the primary * surface base address (evergreen+). */ -void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) +void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, + bool async) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; /* update the scanout addresses */ + WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, + async ? EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0); WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, upper_32_bits(crtc_base)); WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index af985b951d00..f25994b3afa6 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -153,7 +153,7 @@ void r100_wait_for_vblank(struct radeon_device *rdev, int crtc) * bit to go high, when it does, we release the lock, and allow the * double buffered update to take place. */ -void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) +void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 4192f60df98a..170e69111d1b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -746,6 +746,7 @@ struct radeon_flip_work { struct drm_pending_vblank_event *event; struct radeon_bo *old_rbo; struct fence *fence; + bool async; }; struct r500_irq_stat_regs { @@ -2000,7 +2001,7 @@ struct radeon_asic { } dpm; /* pageflipping */ struct { - void (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base); + void (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base, bool async); bool (*page_flip_pending)(struct radeon_device *rdev, int crtc); } pflip; }; @@ -2777,7 +2778,7 @@ static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) -#define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base)) +#define radeon_page_flip(rdev, crtc, base, async) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base), (async)) #define radeon_page_flip_pending(rdev, crtc) (rdev)->asic->pflip.page_flip_pending((rdev), (crtc)) #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 7675dfaaa005..e3f036c20d64 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -138,7 +138,7 @@ extern void r100_pm_finish(struct radeon_device *rdev); extern void r100_pm_init_profile(struct radeon_device *rdev); extern void r100_pm_get_dynpm_state(struct radeon_device *rdev); extern void r100_page_flip(struct radeon_device *rdev, int crtc, - u64 crtc_base); + u64 crtc_base, bool async); extern bool r100_page_flip_pending(struct radeon_device *rdev, int crtc); extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc); extern int r100_mc_wait_for_idle(struct radeon_device *rdev); @@ -250,7 +250,7 @@ extern void rs600_pm_misc(struct radeon_device *rdev); extern void rs600_pm_prepare(struct radeon_device *rdev); extern void rs600_pm_finish(struct radeon_device *rdev); extern void rs600_page_flip(struct radeon_device *rdev, int crtc, - u64 crtc_base); + u64 crtc_base, bool async); extern bool rs600_page_flip_pending(struct radeon_device *rdev, int crtc); void rs600_set_safe_registers(struct radeon_device *rdev); extern void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc); @@ -464,7 +464,8 @@ void rv770_fini(struct radeon_device *rdev); int rv770_suspend(struct radeon_device *rdev); int rv770_resume(struct radeon_device *rdev); void rv770_pm_misc(struct radeon_device *rdev); -void rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); +void rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base, + bool async); bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc); void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); void r700_cp_stop(struct radeon_device *rdev); @@ -534,7 +535,7 @@ extern void btc_pm_init_profile(struct radeon_device *rdev); int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); extern void evergreen_page_flip(struct radeon_device *rdev, int crtc, - u64 crtc_base); + u64 crtc_base, bool async); extern bool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc); extern void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc); void evergreen_disable_interrupt_state(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index fcc7483d3f7b..7f176ecfc583 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -490,7 +490,7 @@ static void radeon_flip_work_func(struct work_struct *__work) vblank->linedur_ns / 1000, stat, vpos, hpos); /* do the flip (mmio) */ - radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base); + radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base, work->async); radeon_crtc->flip_status = RADEON_FLIP_SUBMITTED; spin_unlock_irqrestore(&crtc->dev->event_lock, flags); @@ -525,6 +525,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, work->rdev = rdev; work->crtc_id = radeon_crtc->crtc_id; work->event = event; + work->async = (page_flip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0; /* schedule unpin of the old buffer */ old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb); @@ -1630,6 +1631,9 @@ int radeon_modeset_init(struct radeon_device *rdev) rdev->ddev->mode_config.funcs = &radeon_mode_funcs; + if (radeon_use_pflipirq == 2 && rdev->family >= CHIP_R600) + rdev->ddev->mode_config.async_page_flip = true; + if (ASIC_IS_DCE5(rdev)) { rdev->ddev->mode_config.max_width = 16384; rdev->ddev->mode_config.max_height = 16384; diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 0051c4288725..f16af119c688 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -110,7 +110,7 @@ void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc) } } -void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) +void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); @@ -121,6 +121,8 @@ void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); /* update the scanout addresses */ + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, + async ? AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0); WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, (u32)crtc_base); WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index fa0b03c48227..1c120a4c3c97 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -801,7 +801,7 @@ u32 rv770_get_xclk(struct radeon_device *rdev) return reference_clock; } -void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) +void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async) { struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); @@ -812,6 +812,8 @@ void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); /* update the scanout addresses */ + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, + async ? AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0); if (radeon_crtc->crtc_id) { WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); -- cgit From 7050c6ef5f0e9bc5e6bf9eb035320b70f731b919 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Wed, 6 Apr 2016 15:33:51 -0400 Subject: drm/radeon: add support for loading new UVD fw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Signed-off-by: Arindam Nath Reviewed-by: Leo Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_uvd.c | 55 +++++++++++++++++++++++++++---------- drivers/gpu/drm/radeon/uvd_v4_2.c | 8 +++++- 3 files changed, 49 insertions(+), 15 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 170e69111d1b..d0a96c7f915d 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1679,6 +1679,7 @@ int radeon_pm_get_type_index(struct radeon_device *rdev, #define RADEON_UVD_HEAP_SIZE (1024*1024) struct radeon_uvd { + bool fw_header_present; struct radeon_bo *vcpu_bo; void *cpu_addr; uint64_t gpu_addr; diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 6fe9e4e76284..008de2799d9f 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -34,6 +34,7 @@ #include #include "radeon.h" +#include "radeon_ucode.h" #include "r600d.h" /* 1 second timeout */ @@ -47,7 +48,8 @@ #define FIRMWARE_CYPRESS "radeon/CYPRESS_uvd.bin" #define FIRMWARE_SUMO "radeon/SUMO_uvd.bin" #define FIRMWARE_TAHITI "radeon/TAHITI_uvd.bin" -#define FIRMWARE_BONAIRE "radeon/BONAIRE_uvd.bin" +#define FIRMWARE_BONAIRE_LEGACY "radeon/BONAIRE_uvd.bin" +#define FIRMWARE_BONAIRE "radeon/bonaire_uvd.bin" MODULE_FIRMWARE(FIRMWARE_R600); MODULE_FIRMWARE(FIRMWARE_RS780); @@ -56,6 +58,7 @@ MODULE_FIRMWARE(FIRMWARE_RV710); MODULE_FIRMWARE(FIRMWARE_CYPRESS); MODULE_FIRMWARE(FIRMWARE_SUMO); MODULE_FIRMWARE(FIRMWARE_TAHITI); +MODULE_FIRMWARE(FIRMWARE_BONAIRE_LEGACY); MODULE_FIRMWARE(FIRMWARE_BONAIRE); static void radeon_uvd_idle_work_handler(struct work_struct *work); @@ -63,7 +66,7 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work); int radeon_uvd_init(struct radeon_device *rdev) { unsigned long bo_size; - const char *fw_name; + const char *fw_name = NULL, *legacy_fw_name = NULL; int i, r; INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler); @@ -74,22 +77,22 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_RV670: case CHIP_RV620: case CHIP_RV635: - fw_name = FIRMWARE_R600; + legacy_fw_name = FIRMWARE_R600; break; case CHIP_RS780: case CHIP_RS880: - fw_name = FIRMWARE_RS780; + legacy_fw_name = FIRMWARE_RS780; break; case CHIP_RV770: - fw_name = FIRMWARE_RV770; + legacy_fw_name = FIRMWARE_RV770; break; case CHIP_RV710: case CHIP_RV730: case CHIP_RV740: - fw_name = FIRMWARE_RV710; + legacy_fw_name = FIRMWARE_RV710; break; case CHIP_CYPRESS: @@ -97,7 +100,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_JUNIPER: case CHIP_REDWOOD: case CHIP_CEDAR: - fw_name = FIRMWARE_CYPRESS; + legacy_fw_name = FIRMWARE_CYPRESS; break; case CHIP_SUMO: @@ -107,7 +110,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_BARTS: case CHIP_TURKS: case CHIP_CAICOS: - fw_name = FIRMWARE_SUMO; + legacy_fw_name = FIRMWARE_SUMO; break; case CHIP_TAHITI: @@ -115,7 +118,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_PITCAIRN: case CHIP_ARUBA: case CHIP_OLAND: - fw_name = FIRMWARE_TAHITI; + legacy_fw_name = FIRMWARE_TAHITI; break; case CHIP_BONAIRE: @@ -123,6 +126,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_KAVERI: case CHIP_HAWAII: case CHIP_MULLINS: + legacy_fw_name = FIRMWARE_BONAIRE_LEGACY; fw_name = FIRMWARE_BONAIRE; break; @@ -130,11 +134,34 @@ int radeon_uvd_init(struct radeon_device *rdev) return -EINVAL; } - r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev); - if (r) { - dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", - fw_name); - return r; + rdev->uvd.fw_header_present = false; + if (fw_name) { + /* Let's try to load the newer firmware first */ + r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev); + if (r) { + dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", + fw_name); + } else { + r = radeon_ucode_validate(rdev->uvd_fw); + if (r) + return r; + + rdev->uvd.fw_header_present = true; + } + } + + /* + * In case there is only legacy firmware, or we encounter an error + * while loading the new firmware, we fall back to loading the legacy + * firmware now. + */ + if (!fw_name || r) { + r = request_firmware(&rdev->uvd_fw, legacy_fw_name, rdev->dev); + if (r) { + dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", + legacy_fw_name); + return r; + } } bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + diff --git a/drivers/gpu/drm/radeon/uvd_v4_2.c b/drivers/gpu/drm/radeon/uvd_v4_2.c index d04d5073eef2..205562fa31e3 100644 --- a/drivers/gpu/drm/radeon/uvd_v4_2.c +++ b/drivers/gpu/drm/radeon/uvd_v4_2.c @@ -41,7 +41,13 @@ int uvd_v4_2_resume(struct radeon_device *rdev) uint32_t size; /* programm the VCPU memory controller bits 0-27 */ - addr = rdev->uvd.gpu_addr >> 3; + + /* skip over the header of the new firmware format */ + if (rdev->uvd.fw_header_present) + addr = (rdev->uvd.gpu_addr + 0x200) >> 3; + else + addr = rdev->uvd.gpu_addr >> 3; + size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET0, addr); WREG32(UVD_VCPU_CACHE_SIZE0, size); -- cgit From 8b2cf4f5758f172d0980688383cea83241dc59e6 Mon Sep 17 00:00:00 2001 From: Arindam Nath Date: Wed, 6 Apr 2016 15:33:52 -0400 Subject: drm/radeon: handle more than 10 UVD sessions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Signed-off-by: Arindam Nath Reviewed-by: Leo Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cikd.h | 1 + drivers/gpu/drm/radeon/radeon.h | 9 ++++++--- drivers/gpu/drm/radeon/radeon_uvd.c | 33 +++++++++++++++++++++++++-------- drivers/gpu/drm/radeon/uvd_v1_0.c | 5 +++-- drivers/gpu/drm/radeon/uvd_v2_2.c | 5 +++-- drivers/gpu/drm/radeon/uvd_v4_2.c | 8 ++++++-- 6 files changed, 44 insertions(+), 17 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 391ff9d5d706..cead2284fd79 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -2071,6 +2071,7 @@ #define UVD_UDEC_DBW_ADDR_CONFIG 0xef54 #define UVD_LMI_EXT40_ADDR 0xf498 +#define UVD_GP_SCRATCH4 0xf4e0 #define UVD_LMI_ADDR_EXT 0xf594 #define UVD_VCPU_CACHE_OFFSET0 0xf608 #define UVD_VCPU_CACHE_SIZE0 0xf60c diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index d0a96c7f915d..80b24a495d6c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1674,15 +1674,18 @@ int radeon_pm_get_type_index(struct radeon_device *rdev, /* * UVD */ -#define RADEON_MAX_UVD_HANDLES 10 -#define RADEON_UVD_STACK_SIZE (1024*1024) -#define RADEON_UVD_HEAP_SIZE (1024*1024) +#define RADEON_DEFAULT_UVD_HANDLES 10 +#define RADEON_MAX_UVD_HANDLES 30 +#define RADEON_UVD_STACK_SIZE (200*1024) +#define RADEON_UVD_HEAP_SIZE (256*1024) +#define RADEON_UVD_SESSION_SIZE (50*1024) struct radeon_uvd { bool fw_header_present; struct radeon_bo *vcpu_bo; void *cpu_addr; uint64_t gpu_addr; + unsigned max_handles; atomic_t handles[RADEON_MAX_UVD_HANDLES]; struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; unsigned img_size[RADEON_MAX_UVD_HANDLES]; diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 008de2799d9f..73dfe01435ea 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -135,6 +135,7 @@ int radeon_uvd_init(struct radeon_device *rdev) } rdev->uvd.fw_header_present = false; + rdev->uvd.max_handles = RADEON_DEFAULT_UVD_HANDLES; if (fw_name) { /* Let's try to load the newer firmware first */ r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev); @@ -142,11 +143,27 @@ int radeon_uvd_init(struct radeon_device *rdev) dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", fw_name); } else { + struct common_firmware_header *hdr = (void *)rdev->uvd_fw->data; + unsigned version_major, version_minor, family_id; + r = radeon_ucode_validate(rdev->uvd_fw); if (r) return r; rdev->uvd.fw_header_present = true; + + family_id = le32_to_cpu(hdr->ucode_version) & 0xff; + version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff; + version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff; + DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n", + version_major, version_minor, family_id); + + /* + * Limit the number of UVD handles depending on + * microcode major and minor versions. + */ + if ((version_major >= 0x01) && (version_minor >= 0x37)) + rdev->uvd.max_handles = RADEON_MAX_UVD_HANDLES; } } @@ -166,7 +183,7 @@ int radeon_uvd_init(struct radeon_device *rdev) bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE + - RADEON_GPU_PAGE_SIZE; + RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles; r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, 0, NULL, NULL, &rdev->uvd.vcpu_bo); @@ -199,7 +216,7 @@ int radeon_uvd_init(struct radeon_device *rdev) radeon_bo_unreserve(rdev->uvd.vcpu_bo); - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < rdev->uvd.max_handles; ++i) { atomic_set(&rdev->uvd.handles[i], 0); rdev->uvd.filp[i] = NULL; rdev->uvd.img_size[i] = 0; @@ -236,7 +253,7 @@ int radeon_uvd_suspend(struct radeon_device *rdev) if (rdev->uvd.vcpu_bo == NULL) return 0; - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < rdev->uvd.max_handles; ++i) { uint32_t handle = atomic_read(&rdev->uvd.handles[i]); if (handle != 0) { struct radeon_fence *fence; @@ -311,7 +328,7 @@ void radeon_uvd_force_into_uvd_segment(struct radeon_bo *rbo, void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp) { int i, r; - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < rdev->uvd.max_handles; ++i) { uint32_t handle = atomic_read(&rdev->uvd.handles[i]); if (handle != 0 && rdev->uvd.filp[i] == filp) { struct radeon_fence *fence; @@ -496,7 +513,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, return r; /* try to alloc a new handle */ - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < p->rdev->uvd.max_handles; ++i) { if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { DRM_ERROR("Handle 0x%x already in use!\n", handle); return -EINVAL; @@ -522,7 +539,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, return r; /* validate the handle */ - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < p->rdev->uvd.max_handles; ++i) { if (atomic_read(&p->rdev->uvd.handles[i]) == handle) { if (p->rdev->uvd.filp[i] != p->filp) { DRM_ERROR("UVD handle collision detected!\n"); @@ -537,7 +554,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, case 2: /* it's a destroy msg, free the handle */ - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) + for (i = 0; i < p->rdev->uvd.max_handles; ++i) atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0); radeon_bo_kunmap(bo); return 0; @@ -836,7 +853,7 @@ static void radeon_uvd_count_handles(struct radeon_device *rdev, *sd = 0; *hd = 0; - for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { + for (i = 0; i < rdev->uvd.max_handles; ++i) { if (!atomic_read(&rdev->uvd.handles[i])) continue; diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c index 12ddcfa82e20..0dbeb504a429 100644 --- a/drivers/gpu/drm/radeon/uvd_v1_0.c +++ b/drivers/gpu/drm/radeon/uvd_v1_0.c @@ -124,12 +124,13 @@ int uvd_v1_0_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size); addr += size; - size = RADEON_UVD_STACK_SIZE >> 3; + size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size); addr += size; - size = RADEON_UVD_HEAP_SIZE >> 3; + size = (RADEON_UVD_STACK_SIZE + + (RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size); diff --git a/drivers/gpu/drm/radeon/uvd_v2_2.c b/drivers/gpu/drm/radeon/uvd_v2_2.c index 7ed778cec7c6..9071e656a565 100644 --- a/drivers/gpu/drm/radeon/uvd_v2_2.c +++ b/drivers/gpu/drm/radeon/uvd_v2_2.c @@ -116,12 +116,13 @@ int uvd_v2_2_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size); addr += size; - size = RADEON_UVD_STACK_SIZE >> 3; + size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size); addr += size; - size = RADEON_UVD_HEAP_SIZE >> 3; + size = (RADEON_UVD_STACK_SIZE + + (RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size); diff --git a/drivers/gpu/drm/radeon/uvd_v4_2.c b/drivers/gpu/drm/radeon/uvd_v4_2.c index 205562fa31e3..91613b8a9dc9 100644 --- a/drivers/gpu/drm/radeon/uvd_v4_2.c +++ b/drivers/gpu/drm/radeon/uvd_v4_2.c @@ -53,12 +53,13 @@ int uvd_v4_2_resume(struct radeon_device *rdev) WREG32(UVD_VCPU_CACHE_SIZE0, size); addr += size; - size = RADEON_UVD_STACK_SIZE >> 3; + size = RADEON_UVD_HEAP_SIZE >> 3; WREG32(UVD_VCPU_CACHE_OFFSET1, addr); WREG32(UVD_VCPU_CACHE_SIZE1, size); addr += size; - size = RADEON_UVD_HEAP_SIZE >> 3; + size = (RADEON_UVD_STACK_SIZE + + (RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3; WREG32(UVD_VCPU_CACHE_OFFSET2, addr); WREG32(UVD_VCPU_CACHE_SIZE2, size); @@ -70,5 +71,8 @@ int uvd_v4_2_resume(struct radeon_device *rdev) addr = (rdev->uvd.gpu_addr >> 32) & 0xFF; WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); + if (rdev->uvd.fw_header_present) + WREG32(UVD_GP_SCRATCH4, rdev->uvd.max_handles); + return 0; } -- cgit From 8c4f2bbd66784f00a509bf0787aa16b19ceaa6c7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 7 Apr 2016 06:50:25 +1000 Subject: drm/radeon: add support for SET_APPEND_CNT packet3 (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds support to the command parser for the set append counter packet3, this is required to support atomic counters on evergreen/cayman GPUs. v2: fixup some of the hardcoded numbers with real register names (Christian) Reviewed-by: Christian König Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen_cs.c | 45 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/evergreend.h | 43 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- 3 files changed, 90 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 9e93205eb9e4..18ddd752b64b 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -2608,6 +2608,51 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, } } break; + case PACKET3_SET_APPEND_CNT: + { + uint32_t areg; + uint32_t allowed_reg_base; + uint32_t source_sel; + if (pkt->count != 2) { + DRM_ERROR("bad SET_APPEND_CNT (invalid count)\n"); + return -EINVAL; + } + + allowed_reg_base = GDS_APPEND_COUNT_0; + allowed_reg_base -= PACKET3_SET_CONTEXT_REG_START; + allowed_reg_base >>= 2; + + areg = idx_value >> 16; + if (areg < allowed_reg_base || areg > (allowed_reg_base + 11)) { + dev_warn(p->dev, "forbidden register for append cnt 0x%08x at %d\n", + areg, idx); + return -EINVAL; + } + + source_sel = G_PACKET3_SET_APPEND_CNT_SRC_SELECT(idx_value); + if (source_sel == PACKET3_SAC_SRC_SEL_MEM) { + uint64_t offset; + uint32_t swap; + r = radeon_cs_packet_next_reloc(p, &reloc, 0); + if (r) { + DRM_ERROR("bad SET_APPEND_CNT (missing reloc)\n"); + return -EINVAL; + } + offset = radeon_get_ib_value(p, idx + 1); + swap = offset & 0x3; + offset &= ~0x3; + + offset += ((u64)(radeon_get_ib_value(p, idx + 2) & 0xff)) << 32; + + offset += reloc->gpu_offset; + ib[idx+1] = (offset & 0xfffffffc) | swap; + ib[idx+2] = upper_32_bits(offset) & 0xff; + } else { + DRM_ERROR("bad SET_APPEND_CNT (unsupported operation)\n"); + return -EINVAL; + } + break; + } case PACKET3_NOP: break; default: diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 13b6029d65cc..0b174e14e9a6 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -1689,6 +1689,36 @@ #define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73 #define PACKET3_SET_RESOURCE_INDIRECT 0x74 #define PACKET3_SET_APPEND_CNT 0x75 +/* SET_APPEND_CNT - documentation + * 1. header + * 2. COMMAND + * 1:0 - SOURCE SEL + * 15:2 - Reserved + * 31:16 - WR_REG_OFFSET - context register to write source data to. + * (one of R_02872C_GDS_APPEND_COUNT_0-11) + * 3. CONTROL + * (for source == mem) + * 31:2 SRC_ADDRESS_LO + * 0:1 SWAP + * (for source == GDS) + * 31:0 GDS offset + * (for source == DATA) + * 31:0 DATA + * (for source == REG) + * 31:0 REG + * 4. SRC_ADDRESS_HI[7:0] + * kernel driver 2.44 only supports SRC == MEM. + */ +#define PACKET3_SET_APPEND_CNT_SRC_SELECT(x) ((x) << 0) +#define G_PACKET3_SET_APPEND_CNT_SRC_SELECT(x) ((x & 0x3) >> 0) +/* source is from the data in CONTROL */ +#define PACKET3_SAC_SRC_SEL_DATA 0x0 +/* source is from register */ +#define PACKET3_SAC_SRC_SEL_REG 0x1 +/* source is from GDS offset in CONTROL */ +#define PACKET3_SAC_SRC_SEL_GDS 0x2 +/* source is from memory address */ +#define PACKET3_SAC_SRC_SEL_MEM 0x3 #define SQ_RESOURCE_CONSTANT_WORD7_0 0x3001c #define S__SQ_CONSTANT_TYPE(x) (((x) & 3) << 30) @@ -2005,6 +2035,19 @@ #define GDS_ADDR_BASE 0x28720 +#define GDS_APPEND_COUNT_0 0x2872C +#define GDS_APPEND_COUNT_1 0x28730 +#define GDS_APPEND_COUNT_2 0x28734 +#define GDS_APPEND_COUNT_3 0x28738 +#define GDS_APPEND_COUNT_4 0x2873C +#define GDS_APPEND_COUNT_5 0x28740 +#define GDS_APPEND_COUNT_6 0x28744 +#define GDS_APPEND_COUNT_7 0x28748 +#define GDS_APPEND_COUNT_8 0x2874c +#define GDS_APPEND_COUNT_9 0x28750 +#define GDS_APPEND_COUNT_10 0x28754 +#define GDS_APPEND_COUNT_11 0x28758 + #define CB_IMMED0_BASE 0x28b9c #define CB_IMMED1_BASE 0x28ba0 #define CB_IMMED2_BASE 0x28ba4 diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index d2a925ed2346..1ff77cea436d 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -93,9 +93,10 @@ * 2.41.0 - evergreen/cayman: Add SET_BASE/DRAW_INDIRECT command parsing support * 2.42.0 - Add VCE/VUI (Video Usability Information) support * 2.43.0 - RADEON_INFO_GPU_RESET_COUNTER + * 2.44.0 - SET_APPEND_CNT packet3 support */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 43 +#define KMS_DRIVER_MINOR 44 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); -- cgit From dfd5e50ea43ca4a89de061fb69618299760eb682 Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 6 Apr 2016 11:12:03 +0200 Subject: drm/ttm: remove use_ticket parameter from ttm_bo_reserve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not used any more. Reviewed-by: Sinclair Yeh Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_object.c | 2 +- drivers/gpu/drm/radeon/radeon_object.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 2d901bf28a94..7e0c16c74cf3 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -832,7 +832,7 @@ int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, bool no_wait) { int r; - r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, NULL); + r = ttm_bo_reserve(&bo->tbo, true, no_wait, NULL); if (unlikely(r != 0)) return r; if (mem_type) diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index d8d295ee7c12..a10bb3deee54 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -65,7 +65,7 @@ static inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_intr) { int r; - r = ttm_bo_reserve(&bo->tbo, !no_intr, false, false, NULL); + r = ttm_bo_reserve(&bo->tbo, !no_intr, false, NULL); if (unlikely(r != 0)) { if (r != -ERESTARTSYS) dev_err(bo->rdev->dev, "%p reserve failed\n", bo); -- cgit From 8aa6d4fc5f470c5e4363c705bbae96ccb1b033b0 Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 6 Apr 2016 11:12:04 +0200 Subject: drm/ttm: remove lazy parameter from ttm_bo_wait MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not used any more. Reviewed-by: Sinclair Yeh Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 7e0c16c74cf3..be30861afae9 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -838,7 +838,7 @@ int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, bool no_wait) if (mem_type) *mem_type = bo->tbo.mem.mem_type; - r = ttm_bo_wait(&bo->tbo, true, true, no_wait); + r = ttm_bo_wait(&bo->tbo, true, no_wait); ttm_bo_unreserve(&bo->tbo); return r; } -- cgit From 98c2872ae99bb7c9e8e4369cf48154f41dd6a109 Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 6 Apr 2016 11:12:07 +0200 Subject: drm/ttm: implement LRU add callbacks v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows fine grained control for the driver where to add a BO into the LRU. v2: fix typo in comment Reviewed-by: Sinclair Yeh Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_ttm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 7dddfdce85e6..81032ca57147 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -863,6 +863,8 @@ static struct ttm_bo_driver radeon_bo_driver = { .fault_reserve_notify = &radeon_bo_fault_reserve_notify, .io_mem_reserve = &radeon_ttm_io_mem_reserve, .io_mem_free = &radeon_ttm_io_mem_free, + .lru_tail = &ttm_bo_default_lru_tail, + .swap_lru_tail = &ttm_bo_default_swap_lru_tail, }; int radeon_ttm_init(struct radeon_device *rdev) -- cgit From 3d02b7fee9c3ece1746f5b06c4143b511383fc6b Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Fri, 15 Apr 2016 02:47:49 +0200 Subject: drm/radeon: Allow setting shader registers using DMA/COPY packet3 on SI. Mesa uses a COPY_DATA packet to copy the grid size for indirect dispatches into COMPUTE_USER_DATA_*. Setting those registers with a SET_SH_REG packet is allowed, not allowing them with other packets seems like an oversight. v2: Clarify commit message. Signed-off-by: Bas Nieuwenhuizen Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- drivers/gpu/drm/radeon/si.c | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 1ff77cea436d..c0083f04a842 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -94,9 +94,10 @@ * 2.42.0 - Add VCE/VUI (Video Usability Information) support * 2.43.0 - RADEON_INFO_GPU_RESET_COUNTER * 2.44.0 - SET_APPEND_CNT packet3 support + * 2.45.0 - Allow setting shader registers using DMA/COPY packet3 on SI */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 44 +#define KMS_DRIVER_MINOR 45 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 7afe825ee561..b30e719dd56d 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -4364,6 +4364,10 @@ static bool si_vm_reg_valid(u32 reg) if (reg >= 0x28000) return true; + /* shader regs are also fine */ + if (reg >= 0xB000 && reg < 0xC000) + return true; + /* check config regs */ switch (reg) { case GRBM_GFX_INDEX: -- cgit From 84ef4c12ee7b7a080364ad9168ffcf5fa6df4ecf Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 22 Apr 2016 10:06:23 +1000 Subject: drm/radeon: add cayman VM support for append packet. This adds support for SET_APPEND_CNT packet3 to the VM paths. Signed-off-by: Dave Airlie Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen_cs.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 18ddd752b64b..0d3f744de35a 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -3483,6 +3483,27 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev, } } break; + case PACKET3_SET_APPEND_CNT: { + uint32_t areg; + uint32_t allowed_reg_base; + + if (pkt->count != 2) { + DRM_ERROR("bad SET_APPEND_CNT (invalid count)\n"); + return -EINVAL; + } + + allowed_reg_base = GDS_APPEND_COUNT_0; + allowed_reg_base -= PACKET3_SET_CONTEXT_REG_START; + allowed_reg_base >>= 2; + + areg = idx_value >> 16; + if (areg < allowed_reg_base || areg > (allowed_reg_base + 11)) { + DRM_ERROR("forbidden register for append cnt 0x%08x at %d\n", + areg, idx); + return -EINVAL; + } + break; + } default: return -EINVAL; } -- cgit From a8ad0bd84f986072314595d05444719fdf29e412 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 May 2016 11:04:54 +0100 Subject: drm: Remove unused drm_device from drm_gem_object_lookup() drm_gem_object_lookup() has never required the drm_device for its file local translation of the user handle to the GEM object. Let's remove the unused parameter and save some space. Signed-off-by: Chris Wilson Cc: dri-devel@lists.freedesktop.org Cc: Dave Airlie Cc: Daniel Vetter [danvet: Fixup kerneldoc too.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/radeon/radeon_cs.c | 2 +- drivers/gpu/drm/radeon/radeon_cursor.c | 2 +- drivers/gpu/drm/radeon/radeon_display.c | 2 +- drivers/gpu/drm/radeon/radeon_gem.c | 16 ++++++++-------- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index ab39b85e0f76..271652963fa1 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -101,7 +101,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) unsigned priority; r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4]; - gobj = drm_gem_object_lookup(ddev, p->filp, r->handle); + gobj = drm_gem_object_lookup(p->filp, r->handle); if (gobj == NULL) { DRM_ERROR("gem object lookup failed 0x%x\n", r->handle); diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index afaf346bd50e..2a10e24b34b1 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -274,7 +274,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, return -EINVAL; } - obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); return -ENOENT; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 628eb878a069..6a41b4982647 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1368,7 +1368,7 @@ radeon_user_framebuffer_create(struct drm_device *dev, struct radeon_framebuffer *radeon_fb; int ret; - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); + obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); if (obj == NULL) { dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, " "can't create framebuffer\n", mode_cmd->handles[0]); diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index e26c963f2e93..deb9511725c9 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -382,7 +382,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, down_read(&rdev->exclusive_lock); /* just do a BO wait for now */ - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { up_read(&rdev->exclusive_lock); return -ENOENT; @@ -404,7 +404,7 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, struct drm_gem_object *gobj; struct radeon_bo *robj; - gobj = drm_gem_object_lookup(dev, filp, handle); + gobj = drm_gem_object_lookup(filp, handle); if (gobj == NULL) { return -ENOENT; } @@ -435,7 +435,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, int r; uint32_t cur_placement = 0; - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { return -ENOENT; } @@ -464,7 +464,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, uint32_t cur_placement = 0; long ret; - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { return -ENOENT; } @@ -495,7 +495,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, int r = 0; DRM_DEBUG("%d \n", args->handle); - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) return -ENOENT; robj = gem_to_radeon_bo(gobj); @@ -513,7 +513,7 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, int r = 0; DRM_DEBUG("\n"); - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) return -ENOENT; rbo = gem_to_radeon_bo(gobj); @@ -648,7 +648,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { args->operation = RADEON_VA_RESULT_ERROR; return -ENOENT; @@ -703,7 +703,7 @@ int radeon_gem_op_ioctl(struct drm_device *dev, void *data, struct radeon_bo *robj; int r; - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { return -ENOENT; } -- cgit From c6740c9c9e914742fd2ec159142c40701f7df966 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 18 May 2016 18:07:33 +0200 Subject: drm: remove unused dev variables After drm_gem_object_lookup() was changed along with all its callers, we have several drivers that have unused variables: drm/armada/armada_crtc.c: In function 'armada_drm_crtc_cursor_set': drm/armada/armada_crtc.c:900:21: error: unused variable 'dev' [-Werror=unused-variable] drm/nouveau/nouveau_gem.c: In function 'validate_init': drm/nouveau/nouveau_gem.c:371:21: error: unused variable 'dev' [-Werror=unused-variable] drm/nouveau/nv50_display.c: In function 'nv50_crtc_cursor_set': drm/nouveau/nv50_display.c:1308:21: error: unused variable 'dev' [-Werror=unused-variable] drm/radeon/radeon_cs.c: In function 'radeon_cs_parser_relocs': drm/radeon/radeon_cs.c:77:21: error: unused variable 'ddev' [-Werror=unused-variable] This fixes all the instances I found with ARM randconfig builds so far. Signed-off-by: Arnd Bergmann Fixes: a8ad0bd84f98 ("drm: Remove unused drm_device from drm_gem_object_lookup()") Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1463587653-3035181-6-git-send-email-arnd@arndb.de --- drivers/gpu/drm/radeon/radeon_cs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 271652963fa1..510ea371dacc 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -74,7 +74,6 @@ static void radeon_cs_buckets_get_list(struct radeon_cs_buckets *b, static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) { - struct drm_device *ddev = p->rdev->ddev; struct radeon_cs_chunk *chunk; struct radeon_cs_buckets buckets; unsigned i; -- cgit From fcee59065e58498682c60069cc6fb90694bab27e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 18 May 2016 21:47:38 +0200 Subject: drm: Nuke ->vblank_disable_allowed This was added in commit 0a3e67a4caac273a3bfc4ced3da364830b1ab241 Author: Jesse Barnes Date: Tue Sep 30 12:14:26 2008 -0700 drm: Rework vblank-wait handling to allow interrupt reduction. to stay backwards-compatible with old UMS code that didn't even tell the kernel when it did a modeset, so that the kernel could save/restore vblank counters. At worst this means vblanks will be somewhat funky on a setup that very likely no one still runs. So let's just nuke it. Plan B would be to set it unconditionally in drm_vblank_init for kms drivers, instead of in each driver separately. So if this patch breaks anything please only restore the hunks in drmP.h and drm_irq.c, plus add a check for DRIVER_MODESET in drm_vblank_init. Stumbled over this in a discussion on irc with Chris. Cc: Chris Wilson Cc: Alex Deucher Cc: Liviu Dudau Cc: Russell King Cc: Thierry Reding Cc: Eric Anholt Cc: Laurent Pinchart Cc: Inki Dae Cc: Tomi Valkeinen Cc: Mark Yao Cc: Sascha Hauer Cc: Philipp Zabel Signed-off-by: Daniel Vetter Reviewed-by: Alex Deucher Acked-by: Liviu Dudau Acked-by: Laurent Pinchart Tested-by: Laurent Pinchart Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_irq_kms.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 1e9304d1c88f..c084cadcbf21 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -291,7 +291,6 @@ int radeon_irq_kms_init(struct radeon_device *rdev) if (r) { return r; } - rdev->ddev->vblank_disable_allowed = true; /* enable msi */ rdev->msi_enabled = 0; -- cgit