From patchwork Thu Jan 2 16:12:26 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maarten Lankhorst X-Patchwork-Id: 3425781 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6B7259F2E9 for ; Thu, 2 Jan 2014 16:13:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B016A20158 for ; Thu, 2 Jan 2014 16:13:09 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id E62DF2014A for ; Thu, 2 Jan 2014 16:13:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DDA0AFAA9B for ; Thu, 2 Jan 2014 08:13:07 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from youngberry.canonical.com (youngberry.canonical.com [91.189.89.112]) by gabe.freedesktop.org (Postfix) with ESMTP id 34424FA338; Thu, 2 Jan 2014 08:12:53 -0800 (PST) Received: from 5ed49945.cm-7-5c.dynamic.ziggo.nl ([94.212.153.69] helo=[192.168.1.128]) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1Vykt7-00022c-Ei; Thu, 02 Jan 2014 16:12:51 +0000 Message-ID: <52C58FEA.7080702@canonical.com> Date: Thu, 02 Jan 2014 17:12:26 +0100 From: Maarten Lankhorst User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: Ben Skeggs Subject: [PATCH] drm/nvc0-: Fix voltage obtained from vbios. X-Enigmail-Version: 1.5.2 Cc: "nouveau@lists.freedesktop.org" , "dri-devel@lists.freedesktop.org" X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Coefficients are based on the formula: uV = 0.1 * arg[0] + 150.5 * arg[1] + 22.65025 * arg[2] It seems to be rounded downwards. I have no idea why the voltage isn't specified in the bios directly. Signed-off-by: Maarten Lankhorst ---- diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c b/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c index f343a1b060e8..0a18f9496103 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c @@ -87,14 +87,25 @@ nvbios_vmap_entry_parse(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len, u16 vmap = nvbios_vmap_entry(bios, idx, ver, len); memset(info, 0x00, sizeof(*info)); switch (!!vmap * *ver) { - case 0x10: + case 0x10: { + s32 accum, b, c; + info->link = 0xff; info->min = nv_ro32(bios, vmap + 0x00); info->max = nv_ro32(bios, vmap + 0x04); - info->arg[0] = nv_ro32(bios, vmap + 0x08); - info->arg[1] = nv_ro32(bios, vmap + 0x0c); - info->arg[2] = nv_ro32(bios, vmap + 0x10); + + accum = nv_ro32(bios, vmap + 0x08); + b = nv_ro32(bios, vmap + 0x0c); + c = nv_ro32(bios, vmap + 0x10); + + accum += b * 1505; + accum += (c * 453 / 2) + c / 400; + accum /= 10; + + if (accum > info->min) + info->min = min((u32)accum, info->max); break; + } case 0x20: info->unk0 = nv_ro08(bios, vmap + 0x00); info->link = nv_ro08(bios, vmap + 0x01); diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c b/drivers/gpu/drm/nouveau/core/subdev/volt/base.c index 32794a999106..7bf716b048bd 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/volt/base.c @@ -50,12 +50,23 @@ nouveau_volt_set(struct nouveau_volt *volt, u32 uv) { if (volt->vid_set) { int i, ret = -EINVAL; + u32 best_uv = INT_MAX, best_vid = 0; + for (i = 0; i < volt->vid_nr; i++) { - if (volt->vid[i].uv == uv) { - ret = volt->vid_set(volt, volt->vid[i].vid); - nv_debug(volt, "set %duv: %d\n", uv, ret); + s32 delta = volt->vid[i].uv - uv; + + if (delta < 0 || best_uv < volt->vid[i].uv) + continue; + + best_uv = volt->vid[i].uv; + best_vid = volt->vid[i].vid; + if (!delta) break; - } + } + + if (best_uv < INT_MAX) { + ret = volt->vid_set(volt, best_vid); + nv_debug(volt, "set %duv from %duv: %d\n", best_uv, uv, ret); } return ret; }