From patchwork Mon Jan 20 05:57:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v8,1/7] drm/i915/scaler: Add and compute scaling factors From: Mitul Golani X-Patchwork-Id: 632970 Message-Id: <20250120055730.4156955-2-mitulkumar.ajitkumar.golani@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Mon, 20 Jan 2025 11:27:24 +0530 Add scaling factors to scaler_state for a particular scaler user. These factors will be used later to compute scaler prefill latency. Currently, only plane scaling factors are stored, but the same members can later be extended to store pipe scaling factors as well. --v2: - Rephrase commit message. [Ankit] - Corrects typos. [Ankit] Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display_types.h | 2 ++ drivers/gpu/drm/i915/display/skl_scaler.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 8271e50e3644..603f292996aa 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -711,6 +711,8 @@ struct intel_initial_plane_config { struct intel_scaler { u32 mode; bool in_use; + int hscale; + int vscale; }; struct intel_crtc_scaler_state { diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index a11e09a15e23..67b86f6f62fc 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -434,6 +434,9 @@ static int intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_stat return -EINVAL; } + + scaler_state->scalers[*scaler_id].hscale = hscale; + scaler_state->scalers[*scaler_id].vscale = vscale; } drm_dbg_kms(display->drm, "[CRTC:%d:%s] attached scaler id %u.%u to %s:%d\n", From patchwork Mon Jan 20 05:57:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v8,2/7] drm/i915/scaler: Use crtc_state to setup plane or pipe scaler From: Mitul Golani X-Patchwork-Id: 632971 Message-Id: <20250120055730.4156955-3-mitulkumar.ajitkumar.golani@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Mon, 20 Jan 2025 11:27:25 +0530 Pass crtc_state to intel_atomic_setup_scaler, this will help to check if pch_pfit enabled or not and also will be useful to pass scaler_state with the same which will be used later to store hscale and vscale values. -- v2: - Fix typos. (Ankit) Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/skl_scaler.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 67b86f6f62fc..12efa4008027 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -319,13 +319,15 @@ static int intel_allocate_scaler(struct intel_crtc_scaler_state *scaler_state, return -1; } -static int intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state, +static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, int num_scalers_need, struct intel_crtc *crtc, const char *name, int idx, struct intel_plane_state *plane_state, int *scaler_id) { struct intel_display *display = to_intel_display(crtc); + struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 mode; @@ -455,7 +457,7 @@ static int setup_crtc_scaler(struct intel_atomic_state *state, struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state; - return intel_atomic_setup_scaler(scaler_state, + return intel_atomic_setup_scaler(crtc_state, hweight32(scaler_state->scaler_users), crtc, "CRTC", crtc->base.base.id, NULL, &scaler_state->scaler_id); @@ -490,7 +492,7 @@ static int setup_plane_scaler(struct intel_atomic_state *state, if (IS_ERR(plane_state)) return PTR_ERR(plane_state); - return intel_atomic_setup_scaler(scaler_state, + return intel_atomic_setup_scaler(crtc_state, hweight32(scaler_state->scaler_users), crtc, "PLANE", plane->base.base.id, plane_state, &plane_state->scaler_id); From patchwork Mon Jan 20 05:57:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v8,3/7] drm/i915/scaler: Refactor max_scale computation From: Mitul Golani X-Patchwork-Id: 632972 Message-Id: <20250120055730.4156955-4-mitulkumar.ajitkumar.golani@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Mon, 20 Jan 2025 11:27:26 +0530 Refactor max scaling factor computation into a reusable function for scalers. --v2: - Add missing comment. [Ankit] Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/skl_scaler.c | 70 +++++++++++++---------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 12efa4008027..a832cdccd9fa 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -319,6 +319,44 @@ static int intel_allocate_scaler(struct intel_crtc_scaler_state *scaler_state, return -1; } +static void +calculate_max_scale(struct intel_crtc *crtc, + bool is_yuv_semiplanar, + int scaler_id, + int *max_hscale, int *max_vscale) +{ + struct intel_display *display = to_intel_display(crtc); + + /* + * FIXME: When two scalers are needed, but only one of + * them needs to downscale, we should make sure that + * the one that needs downscaling support is assigned + * as the first scaler, so we don't reject downscaling + * unnecessarily. + */ + + if (DISPLAY_VER(display) >= 14) { + /* + * On versions 14 and up, only the first + * scaler supports a vertical scaling factor + * of more than 1.0, while a horizontal + * scaling factor of 3.0 is supported. + */ + *max_hscale = 0x30000 - 1; + + if (scaler_id == 0) + *max_vscale = 0x30000 - 1; + else + *max_vscale = 0x10000; + } else if (DISPLAY_VER(display) >= 10 || !is_yuv_semiplanar) { + *max_hscale = 0x30000 - 1; + *max_vscale = 0x30000 - 1; + } else { + *max_hscale = 0x20000 - 1; + *max_vscale = 0x20000 - 1; + } +} + static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, int num_scalers_need, struct intel_crtc *crtc, const char *name, int idx, @@ -388,35 +426,9 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, const struct drm_rect *dst = &plane_state->uapi.dst; int hscale, vscale, max_vscale, max_hscale; - /* - * FIXME: When two scalers are needed, but only one of - * them needs to downscale, we should make sure that - * the one that needs downscaling support is assigned - * as the first scaler, so we don't reject downscaling - * unnecessarily. - */ - - if (DISPLAY_VER(display) >= 14) { - /* - * On versions 14 and up, only the first - * scaler supports a vertical scaling factor - * of more than 1.0, while a horizontal - * scaling factor of 3.0 is supported. - */ - max_hscale = 0x30000 - 1; - if (*scaler_id == 0) - max_vscale = 0x30000 - 1; - else - max_vscale = 0x10000; - - } else if (DISPLAY_VER(display) >= 10 || - !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) { - max_hscale = 0x30000 - 1; - max_vscale = 0x30000 - 1; - } else { - max_hscale = 0x20000 - 1; - max_vscale = 0x20000 - 1; - } + calculate_max_scale(crtc, + intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier), + *scaler_id, &max_hscale, &max_vscale); /* * FIXME: We should change the if-else block above to From patchwork Mon Jan 20 05:57:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v8,4/7] drm/i915/scaler: Compute scaling factors for pipe scaler From: Mitul Golani X-Patchwork-Id: 632973 Message-Id: <20250120055730.4156955-5-mitulkumar.ajitkumar.golani@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Mon, 20 Jan 2025 11:27:27 +0530 Compute scaling factors and scaler user for pipe scaler if particular scaler user is pipe scaler. --v2: - Fix typos. [Ankit] - Remove FIXME tag. [Ankit] - Should be common hscale, vscale instead of local one to avoid garbage overwritten. --v3: - Separate out max_scaling information. [Ankit] - Use max_hscale and max_vscale info instead of INT_MAX. [Ankit] Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/skl_scaler.c | 36 ++++++++++++++++++----- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index a832cdccd9fa..72344044d9d3 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -368,6 +368,7 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, &crtc_state->scaler_state; struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 mode; + int hscale, vscale, max_vscale, max_hscale; if (*scaler_id < 0) *scaler_id = intel_allocate_scaler(scaler_state, crtc); @@ -416,15 +417,10 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, mode = SKL_PS_SCALER_MODE_DYN; } - /* - * FIXME: we should also check the scaler factors for pfit, so - * this shouldn't be tied directly to planes. - */ if (plane_state && plane_state->hw.fb) { const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_rect *src = &plane_state->uapi.src; const struct drm_rect *dst = &plane_state->uapi.dst; - int hscale, vscale, max_vscale, max_hscale; calculate_max_scale(crtc, intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier), @@ -448,11 +444,37 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, return -EINVAL; } + } + + if (crtc_state->pch_pfit.enabled) { + struct drm_rect src; + + drm_rect_init(&src, 0, 0, + drm_rect_width(&crtc_state->pipe_src) << 16, + drm_rect_height(&crtc_state->pipe_src) << 16); + + calculate_max_scale(crtc, 0, *scaler_id, + &max_hscale, &max_vscale); - scaler_state->scalers[*scaler_id].hscale = hscale; - scaler_state->scalers[*scaler_id].vscale = vscale; + hscale = drm_rect_calc_hscale(&src, &crtc_state->pch_pfit.dst, + 0, max_hscale); + vscale = drm_rect_calc_vscale(&src, &crtc_state->pch_pfit.dst, + 0, max_vscale); + + if (hscale < 0 || vscale < 0) { + drm_dbg_kms(display->drm, + "Scaler %d doesn't support required pipe scaling\n", + *scaler_id); + drm_rect_debug_print("src: ", &src, true); + drm_rect_debug_print("dst: ", &crtc_state->pch_pfit.dst, false); + + return -EINVAL; + } } + scaler_state->scalers[*scaler_id].hscale = hscale; + scaler_state->scalers[*scaler_id].vscale = vscale; + drm_dbg_kms(display->drm, "[CRTC:%d:%s] attached scaler id %u.%u to %s:%d\n", crtc->base.base.id, crtc->base.name, crtc->pipe, *scaler_id, name, idx); From patchwork Mon Jan 20 05:57:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v8,5/7] drm/i915/scaler: Limit pipe scaler downscaling factors for YUV420 From: Mitul Golani X-Patchwork-Id: 632974 Message-Id: <20250120055730.4156955-6-mitulkumar.ajitkumar.golani@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Mon, 20 Jan 2025 11:27:28 +0530 Limit downscaling to less than 1.5 (source/destination) in the horizontal direction and 1.0 in the vertical direction, When configured for Pipe YUV 420 encoding for port output. Bspec: 50441, 7490, 69901 Signed-off-by: Mitul Golani Reviewed-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/skl_scaler.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 72344044d9d3..c9d7966b37ff 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -456,6 +456,16 @@ static int intel_atomic_setup_scaler(struct intel_crtc_state *crtc_state, calculate_max_scale(crtc, 0, *scaler_id, &max_hscale, &max_vscale); + /* + * When configured for Pipe YUV 420 encoding for port output, + * limit downscaling to less than 1.5 (source/destination) in + * the horizontal direction and 1.0 in the vertical direction. + */ + if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) { + max_hscale = 0x18000 - 1; + max_vscale = 0x10000; + } + hscale = drm_rect_calc_hscale(&src, &crtc_state->pch_pfit.dst, 0, max_hscale); vscale = drm_rect_calc_vscale(&src, &crtc_state->pch_pfit.dst, From patchwork Mon Jan 20 14:05:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v9,6/7] drm/i915/scaler: Check if vblank is sufficient for scaler From: Mitul Golani X-Patchwork-Id: 633030 Message-Id: <20250120140517.3683-1-mitulkumar.ajitkumar.golani@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Mon, 20 Jan 2025 19:35:17 +0530 High refresh rate panels which may have small line times and vblank sizes, Check if vblank size is sufficient for enabled scaler users. --v2: - Use hweight* family of functions for counting bits. [Jani] - Update precision handling for hscale and vscale. [Ankit] - Consider chroma downscaling factor during latency calculation. [Ankit] - Replace function name from scaler_prefill_time to scaler_prefill_latency. --v3: - hscale_k and vscale_k values are already left shifted by 16, after multiplying by 1000, those need to be right shifted to 16. [Ankit] - Replace YCBCR444 to YCBCR420. [Ankit] - Divide by 1000 * 1000 in end to get correct precision. [Ankit] - Initialise latency to 0 to avoid any garbage. --v4: - Elaborate commit message and add Bspec number. [Ankit] - Improvise latency calculation. [Ankit] - Use ceiling value for down scaling factor when less than 1 as per bspec. [Ankit] - Correct linetime calculation. [Ankit] - Consider cdclk prefill adjustment while prefill computation.[Ankit] --v5: - Add Bspec link in commit message trailer. [Ankit] - Correct hscale, vscale data type. - Use intel_crtc_compute_min_cdclk. [Ankit] --v6: - Update FIXME comment. - Use cdclk_state->logical.cdclk instead of intel_crtc_compute_min_cdclk. [Ankit] --v7: - Handle error return from cdclk_prefill_adjustment. [Ankit] - Avoid incorrect round off for linetime. [Ankit] - Correct precision. [Ankit] --v8: - Correct chroma_downscaling_factor redundant change. Which is leftover from previous patch. Bspec: 70151 Signed-off-by: Mitul Golani --- drivers/gpu/drm/i915/display/skl_watermark.c | 51 +++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index f4458d1185b3..3897f504192e 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -2292,6 +2292,54 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state, return 0; } +static int +cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct intel_atomic_state *state = + to_intel_atomic_state(crtc_state->uapi.state); + const struct intel_cdclk_state *cdclk_state; + + cdclk_state = intel_atomic_get_cdclk_state(state); + if (IS_ERR(cdclk_state)) { + drm_WARN_ON(display->drm, PTR_ERR(cdclk_state)); + return 1; + } + + return min(1, DIV_ROUND_UP(crtc_state->pixel_rate, + 2 * cdclk_state->logical.cdclk)); +} + +static int +scaler_prefill_latency(const struct intel_crtc_state *crtc_state) +{ + const struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; + int num_scaler_users = hweight32(scaler_state->scaler_users); + int scaler_prefill_latency = 0; + int linetime = DIV_ROUND_UP(1000 * crtc_state->hw.adjusted_mode.htotal, + crtc_state->hw.adjusted_mode.clock); + + if (!num_scaler_users) + return scaler_prefill_latency; + + scaler_prefill_latency = 4 * linetime; + + if (num_scaler_users > 1) { + u64 hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].hscale, 1000) >> 16); + u64 vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[0].vscale, 1000) >> 16); + int chroma_downscaling_factor = + crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 2 : 1; + + scaler_prefill_latency += DIV_ROUND_UP_ULL((4 * linetime * hscale_k * vscale_k * + chroma_downscaling_factor), 1000000); + } + + scaler_prefill_latency *= cdclk_prefill_adjustment(crtc_state); + + return intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, scaler_prefill_latency); +} + static bool skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state, int wm0_lines, int latency) @@ -2299,9 +2347,10 @@ skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - /* FIXME missing scaler and DSC pre-fill time */ + /* FIXME missing DSC pre-fill time */ return crtc_state->framestart_delay + intel_usecs_to_scanlines(adjusted_mode, latency) + + scaler_prefill_latency(crtc_state) + wm0_lines > adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vblank_start; } From patchwork Mon Jan 20 05:57:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v8,7/7] drm/i915/dsc: Check if vblank is sufficient for dsc prefill From: Mitul Golani X-Patchwork-Id: 632976 Message-Id: <20250120055730.4156955-8-mitulkumar.ajitkumar.golani@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Date: Mon, 20 Jan 2025 11:27:30 +0530 High refresh rate panels which may have small line times and vblank sizes, Check if vblank size is sufficient for dsc prefill latency. --v2: - Consider chroma downscaling factor in latency calculation. [Ankit] - Replace with appropriate function name. --v3: - Remove FIXME tag.[Ankit] - Replace Ycbcr444 to Ycbcr420.[Ankit] - Correct precision. [Ankit] - Use some local valiables like linetime_factor and latency to adjust precision. - Declare latency to 0 initially to avoid returning any garbage values. - Account for second scaler downscaling factor as well. [Ankit] --v4: - Improvise hscale and vscale calculation. [Ankit] - Use appropriate name for number of scaler users. [Ankit] - Update commit message and rebase. - Add linetime and cdclk prefill adjustment calculation. [Ankit] --v5: - Update bspec link in trailer. [Ankit] - Correct hscale, vscale datatype. [Ankit] - Use intel_crtc_compute_min_cdclk. [Ankit] --v6: - Use cdclk_state->logical.cdclk instead of intel_crtc_compute_min_cdclk. [Ankit] --v7: - Fix linetime calculation. [Ankit] - Reduce redandancy use of variables. [Ankit] - Fix typos. [Ankit] Bspec: 70151 Signed-off-by: Mitul Golani --- drivers/gpu/drm/i915/display/skl_watermark.c | 33 +++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index ddba823a599f..6b7f607569b7 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -2307,6 +2307,37 @@ cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state) return 1; } +static int +dsc_prefill_latency(const struct intel_crtc_state *crtc_state) +{ + const struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; + int downscale_amount = 1; + int latency = 0; + int linetime = DIV_ROUND_UP(1000 * crtc_state->hw.adjusted_mode.htotal, + crtc_state->pixel_rate); + int num_scaler_users = hweight32(scaler_state->scaler_users); + int chroma_downscaling_factor = + crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ? 2 : 1; + u64 hscale_k, vscale_k; + + if (!crtc_state->dsc.compression_enable || !num_scaler_users) + return latency; + + for (int i = 0; i < num_scaler_users; i++) { + hscale_k = max(1000, mul_u32_u32(scaler_state->scalers[i].hscale, 1000) >> 16); + vscale_k = max(1000, mul_u32_u32(scaler_state->scalers[i].vscale, 1000) >> 16); + downscale_amount *= DIV_ROUND_UP_ULL(hscale_k * vscale_k, 1000000); + } + + latency = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, + downscale_amount * + DIV_ROUND_UP(15 * linetime, 10) * + chroma_downscaling_factor); + + return latency * cdclk_prefill_adjustment(crtc_state); +} + static int scaler_prefill_latency(const struct intel_crtc_state *crtc_state) { @@ -2345,10 +2376,10 @@ skl_is_vblank_too_short(const struct intel_crtc_state *crtc_state, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - /* FIXME missing DSC pre-fill time */ return crtc_state->framestart_delay + intel_usecs_to_scanlines(adjusted_mode, latency) + scaler_prefill_latency(crtc_state) + + dsc_prefill_latency(crtc_state) + wm0_lines > adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vblank_start; }