From patchwork Mon May 11 20:01:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Christian_K=C3=B6nig?= X-Patchwork-Id: 6383831 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 27B7E9F374 for ; Mon, 11 May 2015 20:02:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2847D206DF for ; Mon, 11 May 2015 20:02:14 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 3709B205DF for ; Mon, 11 May 2015 20:02:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4F2226E52B; Mon, 11 May 2015 13:02:10 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from pegasos-out.vodafone.de (pegasos-out.vodafone.de [80.84.1.38]) by gabe.freedesktop.org (Postfix) with ESMTP id DCBDD6E50C for ; Mon, 11 May 2015 13:02:00 -0700 (PDT) Received: from localhost (localhost.localdomain [127.0.0.1]) by pegasos-out.vodafone.de (Rohrpostix1 Daemon) with ESMTP id 43D09260799; Mon, 11 May 2015 22:02:00 +0200 (CEST) X-Virus-Scanned: amavisd-new at vodafone.de X-Spam-Score: -0.054 X-Spam-Level: X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, FREEMAIL_FROM,RCVD_IN_DNSWL_MED,T_DKIM_INVALID,T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Authentication-Results: rohrpostix1.prod.vfnet.de (amavisd-new); dkim=pass header.i=@vodafone.de Received: from pegasos-out.vodafone.de ([127.0.0.1]) by localhost (rohrpostix1.prod.vfnet.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3s9otvbJL+pW; Mon, 11 May 2015 22:01:58 +0200 (CEST) Received: from smtp-03.vodafone.de (smtp-03.vodafone.de [10.215.254.38]) by pegasos-out.vodafone.de (Rohrpostix1 Daemon) with ESMTP id 87D0826084A; Mon, 11 May 2015 22:01:58 +0200 (CEST) X-DKIM: OpenDKIM Filter v2.6.8 pegasos-out.vodafone.de 87D0826084A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vodafone.de; s=mail; t=1431374518; bh=AcdOXTsY1a6kJrvFOr/j5RT76uaxNk0DyCdayRwCRNg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=j03WUON0cx+pZFKYGiciE2PzKJplWMNaoLmfgtExXDU1DR+tfZ0ffhXt1WlO7jSUR wB/eGHKyElWCqHzvXlG/DKQqwahNaw/HICy1fOEvmO5sm5iHWtWzOHMpo7tj/H5njP SIKK4AKLh9vMsJHxsTZZAB6nDW81OJ9svuz4zP/Y= X-Virus-Scanned: amavisd-new at vodafone.de Received: from smtp-03.vodafone.de ([127.0.0.1]) by localhost (xsmail-dmz7.prod.vfnet.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SeU-IkUjwUnk; Mon, 11 May 2015 22:01:57 +0200 (CEST) From: =?UTF-8?q?Christian=20K=C3=B6nig?= To: alexdeucher@gmail.com Subject: [PATCH 5/9] drm/radeon/dpm: add vce dpm support for TN Date: Mon, 11 May 2015 22:01:51 +0200 Message-Id: <1431374515-2042-5-git-send-email-deathsimple@vodafone.de> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1431374515-2042-1-git-send-email-deathsimple@vodafone.de> References: <1431374515-2042-1-git-send-email-deathsimple@vodafone.de> Cc: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 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.freedesktop.org Sender: "dri-devel" X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/trinity_dpm.c | 76 ++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index a5b02c5..e0d0780 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c @@ -985,6 +985,15 @@ static void trinity_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev trinity_setup_uvd_clocks(rdev, new_rps, old_rps); } +static void trinity_set_vce_clock(struct radeon_device *rdev, + struct radeon_ps *new_rps, + struct radeon_ps *old_rps) +{ + if ((old_rps->evclk != new_rps->evclk) || + (old_rps->ecclk != new_rps->ecclk)) + radeon_set_vce_clocks(rdev, new_rps->evclk, new_rps->ecclk); +} + static void trinity_program_ttt(struct radeon_device *rdev) { struct trinity_power_info *pi = trinity_get_pi(rdev); @@ -1246,6 +1255,7 @@ int trinity_dpm_set_power_state(struct radeon_device *rdev) trinity_force_level_0(rdev); trinity_unforce_levels(rdev); trinity_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps); + trinity_set_vce_clock(rdev, new_ps, old_ps); } trinity_release_mutex(rdev); @@ -1483,7 +1493,35 @@ static void trinity_adjust_uvd_state(struct radeon_device *rdev, } } +static int trinity_get_vce_clock_voltage(struct radeon_device *rdev, + u32 evclk, u32 ecclk, u16 *voltage) +{ + u32 i; + int ret = -EINVAL; + struct radeon_vce_clock_voltage_dependency_table *table = + &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; + + if (((evclk == 0) && (ecclk == 0)) || + (table && (table->count == 0))) { + *voltage = 0; + return 0; + } + + for (i = 0; i < table->count; i++) { + if ((evclk <= table->entries[i].evclk) && + (ecclk <= table->entries[i].ecclk)) { + *voltage = table->entries[i].v; + ret = 0; + break; + } + } + + /* if no match return the highest voltage */ + if (ret) + *voltage = table->entries[table->count - 1].v; + return ret; +} static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, struct radeon_ps *new_rps, @@ -1496,6 +1534,7 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, u32 min_sclk = pi->sys_info.min_sclk; /* XXX check against disp reqs */ u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */ u32 i; + u16 min_vce_voltage; bool force_high; u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count; @@ -1504,6 +1543,14 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, trinity_adjust_uvd_state(rdev, new_rps); + if (new_rps->vce_active) { + new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk; + new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk; + } else { + new_rps->evclk = 0; + new_rps->ecclk = 0; + } + for (i = 0; i < ps->num_levels; i++) { if (ps->levels[i].vddc_index < min_voltage) ps->levels[i].vddc_index = min_voltage; @@ -1512,6 +1559,17 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, ps->levels[i].sclk = trinity_get_valid_engine_clock(rdev, min_sclk); + /* patch in vce limits */ + if (new_rps->vce_active) { + /* sclk */ + if (ps->levels[i].sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk) + ps->levels[i].sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk; + /* vddc */ + trinity_get_vce_clock_voltage(rdev, new_rps->evclk, new_rps->ecclk, &min_vce_voltage); + if (ps->levels[i].vddc_index < min_vce_voltage) + ps->levels[i].vddc_index = min_vce_voltage; + } + ps->levels[i].ds_divider_index = sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, sclk_in_sr); @@ -1733,6 +1791,19 @@ static int trinity_parse_power_table(struct radeon_device *rdev) power_state_offset += 2 + power_state->v2.ucNumDPMLevels; } rdev->pm.dpm.num_ps = state_array->ucNumEntries; + + /* fill in the vce power states */ + for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) { + u32 sclk; + clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx; + clock_info = (union pplib_clock_info *) + &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; + sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); + sclk |= clock_info->sumo.ucEngineClockHigh << 16; + rdev->pm.dpm.vce_states[i].sclk = sclk; + rdev->pm.dpm.vce_states[i].mclk = 0; + } + return 0; } @@ -1914,6 +1985,10 @@ int trinity_dpm_init(struct radeon_device *rdev) if (ret) return ret; + ret = r600_parse_extended_power_table(rdev); + if (ret) + return ret; + ret = trinity_parse_power_table(rdev); if (ret) return ret; @@ -2000,6 +2075,7 @@ void trinity_dpm_fini(struct radeon_device *rdev) } kfree(rdev->pm.dpm.ps); kfree(rdev->pm.dpm.priv); + r600_free_extended_power_table(rdev); } u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low)