From patchwork Mon Mar 22 18:57:40 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 87485 Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2MIwwUC025485 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 22 Mar 2010 18:59:34 GMT Received: from localhost ([127.0.0.1] helo=sfs-ml-3.v29.ch3.sourceforge.com) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1Ntmp7-0008Ko-8C; Mon, 22 Mar 2010 18:58:01 +0000 Received: from sfi-mx-4.v28.ch3.sourceforge.com ([172.29.28.124] helo=mx.sourceforge.net) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1Ntmp6-0008Ki-4B for dri-devel@lists.sourceforge.net; Mon, 22 Mar 2010 18:58:00 +0000 Received-SPF: pass (sfi-mx-4.v28.ch3.sourceforge.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=mjg@redhat.com; helo=mx1.redhat.com; Received: from mx1.redhat.com ([209.132.183.28]) by sfi-mx-4.v28.ch3.sourceforge.com with esmtp (Exim 4.69) id 1Ntmp4-0000at-OF for dri-devel@lists.sourceforge.net; Mon, 22 Mar 2010 18:58:00 +0000 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o2MIvoGa029030 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 22 Mar 2010 14:57:50 -0400 Received: from cavan.codon.org.uk (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o2MIvnlM018444 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO); Mon, 22 Mar 2010 14:57:50 -0400 Received: from lan-nat-pool-bos.redhat.com ([66.187.234.200] helo=localhost.localdomain) by cavan.codon.org.uk with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1Ntmot-0001yh-LO; Mon, 22 Mar 2010 18:57:47 +0000 From: Matthew Garrett To: dri-devel@lists.sourceforge.net Subject: [PATCH 4/4] radeon: Run engine reclocking during vblank Date: Mon, 22 Mar 2010 14:57:40 -0400 Message-Id: <1269284260-12224-4-git-send-email-mjg@redhat.com> In-Reply-To: <1269284260-12224-3-git-send-email-mjg@redhat.com> References: <1269284260-12224-1-git-send-email-mjg@redhat.com> <1269284260-12224-2-git-send-email-mjg@redhat.com> <1269284260-12224-3-git-send-email-mjg@redhat.com> X-SA-Do-Not-Run: Yes X-SA-Exim-Connect-IP: 66.187.234.200 X-SA-Exim-Mail-From: mjg@redhat.com X-SA-Exim-Scanned: No (on cavan.codon.org.uk); SAEximRunCond expanded to false X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 X-Spam-Score: -0.9 (/) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record 0.6 AWL AWL: From: address is in the auto white-list X-Headers-End: 1Ntmp4-0000at-OF Cc: alexdeucher@gmail.com, Matthew Garrett X-BeenThere: dri-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.sourceforge.net X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 22 Mar 2010 18:59:34 +0000 (UTC) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 08e22fe..cdd55b2 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -189,11 +189,14 @@ void r100_set_power_state(struct radeon_device *rdev) /* reclocking the engine appears to be ok as long as the engine is idle * no need for vblank waiting */ - if (sclk != rdev->pm.current_sclk) { - radeon_set_engine_clock(rdev, sclk); - rdev->pm.current_sclk = sclk; - DRM_INFO("Setting: e: %d\n", sclk); - } + if (sclk != rdev->pm.current_sclk) { + if (!rdev->pm.active_crtcs) { + radeon_set_engine_clock(rdev, sclk); + rdev->pm.current_sclk = sclk; + } else { + rdev->pm.new_mclk = sclk; + } + } /* set memory clock */ if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { @@ -461,6 +464,7 @@ int r100_irq_process(struct radeon_device *rdev) { uint32_t status, msi_rearm; bool queue_hotplug = false; + int i = 0; /* reset gui idle ack. the status bit is broken */ rdev->irq.gui_idle_acked = false; @@ -487,24 +491,44 @@ int r100_irq_process(struct radeon_device *rdev) if (status & RADEON_CRTC_VBLANK_STAT) { drm_handle_vblank(rdev->ddev, 0); rdev->pm.vblank_sync = true; - if (rdev->pm.new_mclk) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_memory_clock(rdev, rdev->pm.new_mclk); + if (rdev->pm.new_mclk || rdev->pm.new_sclk) { + while (!radeon_pm_debug_check_in_vbl(rdev, false) && i <100) { + udelay(1); + i++; + } + if (i==100) { + dev_err(rdev->dev, "Failed to sync with vblank\n"); + } else if (rdev->pm.new_mclk) { + radeon_set_memory_clock(rdev, rdev->pm.new_mclk); + rdev->pm.current_mclk = rdev->pm.new_mclk; + } else if (rdev->pm.new_sclk) { + radeon_set_engine_clock(rdev, rdev->pm.new_sclk); + rdev->pm.current_sclk = rdev->pm.new_sclk; + } radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_mclk = rdev->pm.new_mclk; - rdev->pm.new_mclk = 0; + rdev->pm.new_mclk = rdev->pm.new_sclk = 0; } wake_up(&rdev->irq.vblank_queue); } if (status & RADEON_CRTC2_VBLANK_STAT) { drm_handle_vblank(rdev->ddev, 1); rdev->pm.vblank_sync = true; - if (rdev->pm.new_mclk) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_memory_clock(rdev, rdev->pm.new_mclk); + if (rdev->pm.new_mclk || rdev->pm.new_sclk) { + while (!radeon_pm_debug_check_in_vbl(rdev, false) && i <100) { + udelay(1); + i++; + } + if (i==100) { + dev_err(rdev->dev, "Failed to sync with vblank\n"); + } else if (rdev->pm.new_mclk) { + radeon_set_memory_clock(rdev, rdev->pm.new_mclk); + rdev->pm.current_mclk = rdev->pm.new_mclk; + } else if (rdev->pm.new_sclk) { + radeon_set_engine_clock(rdev, rdev->pm.new_sclk); + rdev->pm.current_sclk = rdev->pm.new_sclk; + } radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_mclk = rdev->pm.new_mclk; - rdev->pm.new_mclk = 0; + rdev->pm.new_mclk = rdev->pm.new_sclk = 0; } wake_up(&rdev->irq.vblank_queue); } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a89821b..7bb1163 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -292,9 +292,12 @@ void r600_set_power_state(struct radeon_device *rdev) * no need for vblank waiting */ if (sclk != rdev->pm.current_sclk) { - radeon_set_engine_clock(rdev, sclk); - rdev->pm.current_sclk = sclk; - DRM_INFO("Setting: e: %d\n", sclk); + if (!rdev->pm.active_crtcs) { + radeon_set_engine_clock(rdev, sclk); + rdev->pm.current_sclk = sclk; + } else { + rdev->pm.new_mclk = sclk; + } } /* set memory clock */ @@ -305,10 +308,12 @@ void r600_set_power_state(struct radeon_device *rdev) } else { rdev->pm.new_mclk = mclk; } - radeon_sync_with_vblank(rdev); DRM_INFO("Setting: m: %d\n", mclk); } + if (rdev->pm.new_mclk || rdev->pm.new_sclk) + radeon_sync_with_vblank(rdev); + #if 0 if (radeon_gui_idle(rdev) && (rdev->pm.current_simd_mask != rdev->pm.requested_simd_mask)) { @@ -2988,6 +2993,7 @@ int r600_irq_process(struct radeon_device *rdev) u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; unsigned long flags; bool queue_hotplug = false; + int i = 0; DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); if (!rdev->ih.enabled) @@ -3022,12 +3028,22 @@ restart_ih: if (disp_int & LB_D1_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 0); rdev->pm.vblank_sync = true; - if (rdev->pm.new_mclk) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_memory_clock(rdev, rdev->pm.new_mclk); + if (rdev->pm.new_mclk || rdev->pm.new_sclk) { + while (!radeon_pm_debug_check_in_vbl(rdev, false) && i <100) { + udelay(1); + i++; + } + if (i==100) { + dev_err(rdev->dev, "Failed to sync with vblank\n"); + } else if (rdev->pm.new_mclk) { + radeon_set_memory_clock(rdev, rdev->pm.new_mclk); + rdev->pm.current_mclk = rdev->pm.new_mclk; + } else if (rdev->pm.new_sclk) { + radeon_set_engine_clock(rdev, rdev->pm.new_sclk); + rdev->pm.current_sclk = rdev->pm.new_sclk; + } radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_mclk = rdev->pm.new_mclk; - rdev->pm.new_mclk = 0; + rdev->pm.new_mclk = rdev->pm.new_sclk = 0; } wake_up(&rdev->irq.vblank_queue); disp_int &= ~LB_D1_VBLANK_INTERRUPT; @@ -3051,12 +3067,22 @@ restart_ih: if (disp_int & LB_D2_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 1); rdev->pm.vblank_sync = true; - if (rdev->pm.new_mclk) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_memory_clock(rdev, rdev->pm.new_mclk); + if (rdev->pm.new_mclk || rdev->pm.new_sclk) { + while (!radeon_pm_debug_check_in_vbl(rdev, false) && i <100) { + udelay(1); + i++; + } + if (i==100) { + dev_err(rdev->dev, "Failed to sync with vblank\n"); + } else if (rdev->pm.new_mclk) { + radeon_set_memory_clock(rdev, rdev->pm.new_mclk); + rdev->pm.current_mclk = rdev->pm.new_mclk; + } else if (rdev->pm.new_sclk) { + radeon_set_engine_clock(rdev, rdev->pm.new_sclk); + rdev->pm.current_sclk = rdev->pm.new_sclk; + } radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_mclk = rdev->pm.new_mclk; - rdev->pm.new_mclk = 0; + rdev->pm.new_mclk = rdev->pm.new_sclk = 0; } wake_up(&rdev->irq.vblank_queue); disp_int &= ~LB_D2_VBLANK_INTERRUPT; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index d706974..e3e4afc 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -729,6 +729,7 @@ struct radeon_pm { u32 current_sclk; u32 current_mclk; u32 new_mclk; + u32 new_sclk; u32 *mc_arb_init_values; struct radeon_i2c_chan *i2c_bus; /* r6xx+ only */ diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5b964e2..e68c320 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1940,7 +1940,7 @@ void radeon_atom_set_engine_clock(struct radeon_device *rdev, args.ulTargetEngineClock = eng_clock; /* 10 khz */ - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + atom_execute_table_atomic(rdev->mode_info.atom_context, index, (uint32_t *)&args); } void radeon_atom_set_memory_clock(struct radeon_device *rdev,