/* * We can only enable IPS after we enable a plane and wait for a vblank * This function is called from post_plane_update, which is run after * a vblank wait.
*/
drm_WARN_ON(display->drm,
!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
val = IPS_ENABLE;
if (display->ips.false_color)
val |= IPS_FALSE_COLOR;
if (display->platform.broadwell) {
drm_WARN_ON(display->drm,
intel_pcode_write(display->drm, DISPLAY_IPS_CONTROL,
val | IPS_PCODE_CONTROL)); /* * Quoting Art Runyan: "its not safe to expect any particular * value in IPS_CTL bit 31 after enabling IPS through the * mailbox." Moreover, the mailbox may return a bogus state, * so we need to just enable it and continue on.
*/
} else {
intel_de_write(display, IPS_CTL, val); /* * The bit only becomes 1 in the next vblank, so this wait here * is essentially intel_wait_for_vblank. If we don't have this * and don't wait for vblanks until the end of crtc_enable, then * the HW state readout code will complain that the expected * IPS_CTL value is not the one we read.
*/ if (intel_de_wait_for_set(display, IPS_CTL, IPS_ENABLE, 50))
drm_err(display->drm, "Timed out waiting for IPS enable\n");
}
}
if (!crtc_state->ips_enabled) return need_vblank_wait;
if (display->platform.broadwell) {
drm_WARN_ON(display->drm,
intel_pcode_write(display->drm, DISPLAY_IPS_CONTROL, 0)); /* * Wait for PCODE to finish disabling IPS. The BSpec specified * 42ms timeout value leads to occasional timeouts so use 100ms * instead.
*/ if (intel_de_wait_for_clear(display, IPS_CTL, IPS_ENABLE, 100))
drm_err(display->drm, "Timed out waiting for IPS disable\n");
} else {
intel_de_write(display, IPS_CTL, 0);
intel_de_posting_read(display, IPS_CTL);
}
/* We need to wait for a vblank before we can disable the plane. */
need_vblank_wait = true;
if (intel_crtc_needs_modeset(new_crtc_state)) returntrue;
/* * Workaround : Do not read or write the pipe palette/gamma data while * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. * * Disable IPS before we program the LUT.
*/ if (display->platform.haswell &&
intel_crtc_needs_color_update(new_crtc_state) &&
new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) returntrue;
if (intel_crtc_needs_modeset(new_crtc_state)) returntrue;
/* * Workaround : Do not read or write the pipe palette/gamma data while * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. * * Re-enable IPS after the LUT has been programmed.
*/ if (display->platform.haswell &&
intel_crtc_needs_color_update(new_crtc_state) &&
new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) returntrue;
/* * We can't read out IPS on broadwell, assume the worst and * forcibly enable IPS on the first fastset.
*/ if (intel_crtc_needs_fastset(new_crtc_state) && old_crtc_state->inherited) returntrue;
/* IPS only exists on ULT machines and is tied to pipe A. */ bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
{ struct intel_display *display = to_intel_display(crtc);
/* IPS only exists on ULT machines and is tied to pipe A. */ if (!hsw_crtc_supports_ips(crtc)) returnfalse;
if (!display->params.enable_ips) returnfalse;
if (crtc_state->pipe_bpp > 24) returnfalse;
/* * We compare against max which means we must take * the increased cdclk requirement into account when * calculating the new cdclk. * * Should measure whether using a lower cdclk w/o IPS
*/ if (display->platform.broadwell &&
crtc_state->pixel_rate > display->cdclk.max_cdclk_freq * 95 / 100) returnfalse;
returntrue;
}
int hsw_ips_min_cdclk(conststruct intel_crtc_state *crtc_state)
{ struct intel_display *display = to_intel_display(crtc_state);
if (!display->platform.broadwell) return 0;
if (!hsw_crtc_state_ips_capable(crtc_state)) return 0;
/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ return DIV_ROUND_UP(crtc_state->pixel_rate * 100, 95);
}
if (!hsw_crtc_state_ips_capable(crtc_state)) return 0;
/* * When IPS gets enabled, the pipe CRC changes. Since IPS gets * enabled and disabled dynamically based on package C states, * user space can't make reliable use of the CRCs, so let's just * completely disable it.
*/ if (crtc_state->crc_enabled) return 0;
/* IPS should be fine as long as at least one plane is enabled. */ if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR))) return 0;
if (display->platform.broadwell) { conststruct intel_cdclk_state *cdclk_state;
cdclk_state = intel_atomic_get_cdclk_state(state); if (IS_ERR(cdclk_state)) return PTR_ERR(cdclk_state);
/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ if (crtc_state->pixel_rate > intel_cdclk_logical(cdclk_state) * 95 / 100) return 0;
}
if (display->platform.haswell) {
crtc_state->ips_enabled = intel_de_read(display, IPS_CTL) & IPS_ENABLE;
} else { /* * We cannot readout IPS state on broadwell, set to * true so we can set it to a defined state on first * commit.
*/
crtc_state->ips_enabled = true;
}
}
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.