/* * DP Sink is capable of VRR video timings if * Ignore MSA bit is set in DPCD. * EDID monitor range also should be atleast 10 for reasonable * Adaptive Sync or Variable Refresh Rate end user experience.
*/ switch (connector->base.connector_type) { case DRM_MODE_CONNECTOR_eDP: if (!connector->panel.vbt.vrr) returnfalse;
fallthrough; case DRM_MODE_CONNECTOR_DisplayPort: if (connector->mst.dp) returnfalse;
intel_dp = intel_attached_dp(connector);
if (!drm_dp_sink_can_do_video_without_timing_msa(intel_dp->dpcd)) returnfalse;
staticint intel_vrr_extra_vblank_delay(struct intel_display *display)
{ /* * On ICL/TGL VRR hardware inserts one extra scanline * just after vactive, which pushes the vmin decision * boundary ahead accordingly. We'll include the extra * scanline in our vblank delay estimates to make sure * that we never underestimate how long we have until * the delayed vblank has passed.
*/ return DISPLAY_VER(display) < 13 ? 1 : 0;
}
int intel_vrr_vblank_delay(conststruct intel_crtc_state *crtc_state)
{ struct intel_display *display = to_intel_display(crtc_state);
/* * Without VRR registers get latched at: * vblank_start * * With VRR the earliest registers can get latched is: * intel_vrr_vmin_vblank_start(), which if we want to maintain * the correct min vtotal is >=vblank_start+1 * * The latest point registers can get latched is the vmax decision boundary: * intel_vrr_vmax_vblank_start() * * Between those two points the vblank exit starts (and hence registers get * latched) ASAP after a push is sent. * * framestart_delay is programmable 1-4.
*/ staticint intel_vrr_vblank_exit_length(conststruct intel_crtc_state *crtc_state)
{ struct intel_display *display = to_intel_display(crtc_state);
if (DISPLAY_VER(display) >= 13) return crtc_state->vrr.guardband; else /* hardware imposes one extra scanline somewhere */ return crtc_state->vrr.pipeline_full + crtc_state->framestart_delay + 1;
}
int intel_vrr_vmin_vtotal(conststruct intel_crtc_state *crtc_state)
{ struct intel_display *display = to_intel_display(crtc_state);
/* Min vblank actually determined by flipline */ if (DISPLAY_VER(display) >= 13) return intel_vrr_vmin_flipline(crtc_state); else return intel_vrr_vmin_flipline(crtc_state) +
intel_vrr_real_vblank_delay(crtc_state);
}
int intel_vrr_vmax_vtotal(conststruct intel_crtc_state *crtc_state)
{ struct intel_display *display = to_intel_display(crtc_state);
static void intel_vrr_compute_cmrr_timings(struct intel_crtc_state *crtc_state)
{
crtc_state->cmrr.enable = true; /* * TODO: Compute precise target refresh rate to determine * if video_mode_required should be true. Currently set to * false due to uncertainty about the precise target * refresh Rate.
*/
crtc_state->vrr.vmax = cmrr_get_vtotal(crtc_state, false);
crtc_state->vrr.vmin = crtc_state->vrr.vmax;
crtc_state->vrr.flipline = crtc_state->vrr.vmin;
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
}
/* * For fixed refresh rate mode Vmin, Vmax and Flipline all are set to * Vtotal value.
*/ static int intel_vrr_fixed_rr_vtotal(conststruct intel_crtc_state *crtc_state)
{ struct intel_display *display = to_intel_display(crtc_state); int crtc_vtotal = crtc_state->hw.adjusted_mode.crtc_vtotal;
static void intel_vrr_compute_fixed_rr_timings(struct intel_crtc_state *crtc_state)
{ /* * For fixed rr, vmin = vmax = flipline. * vmin is already set to crtc_vtotal set vmax and flipline the same.
*/
crtc_state->vrr.vmax = crtc_state->hw.adjusted_mode.crtc_vtotal;
crtc_state->vrr.flipline = crtc_state->hw.adjusted_mode.crtc_vtotal;
}
static int intel_vrr_compute_vmin(struct intel_crtc_state *crtc_state)
{ /* * To make fixed rr and vrr work seamless the guardband/pipeline full * should be set such that it satisfies both the fixed and variable * timings. * For this set the vmin as crtc_vtotal. With this we never need to * change anything to do with the guardband.
*/ return crtc_state->hw.adjusted_mode.crtc_vtotal;
}
static int intel_vrr_compute_vmax(struct intel_connector *connector, conststruct drm_display_mode *adjusted_mode)
{ conststruct drm_display_info *info = &connector->base.display_info; int vmax;
/* * Allow fixed refresh rate with VRR Timing Generator. * For now set the vrr.in_range to 0, to allow fixed_rr but skip actual * VRR and LRR. * #TODO For actual VRR with joiner, we need to figure out how to * correctly sequence transcoder level stuff vs. pipe level stuff * in the commit.
*/ if (crtc_state->joiner_pipes)
crtc_state->vrr.in_range = false;
vmin = intel_vrr_compute_vmin(crtc_state);
if (crtc_state->vrr.in_range) { if (HAS_LRR(display))
crtc_state->update_lrr = true;
vmax = intel_vrr_compute_vmax(connector, adjusted_mode);
} else {
vmax = vmin;
}
/* * flipline determines the min vblank length the hardware will * generate, and on ICL/TGL flipline>=vmin+1, hence we reduce * vmin by one to make sure we can get the actual min vblank length.
*/
crtc_state->vrr.vmin -= intel_vrr_flipline_offset(display);
/* * vmin/vmax/flipline also need to be adjusted by * the vblank delay to maintain correct vtotals.
*/
crtc_state->vrr.vmin -= intel_vrr_real_vblank_delay(crtc_state);
crtc_state->vrr.vmax -= intel_vrr_real_vblank_delay(crtc_state);
crtc_state->vrr.flipline -= intel_vrr_real_vblank_delay(crtc_state);
}
}
/* * This bit seems to have two meanings depending on the platform: * TGL: generate VRR "safe window" for DSB vblank waits * ADL/DG2: make TRANS_SET_CONTEXT_LATENCY effective with VRR
*/ if (IS_DISPLAY_VER(display, 12, 13))
intel_de_rmw(display, CHICKEN_TRANS(display, cpu_transcoder),
0, PIPE_VBLANK_WITH_DELAY);
if (!intel_vrr_possible(crtc_state)) {
intel_de_write(display,
TRANS_VRR_CTL(display, cpu_transcoder), 0); return;
}
/* * Make sure the push send bit has cleared. This should * already be the case as long as the caller makes sure * this is called after the delayed vblank has occurred.
*/ if (dsb) { int wait_us, count;
wait_us = 2;
count = 1;
/* * If the bit hasn't cleared the DSB will * raise the poll error interrupt.
*/
intel_dsb_poll(dsb, TRANS_PUSH(display, cpu_transcoder),
TRANS_PUSH_SEND, 0, wait_us, count);
} else { if (intel_vrr_is_push_sent(crtc_state))
drm_err(display->drm, "[CRTC:%d:%s] VRR push send still pending\n",
crtc->base.base.id, crtc->base.name);
}
}
/* * For BMG and LNL+ onwards the EMP_AS_SDP_TL is used for programming * double buffering point and transmission line for VRR packets for * HDMI2.1/DP/eDP/DP->HDMI2.1 PCON. * Since currently we support VRR only for DP/eDP, so this is programmed * to for Adaptive Sync SDP to Vsync start.
*/ if (DISPLAY_VERx100(display) == 1401 || DISPLAY_VER(display) >= 20)
intel_de_write(display,
EMP_AS_SDP_TL(display, cpu_transcoder),
EMP_AS_SDP_DB_TL(crtc_state->vrr.vsync_start));
}
/* * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal * bits are not filled. Since for these platforms TRAN_VMIN is always * filled with crtc_vtotal, use TRAN_VRR_VMIN to get the vtotal for * adjusted_mode.
*/ if (intel_vrr_always_use_vrr_tg(display))
crtc_state->hw.adjusted_mode.crtc_vtotal =
intel_vrr_vmin_vtotal(crtc_state);
/* * #TODO: For Both VRR and CMRR the flag I915_MODE_FLAG_VRR is set for mode_flags. * Since CMRR is currently disabled, set this flag for VRR for now. * Need to keep this in mind while re-enabling CMRR.
*/ if (crtc_state->vrr.enable)
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.