staticbool is_best_fixed_mode(struct intel_connector *connector, int vrefresh, int fixed_mode_vrefresh, conststruct drm_display_mode *best_mode)
{ /* we want to always return something */ if (!best_mode) returntrue;
/* * With VRR always pick a mode with equal/higher than requested * vrefresh, which we can then reduce to match the requested * vrefresh by extending the vblank length.
*/ if (intel_vrr_is_in_range(connector, vrefresh) &&
intel_vrr_is_in_range(connector, fixed_mode_vrefresh) &&
fixed_mode_vrefresh < vrefresh) returnfalse;
/* pick the fixed_mode that is closest in terms of vrefresh */ return abs(fixed_mode_vrefresh - vrefresh) <
abs(drm_mode_vrefresh(best_mode) - vrefresh);
}
/* pick the fixed_mode with the lowest refresh rate */
list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) { int vrefresh = drm_mode_vrefresh(fixed_mode);
/* pick the fixed_mode that has the highest clock */
list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) { if (fixed_mode->clock > best_mode->clock)
best_mode = fixed_mode;
}
return best_mode;
}
int intel_panel_get_modes(struct intel_connector *connector)
{ conststruct drm_display_mode *fixed_mode; int num_modes = 0;
/* * 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);
if (!is_vrr) { /* * We don't want to lie too much to the user about the refresh * rate they're going to get. But we have to allow a bit of latitude * for Xorg since it likes to automagically cook up modes with slightly * off refresh rates.
*/ if (abs(vrefresh - fixed_mode_vrefresh) > 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);
if (list_empty(&connector->base.probed_modes)) return;
/* make sure the preferred mode is first */
list_for_each_entry(scan, &connector->base.probed_modes, head) { if (scan->type & DRM_MODE_TYPE_PREFERRED) {
fixed_mode = scan; break;
}
}
if (!fixed_mode)
fixed_mode = list_first_entry(&connector->base.probed_modes,
typeof(*fixed_mode), head);
/* * If the panel was already enabled at probe, and we took over the state, the * panel prepared state is out of sync, and the panel followers won't be * notified. We need to call drm_panel_prepare() on enabled panels. * * It would be natural to handle this e.g. in the connector ->sync_state hook at * intel_modeset_readout_hw_state(), but that's unfortunately too early. We * don't have drm_connector::kdev at that time. For now, figure out the state at * ->late_register, and sync there.
*/ staticvoid intel_panel_sync_state(struct intel_connector *connector)
{ struct intel_display *display = to_intel_display(connector); struct drm_connector_state *conn_state; struct intel_crtc *crtc; int ret;
ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex, NULL); if (ret) return;
conn_state = connector->base.state;
crtc = to_intel_crtc(conn_state->crtc); if (crtc) { struct intel_crtc_state *crtc_state;
/* Sanity check. */ if (drm_WARN_ON(display->drm, !dev)) goto out;
/* * We need drm_connector::kdev for allocating the panel, to make * drm_panel_add_follower() lookups work. The kdev is * initialized in drm_sysfs_connector_add(), just before the * connector .late_register() hooks. So we can't allocate the * panel at connector init time, and can't allocate struct * intel_panel with a drm_panel sub-struct. For now, use * __devm_drm_panel_alloc() directly. * * The lookups also depend on drm_connector::fwnode being set in * intel_acpi_assign_connector_fwnodes(). However, if that's * missing, it will gracefully lead to -EPROBE_DEFER in * drm_panel_add_follower().
*/
base = __devm_drm_panel_alloc(dev, sizeof(*base), 0,
&dummy_panel_funcs,
connector->base.connector_type); if (IS_ERR(base)) {
ret = PTR_ERR(base); goto err;
}
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.