[PATCH] drm/amdgpu: defer initing UVD & VCE IP blocks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



UVD & VCE blocks take up around 1200 msecs of boot time.
This patch adds them to the late init work function
so as to reduce boot time.

Signed-off-by: Shirish S <shirish.s at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 0e798b3..54f1320 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1589,7 +1589,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
 	for (i = 0; i < adev->num_ip_blocks; i++) {
 		if (!adev->ip_blocks[i].status.sw)
 			continue;
-		if (adev->ip_blocks[i].status.hw)
+		if (adev->ip_blocks[i].status.hw ||
+		    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_UVD ||
+		    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_VCE)
 			continue;
 		r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
 		if (r) {
@@ -1639,17 +1641,18 @@ static bool amdgpu_device_check_vram_lost(struct amdgpu_device *adev)
 }
 
 /**
- * amdgpu_device_ip_late_set_cg_state - late init for clockgating
+ * amdgpu_late_init_ip_blocks - late init of some IP blocks and clockgating
  *
  * @adev: amdgpu_device pointer
  *
- * Late initialization pass enabling clockgating for hardware IPs.
+ * Late initialization pass for high time consuming IP blocks like UVD & VCE
+ * along with  enabling clockgating for hardware IPs.
  * The list of all the hardware IPs that make up the asic is walked and the
  * set_clockgating_state callbacks are run.  This stage is run late
  * in the init process.
  * Returns 0 on success, negative error code on failure.
  */
-static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev)
+static int amdgpu_late_init_ip_blocks(struct amdgpu_device *adev)
 {
 	int i = 0, r;
 
@@ -1657,6 +1660,19 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev)
 		return 0;
 
 	for (i = 0; i < adev->num_ip_blocks; i++) {
+		if (!adev->ip_blocks[i].status.hw &&
+		    (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_UVD ||
+		    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_VCE)) {
+			r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
+			if (r) {
+				DRM_ERROR("hw_init of IP block <%s> failed %d\n",
+					  adev->ip_blocks[i].version->funcs->name, r);
+				return r;
+			}
+
+			adev->ip_blocks[i].status.hw = true;
+		}
+
 		if (!adev->ip_blocks[i].status.valid)
 			continue;
 		/* skip CG for VCE/UVD, it's handled specially */
@@ -1823,7 +1839,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
  *
  * @work: work_struct
  *
- * Work handler for amdgpu_device_ip_late_set_cg_state.  We put the
+ * Work handler for amdgpu_late_init_ip_blocks.  We put the
  * clockgating setup into a worker thread to speed up driver init and
  * resume from suspend.
  */
@@ -1831,7 +1847,7 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work)
 {
 	struct amdgpu_device *adev =
 		container_of(work, struct amdgpu_device, late_init_work.work);
-	amdgpu_device_ip_late_set_cg_state(adev);
+	amdgpu_late_init_ip_blocks(adev);
 }
 
 /**
-- 
2.7.4



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux