aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShirish S <shirish.s@amd.com>2017-05-25 00:35:25 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-05-31 14:16:30 -0400
commit2dc80b00652f2a08f3f1a01e668e3c7ad716f55f (patch)
tree622790fc39010cde773be740e6165595e041d81a
parent7e1544ae4dda3222538b08eb2da3cf82e0ca90dc (diff)
drm/amdgpu: optimize amdgpu driver load & resume time
amdgpu_device_resume() & amdgpu_device_init() have a high time consuming call of amdgpu_late_init() which sets the clock_gating state of all IP blocks and is blocking. This patch defers only this setting of clock gating state operation to post resume of amdgpu driver but ideally before the UI comes up or in some cases post ui as well. With this change the resume time of amdgpu_device comes down from 1.299s to 0.199s which further helps in reducing the overall system resume time. V1: made the optimization applicable during driver load as well. TEST:(For ChromiumOS on STONEY only) * UI comes up * amdgpu_late_init() call gets called consistently and no errors reported. Signed-off-by: Shirish S <shirish.s@amd.com> Reviewed-by: Huang Rui <ray.huang@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c46
2 files changed, 39 insertions, 10 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 359fb0ca8209..c01b8b62682b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1613,6 +1613,9 @@ struct amdgpu_device {
1613 /* amdkfd interface */ 1613 /* amdkfd interface */
1614 struct kfd_dev *kfd; 1614 struct kfd_dev *kfd;
1615 1615
1616 /* delayed work_func for deferring clockgating during resume */
1617 struct delayed_work late_init_work;
1618
1616 struct amdgpu_virt virt; 1619 struct amdgpu_virt virt;
1617 1620
1618 /* link all shadow bo */ 1621 /* link all shadow bo */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index a1d631ab8eb9..e731c4876a09 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -57,6 +57,8 @@
57MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin"); 57MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin");
58MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); 58MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");
59 59
60#define AMDGPU_RESUME_MS 2000
61
60static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); 62static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
61static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); 63static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev);
62 64
@@ -1669,22 +1671,13 @@ static bool amdgpu_check_vram_lost(struct amdgpu_device *adev)
1669 AMDGPU_RESET_MAGIC_NUM); 1671 AMDGPU_RESET_MAGIC_NUM);
1670} 1672}
1671 1673
1672static int amdgpu_late_init(struct amdgpu_device *adev) 1674static int amdgpu_late_set_cg_state(struct amdgpu_device *adev)
1673{ 1675{
1674 int i = 0, r; 1676 int i = 0, r;
1675 1677
1676 for (i = 0; i < adev->num_ip_blocks; i++) { 1678 for (i = 0; i < adev->num_ip_blocks; i++) {
1677 if (!adev->ip_blocks[i].status.valid) 1679 if (!adev->ip_blocks[i].status.valid)
1678 continue; 1680 continue;
1679 if (adev->ip_blocks[i].version->funcs->late_init) {
1680 r = adev->ip_blocks[i].version->funcs->late_init((void *)adev);
1681 if (r) {
1682 DRM_ERROR("late_init of IP block <%s> failed %d\n",
1683 adev->ip_blocks[i].version->funcs->name, r);
1684 return r;
1685 }
1686 adev->ip_blocks[i].status.late_initialized = true;
1687 }
1688 /* skip CG for VCE/UVD, it's handled specially */ 1681 /* skip CG for VCE/UVD, it's handled specially */
1689 if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && 1682 if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
1690 adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) { 1683 adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) {
@@ -1698,6 +1691,29 @@ static int amdgpu_late_init(struct amdgpu_device *adev)
1698 } 1691 }
1699 } 1692 }
1700 } 1693 }
1694 return 0;
1695}
1696
1697static int amdgpu_late_init(struct amdgpu_device *adev)
1698{
1699 int i = 0, r;
1700
1701 for (i = 0; i < adev->num_ip_blocks; i++) {
1702 if (!adev->ip_blocks[i].status.valid)
1703 continue;
1704 if (adev->ip_blocks[i].version->funcs->late_init) {
1705 r = adev->ip_blocks[i].version->funcs->late_init((void *)adev);
1706 if (r) {
1707 DRM_ERROR("late_init of IP block <%s> failed %d\n",
1708 adev->ip_blocks[i].version->funcs->name, r);
1709 return r;
1710 }
1711 adev->ip_blocks[i].status.late_initialized = true;
1712 }
1713 }
1714
1715 mod_delayed_work(system_wq, &adev->late_init_work,
1716 msecs_to_jiffies(AMDGPU_RESUME_MS));
1701 1717
1702 amdgpu_fill_reset_magic(adev); 1718 amdgpu_fill_reset_magic(adev);
1703 1719
@@ -1791,6 +1807,13 @@ static int amdgpu_fini(struct amdgpu_device *adev)
1791 return 0; 1807 return 0;
1792} 1808}
1793 1809
1810static void amdgpu_late_init_func_handler(struct work_struct *work)
1811{
1812 struct amdgpu_device *adev =
1813 container_of(work, struct amdgpu_device, late_init_work.work);
1814 amdgpu_late_set_cg_state(adev);
1815}
1816
1794int amdgpu_suspend(struct amdgpu_device *adev) 1817int amdgpu_suspend(struct amdgpu_device *adev)
1795{ 1818{
1796 int i, r; 1819 int i, r;
@@ -2050,6 +2073,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
2050 INIT_LIST_HEAD(&adev->gtt_list); 2073 INIT_LIST_HEAD(&adev->gtt_list);
2051 spin_lock_init(&adev->gtt_list_lock); 2074 spin_lock_init(&adev->gtt_list_lock);
2052 2075
2076 INIT_DELAYED_WORK(&adev->late_init_work, amdgpu_late_init_func_handler);
2077
2053 if (adev->asic_type >= CHIP_BONAIRE) { 2078 if (adev->asic_type >= CHIP_BONAIRE) {
2054 adev->rmmio_base = pci_resource_start(adev->pdev, 5); 2079 adev->rmmio_base = pci_resource_start(adev->pdev, 5);
2055 adev->rmmio_size = pci_resource_len(adev->pdev, 5); 2080 adev->rmmio_size = pci_resource_len(adev->pdev, 5);
@@ -2247,6 +2272,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
2247 amdgpu_fbdev_fini(adev); 2272 amdgpu_fbdev_fini(adev);
2248 r = amdgpu_fini(adev); 2273 r = amdgpu_fini(adev);
2249 adev->accel_working = false; 2274 adev->accel_working = false;
2275 cancel_delayed_work_sync(&adev->late_init_work);
2250 /* free i2c buses */ 2276 /* free i2c buses */
2251 amdgpu_i2c_fini(adev); 2277 amdgpu_i2c_fini(adev);
2252 amdgpu_atombios_fini(adev); 2278 amdgpu_atombios_fini(adev);