Merge tag 'drm-intel-fixes-2013-09-19' of git://people.freedesktop.org/~danvet/drm-intel into drm-fixes
Some more dealock fixes around pageflips and gpu hangs, fixes for hsw hangs when doing modesets/dpms. And a few minor things to rectify issues with our modeset state tracking which the checker spotted. * tag 'drm-intel-fixes-2013-09-19' of git://people.freedesktop.org/~danvet/drm-intel: drm/i915: Don't enable the cursor on a disable pipe drm/i915: do not update cursor in crtc mode set drm/i915: kill set_need_resched drm/i915/dvo: set crtc timings again for panel fixed modes drm/i915/sdvo: Robustify the dtd<->drm_mode conversions drm/i915/sdvo: Fully translate sync flags in the dtd->mode conversion drm/i915: Use proper print format for debug prints drm/i915: fix wait_for_pending_flips vs gpu hang deadlock drm/i915: Track pfit enable state separately from size
This commit is contained in:
Коммит
8e1f80c01a
|
@ -1390,14 +1390,11 @@ out:
|
|||
if (i915_terminally_wedged(&dev_priv->gpu_error))
|
||||
return VM_FAULT_SIGBUS;
|
||||
case -EAGAIN:
|
||||
/* Give the error handler a chance to run and move the
|
||||
* objects off the GPU active list. Next time we service the
|
||||
* fault, we should be able to transition the page into the
|
||||
* GTT without touching the GPU (and so avoid further
|
||||
* EIO/EGAIN). If the GPU is wedged, then there is no issue
|
||||
* with coherency, just lost writes.
|
||||
/*
|
||||
* EAGAIN means the gpu is hung and we'll wait for the error
|
||||
* handler to reset everything when re-faulting in
|
||||
* i915_mutex_lock_interruptible.
|
||||
*/
|
||||
set_need_resched();
|
||||
case 0:
|
||||
case -ERESTARTSYS:
|
||||
case -EINTR:
|
||||
|
|
|
@ -1469,6 +1469,34 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void i915_error_wake_up(struct drm_i915_private *dev_priv,
|
||||
bool reset_completed)
|
||||
{
|
||||
struct intel_ring_buffer *ring;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Notify all waiters for GPU completion events that reset state has
|
||||
* been changed, and that they need to restart their wait after
|
||||
* checking for potential errors (and bail out to drop locks if there is
|
||||
* a gpu reset pending so that i915_error_work_func can acquire them).
|
||||
*/
|
||||
|
||||
/* Wake up __wait_seqno, potentially holding dev->struct_mutex. */
|
||||
for_each_ring(ring, dev_priv, i)
|
||||
wake_up_all(&ring->irq_queue);
|
||||
|
||||
/* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */
|
||||
wake_up_all(&dev_priv->pending_flip_queue);
|
||||
|
||||
/*
|
||||
* Signal tasks blocked in i915_gem_wait_for_error that the pending
|
||||
* reset state is cleared.
|
||||
*/
|
||||
if (reset_completed)
|
||||
wake_up_all(&dev_priv->gpu_error.reset_queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* i915_error_work_func - do process context error handling work
|
||||
* @work: work struct
|
||||
|
@ -1483,11 +1511,10 @@ static void i915_error_work_func(struct work_struct *work)
|
|||
drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t,
|
||||
gpu_error);
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
struct intel_ring_buffer *ring;
|
||||
char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
|
||||
char *reset_event[] = { I915_RESET_UEVENT "=1", NULL };
|
||||
char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL };
|
||||
int i, ret;
|
||||
int ret;
|
||||
|
||||
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
|
||||
|
||||
|
@ -1506,8 +1533,16 @@ static void i915_error_work_func(struct work_struct *work)
|
|||
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE,
|
||||
reset_event);
|
||||
|
||||
/*
|
||||
* All state reset _must_ be completed before we update the
|
||||
* reset counter, for otherwise waiters might miss the reset
|
||||
* pending state and not properly drop locks, resulting in
|
||||
* deadlocks with the reset work.
|
||||
*/
|
||||
ret = i915_reset(dev);
|
||||
|
||||
intel_display_handle_reset(dev);
|
||||
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* After all the gem state is reset, increment the reset
|
||||
|
@ -1528,12 +1563,11 @@ static void i915_error_work_func(struct work_struct *work)
|
|||
atomic_set(&error->reset_counter, I915_WEDGED);
|
||||
}
|
||||
|
||||
for_each_ring(ring, dev_priv, i)
|
||||
wake_up_all(&ring->irq_queue);
|
||||
|
||||
intel_display_handle_reset(dev);
|
||||
|
||||
wake_up_all(&dev_priv->gpu_error.reset_queue);
|
||||
/*
|
||||
* Note: The wake_up also serves as a memory barrier so that
|
||||
* waiters see the update value of the reset counter atomic_t.
|
||||
*/
|
||||
i915_error_wake_up(dev_priv, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1642,8 +1676,6 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
|
|||
void i915_handle_error(struct drm_device *dev, bool wedged)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_ring_buffer *ring;
|
||||
int i;
|
||||
|
||||
i915_capture_error_state(dev);
|
||||
i915_report_and_clear_eir(dev);
|
||||
|
@ -1653,11 +1685,19 @@ void i915_handle_error(struct drm_device *dev, bool wedged)
|
|||
&dev_priv->gpu_error.reset_counter);
|
||||
|
||||
/*
|
||||
* Wakeup waiting processes so that the reset work item
|
||||
* doesn't deadlock trying to grab various locks.
|
||||
* Wakeup waiting processes so that the reset work function
|
||||
* i915_error_work_func doesn't deadlock trying to grab various
|
||||
* locks. By bumping the reset counter first, the woken
|
||||
* processes will see a reset in progress and back off,
|
||||
* releasing their locks and then wait for the reset completion.
|
||||
* We must do this for _all_ gpu waiters that might hold locks
|
||||
* that the reset work needs to acquire.
|
||||
*
|
||||
* Note: The wake_up serves as the required memory barrier to
|
||||
* ensure that the waiters see the updated value of the reset
|
||||
* counter atomic_t.
|
||||
*/
|
||||
for_each_ring(ring, dev_priv, i)
|
||||
wake_up_all(&ring->irq_queue);
|
||||
i915_error_wake_up(dev_priv, false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -778,7 +778,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
|
|||
/* Can only use the always-on power well for eDP when
|
||||
* not using the panel fitter, and when not using motion
|
||||
* blur mitigation (which we don't support). */
|
||||
if (intel_crtc->config.pch_pfit.size)
|
||||
if (intel_crtc->config.pch_pfit.enabled)
|
||||
temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
|
||||
else
|
||||
temp |= TRANS_DDI_EDP_INPUT_A_ON;
|
||||
|
|
|
@ -2249,7 +2249,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
|||
I915_WRITE(PIPESRC(intel_crtc->pipe),
|
||||
((crtc->mode.hdisplay - 1) << 16) |
|
||||
(crtc->mode.vdisplay - 1));
|
||||
if (!intel_crtc->config.pch_pfit.size &&
|
||||
if (!intel_crtc->config.pch_pfit.enabled &&
|
||||
(intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
|
||||
intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
|
||||
I915_WRITE(PF_CTL(intel_crtc->pipe), 0);
|
||||
|
@ -3203,7 +3203,7 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
|
|||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe = crtc->pipe;
|
||||
|
||||
if (crtc->config.pch_pfit.size) {
|
||||
if (crtc->config.pch_pfit.enabled) {
|
||||
/* Force use of hard-coded filter coefficients
|
||||
* as some pre-programmed values are broken,
|
||||
* e.g. x201.
|
||||
|
@ -3428,7 +3428,7 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc)
|
|||
|
||||
/* To avoid upsetting the power well on haswell only disable the pfit if
|
||||
* it's in use. The hw state code will make sure we get this right. */
|
||||
if (crtc->config.pch_pfit.size) {
|
||||
if (crtc->config.pch_pfit.enabled) {
|
||||
I915_WRITE(PF_CTL(pipe), 0);
|
||||
I915_WRITE(PF_WIN_POS(pipe), 0);
|
||||
I915_WRITE(PF_WIN_SZ(pipe), 0);
|
||||
|
@ -4877,9 +4877,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Ensure that the cursor is valid for the new mode before changing... */
|
||||
intel_crtc_update_cursor(crtc, true);
|
||||
|
||||
if (is_lvds && dev_priv->lvds_downclock_avail) {
|
||||
/*
|
||||
* Ensure we match the reduced clock's P to the target clock.
|
||||
|
@ -5768,9 +5765,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
|||
intel_crtc->config.dpll.p2 = clock.p2;
|
||||
}
|
||||
|
||||
/* Ensure that the cursor is valid for the new mode before changing... */
|
||||
intel_crtc_update_cursor(crtc, true);
|
||||
|
||||
/* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
|
||||
if (intel_crtc->config.has_pch_encoder) {
|
||||
fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll);
|
||||
|
@ -5859,6 +5853,7 @@ static void ironlake_get_pfit_config(struct intel_crtc *crtc,
|
|||
tmp = I915_READ(PF_CTL(crtc->pipe));
|
||||
|
||||
if (tmp & PF_ENABLE) {
|
||||
pipe_config->pch_pfit.enabled = true;
|
||||
pipe_config->pch_pfit.pos = I915_READ(PF_WIN_POS(crtc->pipe));
|
||||
pipe_config->pch_pfit.size = I915_READ(PF_WIN_SZ(crtc->pipe));
|
||||
|
||||
|
@ -6236,7 +6231,7 @@ static void haswell_modeset_global_resources(struct drm_device *dev)
|
|||
if (!crtc->base.enabled)
|
||||
continue;
|
||||
|
||||
if (crtc->pipe != PIPE_A || crtc->config.pch_pfit.size ||
|
||||
if (crtc->pipe != PIPE_A || crtc->config.pch_pfit.enabled ||
|
||||
crtc->config.cpu_transcoder != TRANSCODER_EDP)
|
||||
enable = true;
|
||||
}
|
||||
|
@ -6259,9 +6254,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
|
|||
if (!intel_ddi_pll_mode_set(crtc))
|
||||
return -EINVAL;
|
||||
|
||||
/* Ensure that the cursor is valid for the new mode before changing... */
|
||||
intel_crtc_update_cursor(crtc, true);
|
||||
|
||||
if (intel_crtc->config.has_dp_encoder)
|
||||
intel_dp_set_m_n(intel_crtc);
|
||||
|
||||
|
@ -6494,15 +6486,15 @@ static void haswell_write_eld(struct drm_connector *connector,
|
|||
|
||||
/* Set ELD valid state */
|
||||
tmp = I915_READ(aud_cntrl_st2);
|
||||
DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%8x\n", tmp);
|
||||
DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%08x\n", tmp);
|
||||
tmp |= (AUDIO_ELD_VALID_A << (pipe * 4));
|
||||
I915_WRITE(aud_cntrl_st2, tmp);
|
||||
tmp = I915_READ(aud_cntrl_st2);
|
||||
DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%8x\n", tmp);
|
||||
DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%08x\n", tmp);
|
||||
|
||||
/* Enable HDMI mode */
|
||||
tmp = I915_READ(aud_config);
|
||||
DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%8x\n", tmp);
|
||||
DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%08x\n", tmp);
|
||||
/* clear N_programing_enable and N_value_index */
|
||||
tmp &= ~(AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE);
|
||||
I915_WRITE(aud_config, tmp);
|
||||
|
@ -6937,7 +6929,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||
intel_crtc->cursor_width = width;
|
||||
intel_crtc->cursor_height = height;
|
||||
|
||||
intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
|
||||
if (intel_crtc->active)
|
||||
intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
|
||||
|
||||
return 0;
|
||||
fail_unpin:
|
||||
|
@ -6956,7 +6949,8 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
|||
intel_crtc->cursor_x = x;
|
||||
intel_crtc->cursor_y = y;
|
||||
|
||||
intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
|
||||
if (intel_crtc->active)
|
||||
intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -8205,9 +8199,10 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
|
|||
pipe_config->gmch_pfit.control,
|
||||
pipe_config->gmch_pfit.pgm_ratios,
|
||||
pipe_config->gmch_pfit.lvds_border_bits);
|
||||
DRM_DEBUG_KMS("pch pfit: pos: 0x%08x, size: 0x%08x\n",
|
||||
DRM_DEBUG_KMS("pch pfit: pos: 0x%08x, size: 0x%08x, %s\n",
|
||||
pipe_config->pch_pfit.pos,
|
||||
pipe_config->pch_pfit.size);
|
||||
pipe_config->pch_pfit.size,
|
||||
pipe_config->pch_pfit.enabled ? "enabled" : "disabled");
|
||||
DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled);
|
||||
}
|
||||
|
||||
|
@ -8603,8 +8598,11 @@ intel_pipe_config_compare(struct drm_device *dev,
|
|||
if (INTEL_INFO(dev)->gen < 4)
|
||||
PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
|
||||
PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
|
||||
PIPE_CONF_CHECK_I(pch_pfit.pos);
|
||||
PIPE_CONF_CHECK_I(pch_pfit.size);
|
||||
PIPE_CONF_CHECK_I(pch_pfit.enabled);
|
||||
if (current_config->pch_pfit.enabled) {
|
||||
PIPE_CONF_CHECK_I(pch_pfit.pos);
|
||||
PIPE_CONF_CHECK_I(pch_pfit.size);
|
||||
}
|
||||
|
||||
PIPE_CONF_CHECK_I(ips_enabled);
|
||||
|
||||
|
|
|
@ -280,6 +280,7 @@ struct intel_crtc_config {
|
|||
struct {
|
||||
u32 pos;
|
||||
u32 size;
|
||||
bool enabled;
|
||||
} pch_pfit;
|
||||
|
||||
/* FDI configuration, only valid if has_pch_encoder is set. */
|
||||
|
|
|
@ -263,6 +263,8 @@ static bool intel_dvo_compute_config(struct intel_encoder *encoder,
|
|||
C(vtotal);
|
||||
C(clock);
|
||||
#undef C
|
||||
|
||||
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
||||
}
|
||||
|
||||
if (intel_dvo->dev.dev_ops->mode_fixup)
|
||||
|
|
|
@ -112,6 +112,7 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
|
|||
done:
|
||||
pipe_config->pch_pfit.pos = (x << 16) | y;
|
||||
pipe_config->pch_pfit.size = (width << 16) | height;
|
||||
pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -2096,16 +2096,16 @@ static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev,
|
|||
struct drm_crtc *crtc)
|
||||
{
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
uint32_t pixel_rate, pfit_size;
|
||||
uint32_t pixel_rate;
|
||||
|
||||
pixel_rate = intel_crtc->config.adjusted_mode.clock;
|
||||
|
||||
/* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
|
||||
* adjust the pixel_rate here. */
|
||||
|
||||
pfit_size = intel_crtc->config.pch_pfit.size;
|
||||
if (pfit_size) {
|
||||
if (intel_crtc->config.pch_pfit.enabled) {
|
||||
uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
|
||||
uint32_t pfit_size = intel_crtc->config.pch_pfit.size;
|
||||
|
||||
pipe_w = intel_crtc->config.requested_mode.hdisplay;
|
||||
pipe_h = intel_crtc->config.requested_mode.vdisplay;
|
||||
|
|
|
@ -788,6 +788,8 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
|
|||
uint16_t h_sync_offset, v_sync_offset;
|
||||
int mode_clock;
|
||||
|
||||
memset(dtd, 0, sizeof(*dtd));
|
||||
|
||||
width = mode->hdisplay;
|
||||
height = mode->vdisplay;
|
||||
|
||||
|
@ -830,44 +832,51 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
|
|||
if (mode->flags & DRM_MODE_FLAG_PVSYNC)
|
||||
dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE;
|
||||
|
||||
dtd->part2.sdvo_flags = 0;
|
||||
dtd->part2.v_sync_off_high = v_sync_offset & 0xc0;
|
||||
dtd->part2.reserved = 0;
|
||||
}
|
||||
|
||||
static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
|
||||
static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode *pmode,
|
||||
const struct intel_sdvo_dtd *dtd)
|
||||
{
|
||||
mode->hdisplay = dtd->part1.h_active;
|
||||
mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
|
||||
mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off;
|
||||
mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2;
|
||||
mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width;
|
||||
mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
|
||||
mode->htotal = mode->hdisplay + dtd->part1.h_blank;
|
||||
mode->htotal += (dtd->part1.h_high & 0xf) << 8;
|
||||
struct drm_display_mode mode = {};
|
||||
|
||||
mode->vdisplay = dtd->part1.v_active;
|
||||
mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
|
||||
mode->vsync_start = mode->vdisplay;
|
||||
mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
|
||||
mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2;
|
||||
mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0;
|
||||
mode->vsync_end = mode->vsync_start +
|
||||
mode.hdisplay = dtd->part1.h_active;
|
||||
mode.hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
|
||||
mode.hsync_start = mode.hdisplay + dtd->part2.h_sync_off;
|
||||
mode.hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2;
|
||||
mode.hsync_end = mode.hsync_start + dtd->part2.h_sync_width;
|
||||
mode.hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
|
||||
mode.htotal = mode.hdisplay + dtd->part1.h_blank;
|
||||
mode.htotal += (dtd->part1.h_high & 0xf) << 8;
|
||||
|
||||
mode.vdisplay = dtd->part1.v_active;
|
||||
mode.vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
|
||||
mode.vsync_start = mode.vdisplay;
|
||||
mode.vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
|
||||
mode.vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2;
|
||||
mode.vsync_start += dtd->part2.v_sync_off_high & 0xc0;
|
||||
mode.vsync_end = mode.vsync_start +
|
||||
(dtd->part2.v_sync_off_width & 0xf);
|
||||
mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4;
|
||||
mode->vtotal = mode->vdisplay + dtd->part1.v_blank;
|
||||
mode->vtotal += (dtd->part1.v_high & 0xf) << 8;
|
||||
mode.vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4;
|
||||
mode.vtotal = mode.vdisplay + dtd->part1.v_blank;
|
||||
mode.vtotal += (dtd->part1.v_high & 0xf) << 8;
|
||||
|
||||
mode->clock = dtd->part1.clock * 10;
|
||||
mode.clock = dtd->part1.clock * 10;
|
||||
|
||||
mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
|
||||
if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE)
|
||||
mode->flags |= DRM_MODE_FLAG_INTERLACE;
|
||||
mode.flags |= DRM_MODE_FLAG_INTERLACE;
|
||||
if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
|
||||
mode->flags |= DRM_MODE_FLAG_PHSYNC;
|
||||
mode.flags |= DRM_MODE_FLAG_PHSYNC;
|
||||
else
|
||||
mode.flags |= DRM_MODE_FLAG_NHSYNC;
|
||||
if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
|
||||
mode->flags |= DRM_MODE_FLAG_PVSYNC;
|
||||
mode.flags |= DRM_MODE_FLAG_PVSYNC;
|
||||
else
|
||||
mode.flags |= DRM_MODE_FLAG_NVSYNC;
|
||||
|
||||
drm_mode_set_crtcinfo(&mode, 0);
|
||||
|
||||
drm_mode_copy(pmode, &mode);
|
||||
}
|
||||
|
||||
static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo)
|
||||
|
|
Загрузка…
Ссылка в новой задаче