From: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: ville.syrjala@intel.com
Subject: [Intel-gfx] [RFC 1/1] drm/i915/display: Update vtotal based on closest possible panel timings
Date: Fri, 24 Nov 2023 00:30:24 +0530 [thread overview]
Message-ID: <20231123190024.34455-2-mitulkumar.ajitkumar.golani@intel.com> (raw)
In-Reply-To: <20231123190024.34455-1-mitulkumar.ajitkumar.golani@intel.com>
For edp VRR supported panel, vtotal should be updated
based on closest available panel timings and adjusted_mode
panel configuration, instead of rounding up to nearest possible
integer. This is to facilitate user about the refreh rate
they're going to get when it is slightly off from list of available modes.
Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
---
drivers/gpu/drm/i915/display/intel_panel.c | 53 ++++++++++++++++++----
drivers/gpu/drm/i915/display/intel_vrr.h | 2 +
2 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index 0d8e5320a4f8..f53cea2d7b29 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -197,26 +197,56 @@ enum drrs_type intel_panel_drrs_type(struct intel_connector *connector)
return connector->panel.vbt.drrs_type;
}
+static int
+mode_vrefresh_k(const struct drm_display_mode *mode)
+{
+ unsigned int num, den;
+
+ if (mode->htotal == 0 || mode->vtotal == 0)
+ return 0;
+
+ num = mode->clock;
+ den = mode->htotal * mode->vtotal;
+
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ num *= 2;
+ if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+ den *= 2;
+ if (mode->vscan > 1)
+ den *= mode->vscan;
+
+ return mul_u64_u64_div_u64(num,
+ 1000 * FIXED_POINT_PRECISION,
+ den);
+}
+
int intel_panel_compute_config(struct intel_connector *connector,
struct drm_display_mode *adjusted_mode)
{
const struct drm_display_mode *fixed_mode =
intel_panel_fixed_mode(connector, adjusted_mode);
- int vrefresh, fixed_mode_vrefresh;
+ int vrefresh_int, vrefresh_fraction;
+ int fixed_mode_vrefresh_int;
+ int vrefresh_k = mode_vrefresh_k(adjusted_mode);
+ int fixed_mode_vrefresh_k = mode_vrefresh_k(fixed_mode);
bool is_vrr;
if (!fixed_mode)
return 0;
- vrefresh = drm_mode_vrefresh(adjusted_mode);
- fixed_mode_vrefresh = drm_mode_vrefresh(fixed_mode);
+ vrefresh_int = vrefresh_k / FIXED_POINT_PRECISION;
+ vrefresh_fraction = do_div(vrefresh_k, FIXED_POINT_PRECISION);
+ fixed_mode_vrefresh_int = fixed_mode_vrefresh_k / FIXED_POINT_PRECISION;
/*
* Assume that we shouldn't muck about with the
* timings if they don't land in the VRR range.
*/
- is_vrr = intel_vrr_is_in_range(connector, vrefresh) &&
- intel_vrr_is_in_range(connector, fixed_mode_vrefresh);
+ is_vrr =
+ intel_vrr_is_in_range(connector,
+ drm_mode_vrefresh(adjusted_mode)) &&
+ intel_vrr_is_in_range(connector,
+ drm_mode_vrefresh(fixed_mode));
if (!is_vrr) {
/*
@@ -225,11 +255,12 @@ int intel_panel_compute_config(struct intel_connector *connector,
* for Xorg since it likes to automagically cook up modes with slightly
* off refresh rates.
*/
- if (abs(vrefresh - fixed_mode_vrefresh) > 1) {
+ if (abs(vrefresh_int - fixed_mode_vrefresh_int) > 1) {
drm_dbg_kms(connector->base.dev,
"[CONNECTOR:%d:%s] Requested mode vrefresh (%d Hz) does not match fixed mode vrefresh (%d Hz)\n",
connector->base.base.id, connector->base.name,
- vrefresh, fixed_mode_vrefresh);
+ DIV_ROUND_UP(vrefresh_k, 1000),
+ DIV_ROUND_UP(fixed_mode_vrefresh_k, 1000));
return -EINVAL;
}
@@ -237,10 +268,12 @@ int intel_panel_compute_config(struct intel_connector *connector,
drm_mode_copy(adjusted_mode, fixed_mode);
- if (is_vrr && fixed_mode_vrefresh != vrefresh)
+ if (is_vrr && fixed_mode_vrefresh_k != vrefresh_k)
adjusted_mode->vtotal =
- DIV_ROUND_CLOSEST(adjusted_mode->clock * 1000,
- adjusted_mode->htotal * vrefresh);
+ mul_u64_u32_div(adjusted_mode->clock * 1000,
+ FIXED_POINT_PRECISION,
+ adjusted_mode->htotal *
+ (vrefresh_int * FIXED_POINT_PRECISION + vrefresh_fraction));
drm_mode_set_crtcinfo(adjusted_mode, 0);
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h
index 89937858200d..4bfabaac9ac8 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.h
+++ b/drivers/gpu/drm/i915/display/intel_vrr.h
@@ -13,6 +13,8 @@ struct intel_atomic_state;
struct intel_connector;
struct intel_crtc_state;
+#define FIXED_POINT_PRECISION 100
+
bool intel_vrr_is_capable(struct intel_connector *connector);
bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh);
void intel_vrr_check_modeset(struct intel_atomic_state *state);
--
2.25.1
next prev parent reply other threads:[~2023-11-23 19:05 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-23 19:00 [Intel-gfx] [RFC 0/1] Update vtotal based on closest possible panel timings Mitul Golani
2023-11-23 19:00 ` Mitul Golani [this message]
2023-11-23 21:23 ` [Intel-gfx] ✗ Fi.CI.BAT: failure for " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231123190024.34455-2-mitulkumar.ajitkumar.golani@intel.com \
--to=mitulkumar.ajitkumar.golani@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=ville.syrjala@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox