Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp2323348pxa; Mon, 3 Aug 2020 13:12:42 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzMez5isxr7NgPuJAHLFMBj6M8dwvsgPBU4es8CWOw5uyXkurRQLSU14rLQ1QimViEZopmE X-Received: by 2002:a05:6402:1b89:: with SMTP id cc9mr17728045edb.227.1596485561987; Mon, 03 Aug 2020 13:12:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1596485561; cv=none; d=google.com; s=arc-20160816; b=P0lQkm/9eXEx6zeAAkIproG1pVMZmczsn04zVqbm/a1MI3s2Hj18EhoVupMFPImrRp vpBZt470hIoW72tOX8xj0ar5mJgVNINWem10TeZjvan5RZHtcWKJN14kWLTuD1xgVj0R EtEbJODi3QhMmIls3VD3OL22wwkhDlkgVO5rwo778FV6FLGVDCLSAXVhEwYn1NBwK2Wl YY+pnoxaMNdq7dYhngGjmmNuQ46vmOFX/MAQYvSrcBSrYiYpiwGzC5KhY0oXM9MlSQKl Uau+WyJ8XSvgcYVZANJruamHVW6aevdu8zQRb5/Oq/76n7Ek0OEyUxp/xfo3Iv8J8Zq+ yS+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=r1jd5mjQe/4Tm7Afy1JoYQkOXKIpReCTfy1TsU1XEl4=; b=oH/lxYm9S+cB7YDvfvorLUDfhtC3XXCSNQ5GFVCLYEhEHvLS9iwewTKEpal4oxwcUl Dqe1ARXeLySCPgFukQ1n6cLuyIj6slkJciy+4G56VPNbH4KqQ6MSbVtMLToL7jksr0kT GgzGNgcVPwR6JSlmQtx8eJsiQf3NAsG5pqNBpFSZtCLb1AGERQBoIf35LYGt6HX8KvDJ EiOzmWKwALSpvhhrjc4kewkcVliledceGeFRxjTlDo3CrrjFnvspuu53W04g2jKm4CNh +/ayJ29gqQ86QsXwwdcwUBCwqpM+n9EJrX8OZLUJkKl9LHaVyVY3nfvTx08fJBjZjUTS B/BA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ispras.ru Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h11si591935edr.606.2020.08.03.13.12.19; Mon, 03 Aug 2020 13:12:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ispras.ru Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726398AbgHCUJz (ORCPT + 99 others); Mon, 3 Aug 2020 16:09:55 -0400 Received: from mail.ispras.ru ([83.149.199.84]:44926 "EHLO mail.ispras.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726130AbgHCUJz (ORCPT ); Mon, 3 Aug 2020 16:09:55 -0400 X-Greylist: delayed 329 seconds by postgrey-1.27 at vger.kernel.org; Mon, 03 Aug 2020 16:09:52 EDT Received: from localhost.localdomain (unknown [46.188.10.168]) by mail.ispras.ru (Postfix) with ESMTPSA id 5060C40A206F; Mon, 3 Aug 2020 20:04:22 +0000 (UTC) From: Alexander Monakov To: amd-gfx@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, Alexander Monakov , Alex Deucher Subject: [PATCH] drm/amd/display: use correct scale for actual_brightness Date: Mon, 3 Aug 2020 23:02:18 +0300 Message-Id: <20200803200218.2167-1-amonakov@ispras.ru> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Documentation for sysfs backlight level interface requires that values in both 'brightness' and 'actual_brightness' files are interpreted to be in range from 0 to the value given in the 'max_brightness' file. With amdgpu, max_brightness gives 255, and values written by the user into 'brightness' are internally rescaled to a wider range. However, reading from 'actual_brightness' gives the raw register value without inverse rescaling. This causes issues for various userspace tools such as PowerTop and systemd that expect the value to be in the correct range. Introduce a helper to retrieve internal backlight range. Extend the existing 'convert_brightness' function to handle conversion in both directions. Bug: https://bugzilla.kernel.org/show_bug.cgi?id=203905 Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1242 Cc: Alex Deucher Signed-off-by: Alexander Monakov --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 73 ++++++++----------- 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 710edc70e37e..03e21e7b7917 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2881,51 +2881,42 @@ static int set_backlight_via_aux(struct dc_link *link, uint32_t brightness) return rc ? 0 : 1; } -static u32 convert_brightness(const struct amdgpu_dm_backlight_caps *caps, - const uint32_t user_brightness) +static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, + unsigned *min, unsigned *max) { - u32 min, max, conversion_pace; - u32 brightness = user_brightness; - if (!caps) - goto out; + return 0; - if (!caps->aux_support) { - max = caps->max_input_signal; - min = caps->min_input_signal; - /* - * The brightness input is in the range 0-255 - * It needs to be rescaled to be between the - * requested min and max input signal - * It also needs to be scaled up by 0x101 to - * match the DC interface which has a range of - * 0 to 0xffff - */ - conversion_pace = 0x101; - brightness = - user_brightness - * conversion_pace - * (max - min) - / AMDGPU_MAX_BL_LEVEL - + min * conversion_pace; + if (caps->aux_support) { + // Firmware limits are in nits, DC API wants millinits. + *max = 1000 * caps->aux_max_input_signal; + *min = 1000 * caps->aux_min_input_signal; } else { - /* TODO - * We are doing a linear interpolation here, which is OK but - * does not provide the optimal result. We probably want - * something close to the Perceptual Quantizer (PQ) curve. - */ - max = caps->aux_max_input_signal; - min = caps->aux_min_input_signal; - - brightness = (AMDGPU_MAX_BL_LEVEL - user_brightness) * min - + user_brightness * max; - // Multiple the value by 1000 since we use millinits - brightness *= 1000; - brightness = DIV_ROUND_CLOSEST(brightness, AMDGPU_MAX_BL_LEVEL); + // Firmware limits are 8-bit, PWM control is 16-bit. + *max = 0x101 * caps->max_input_signal; + *min = 0x101 * caps->min_input_signal; } + return 1; +} -out: - return brightness; +static u32 convert_brightness(const struct amdgpu_dm_backlight_caps *caps, + const uint32_t brightness, int from_user) +{ + unsigned min, max; + + if (!get_brightness_range(caps, &min, &max)) + return brightness; + + if (from_user) + // Rescale 0..255 to min..max + return min + DIV_ROUND_CLOSEST((max - min) * brightness, + AMDGPU_MAX_BL_LEVEL); + + if (brightness < min) + return 0; + // Rescale min..max to 0..255 + return DIV_ROUND_CLOSEST(AMDGPU_MAX_BL_LEVEL * (brightness - min), + max - min); } static int amdgpu_dm_backlight_update_status(struct backlight_device *bd) @@ -2941,7 +2932,7 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd) link = (struct dc_link *)dm->backlight_link; - brightness = convert_brightness(&caps, bd->props.brightness); + brightness = convert_brightness(&caps, bd->props.brightness, 1); // Change brightness based on AUX property if (caps.aux_support) return set_backlight_via_aux(link, brightness); @@ -2958,7 +2949,7 @@ static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd) if (ret == DC_ERROR_UNEXPECTED) return bd->props.brightness; - return ret; + return convert_brightness(&dm->backlight_caps, ret, 0); } static const struct backlight_ops amdgpu_dm_backlight_ops = { base-commit: bcf876870b95592b52519ed4aafcf9d95999bc9c -- 2.26.2