Merge tag 'drm-fixes-for-4.8-rc3-2' of git://people.freedesktop.org/~airlied/linux
Pull more drm fixes from Dave Airlie: "Daniel pointed out I'd missed some i915 fixes, and I also found a single etnaviv fix I missed. So here they are" * tag 'drm-fixes-for-4.8-rc3-2' of git://people.freedesktop.org/~airlied/linux: drm/etnaviv: take GPU lock later in the submit process drm/i915: Fix modeset handling during gpu reset, v5. drm/i915: fix aliasing_ppgtt leak drm/i915: fix WaInsertDummyPushConstPs drm/i915: Fix iboost setting for SKL Y/U DP DDI buffer translation entry 2 drm/i915/gen9: Give one extra block per line for SKL plane WM calculations drm/i915: Acquire audio powerwell for HD-Audio registers drm/i915: Add missing rpm wakelock to GGTT pread drm/i915/fbc: FBC causes display flicker when VT-d is enabled on Skylake drm/i915: Clean up the extra RPM ref on CHV with i915.enable_rc6=0 drm/i915: Program iboost settings for HDMI/DVI on SKL drm/i915: Fix iboost setting for DDI with 4 lanes on SKL drm/i915: Handle ENOSPC after failing to insert a mappable node drm/i915: Flush GT idle status upon reset
This commit is contained in:
commit
952b159f29
@ -1333,8 +1333,6 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&gpu->lock);
|
||||
|
||||
/*
|
||||
* TODO
|
||||
*
|
||||
@ -1348,16 +1346,18 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
|
||||
if (unlikely(event == ~0U)) {
|
||||
DRM_ERROR("no free event\n");
|
||||
ret = -EBUSY;
|
||||
goto out_unlock;
|
||||
goto out_pm_put;
|
||||
}
|
||||
|
||||
fence = etnaviv_gpu_fence_alloc(gpu);
|
||||
if (!fence) {
|
||||
event_free(gpu, event);
|
||||
ret = -ENOMEM;
|
||||
goto out_unlock;
|
||||
goto out_pm_put;
|
||||
}
|
||||
|
||||
mutex_lock(&gpu->lock);
|
||||
|
||||
gpu->event[event].fence = fence;
|
||||
submit->fence = fence->seqno;
|
||||
gpu->active_fence = submit->fence;
|
||||
@ -1395,9 +1395,9 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
|
||||
hangcheck_timer_reset(gpu);
|
||||
ret = 0;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&gpu->lock);
|
||||
|
||||
out_pm_put:
|
||||
etnaviv_gpu_pm_put(gpu);
|
||||
|
||||
return ret;
|
||||
|
@ -1854,6 +1854,7 @@ struct drm_i915_private {
|
||||
enum modeset_restore modeset_restore;
|
||||
struct mutex modeset_restore_lock;
|
||||
struct drm_atomic_state *modeset_restore_state;
|
||||
struct drm_modeset_acquire_ctx reset_ctx;
|
||||
|
||||
struct list_head vm_list; /* Global list of all address spaces */
|
||||
struct i915_ggtt ggtt; /* VM representing the global address space */
|
||||
|
@ -879,9 +879,12 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
|
||||
ret = i915_gem_shmem_pread(dev, obj, args, file);
|
||||
|
||||
/* pread for non shmem backed objects */
|
||||
if (ret == -EFAULT || ret == -ENODEV)
|
||||
if (ret == -EFAULT || ret == -ENODEV) {
|
||||
intel_runtime_pm_get(to_i915(dev));
|
||||
ret = i915_gem_gtt_pread(dev, obj, args->size,
|
||||
args->offset, args->data_ptr);
|
||||
intel_runtime_pm_put(to_i915(dev));
|
||||
}
|
||||
|
||||
out:
|
||||
drm_gem_object_unreference(&obj->base);
|
||||
@ -1306,7 +1309,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
|
||||
* textures). Fallback to the shmem path in that case. */
|
||||
}
|
||||
|
||||
if (ret == -EFAULT) {
|
||||
if (ret == -EFAULT || ret == -ENOSPC) {
|
||||
if (obj->phys_handle)
|
||||
ret = i915_gem_phys_pwrite(obj, args, file);
|
||||
else if (i915_gem_object_has_struct_page(obj))
|
||||
@ -3169,6 +3172,8 @@ static void i915_gem_reset_engine_cleanup(struct intel_engine_cs *engine)
|
||||
}
|
||||
|
||||
intel_ring_init_seqno(engine, engine->last_submitted_seqno);
|
||||
|
||||
engine->i915->gt.active_engines &= ~intel_engine_flag(engine);
|
||||
}
|
||||
|
||||
void i915_gem_reset(struct drm_device *dev)
|
||||
@ -3186,6 +3191,7 @@ void i915_gem_reset(struct drm_device *dev)
|
||||
|
||||
for_each_engine(engine, dev_priv)
|
||||
i915_gem_reset_engine_cleanup(engine);
|
||||
mod_delayed_work(dev_priv->wq, &dev_priv->gt.idle_work, 0);
|
||||
|
||||
i915_gem_context_reset(dev);
|
||||
|
||||
|
@ -2873,6 +2873,7 @@ void i915_ggtt_cleanup_hw(struct drm_device *dev)
|
||||
struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
|
||||
|
||||
ppgtt->base.cleanup(&ppgtt->base);
|
||||
kfree(ppgtt);
|
||||
}
|
||||
|
||||
i915_gem_cleanup_stolen(dev);
|
||||
|
@ -1536,6 +1536,7 @@ enum skl_disp_power_wells {
|
||||
#define BALANCE_LEG_MASK(port) (7<<(8+3*(port)))
|
||||
/* Balance leg disable bits */
|
||||
#define BALANCE_LEG_DISABLE_SHIFT 23
|
||||
#define BALANCE_LEG_DISABLE(port) (1 << (23 + (port)))
|
||||
|
||||
/*
|
||||
* Fence registers
|
||||
|
@ -600,6 +600,8 @@ static void i915_audio_component_codec_wake_override(struct device *dev,
|
||||
if (!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv))
|
||||
return;
|
||||
|
||||
i915_audio_component_get_power(dev);
|
||||
|
||||
/*
|
||||
* Enable/disable generating the codec wake signal, overriding the
|
||||
* internal logic to generate the codec wake to controller.
|
||||
@ -615,6 +617,8 @@ static void i915_audio_component_codec_wake_override(struct device *dev,
|
||||
I915_WRITE(HSW_AUD_CHICKENBIT, tmp);
|
||||
usleep_range(1000, 1500);
|
||||
}
|
||||
|
||||
i915_audio_component_put_power(dev);
|
||||
}
|
||||
|
||||
/* Get CDCLK in kHz */
|
||||
@ -648,6 +652,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
|
||||
!IS_HASWELL(dev_priv))
|
||||
return 0;
|
||||
|
||||
i915_audio_component_get_power(dev);
|
||||
mutex_lock(&dev_priv->av_mutex);
|
||||
/* 1. get the pipe */
|
||||
intel_encoder = dev_priv->dig_port_map[port];
|
||||
@ -698,6 +703,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&dev_priv->av_mutex);
|
||||
i915_audio_component_put_power(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
|
||||
static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
|
||||
{ 0x0000201B, 0x000000A2, 0x0 },
|
||||
{ 0x00005012, 0x00000088, 0x0 },
|
||||
{ 0x80007011, 0x000000CD, 0x0 },
|
||||
{ 0x80007011, 0x000000CD, 0x1 },
|
||||
{ 0x80009010, 0x000000C0, 0x1 },
|
||||
{ 0x0000201B, 0x0000009D, 0x0 },
|
||||
{ 0x80005012, 0x000000C0, 0x1 },
|
||||
@ -158,7 +158,7 @@ static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
|
||||
static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = {
|
||||
{ 0x00000018, 0x000000A2, 0x0 },
|
||||
{ 0x00005012, 0x00000088, 0x0 },
|
||||
{ 0x80007011, 0x000000CD, 0x0 },
|
||||
{ 0x80007011, 0x000000CD, 0x3 },
|
||||
{ 0x80009010, 0x000000C0, 0x3 },
|
||||
{ 0x00000018, 0x0000009D, 0x0 },
|
||||
{ 0x80005012, 0x000000C0, 0x3 },
|
||||
@ -388,6 +388,40 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
|
||||
}
|
||||
}
|
||||
|
||||
static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port)
|
||||
{
|
||||
int n_hdmi_entries;
|
||||
int hdmi_level;
|
||||
int hdmi_default_entry;
|
||||
|
||||
hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
|
||||
|
||||
if (IS_BROXTON(dev_priv))
|
||||
return hdmi_level;
|
||||
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
|
||||
skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
|
||||
hdmi_default_entry = 8;
|
||||
} else if (IS_BROADWELL(dev_priv)) {
|
||||
n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
|
||||
hdmi_default_entry = 7;
|
||||
} else if (IS_HASWELL(dev_priv)) {
|
||||
n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
|
||||
hdmi_default_entry = 6;
|
||||
} else {
|
||||
WARN(1, "ddi translation table missing\n");
|
||||
n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
|
||||
hdmi_default_entry = 7;
|
||||
}
|
||||
|
||||
/* Choose a good default if VBT is badly populated */
|
||||
if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
|
||||
hdmi_level >= n_hdmi_entries)
|
||||
hdmi_level = hdmi_default_entry;
|
||||
|
||||
return hdmi_level;
|
||||
}
|
||||
|
||||
/*
|
||||
* Starting with Haswell, DDI port buffers must be programmed with correct
|
||||
* values in advance. The buffer values are different for FDI and DP modes,
|
||||
@ -399,7 +433,7 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
u32 iboost_bit = 0;
|
||||
int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
|
||||
int i, n_hdmi_entries, n_dp_entries, n_edp_entries,
|
||||
size;
|
||||
int hdmi_level;
|
||||
enum port port;
|
||||
@ -410,7 +444,7 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
|
||||
const struct ddi_buf_trans *ddi_translations;
|
||||
|
||||
port = intel_ddi_get_encoder_port(encoder);
|
||||
hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
|
||||
hdmi_level = intel_ddi_hdmi_level(dev_priv, port);
|
||||
|
||||
if (IS_BROXTON(dev_priv)) {
|
||||
if (encoder->type != INTEL_OUTPUT_HDMI)
|
||||
@ -430,7 +464,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
|
||||
skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
|
||||
ddi_translations_hdmi =
|
||||
skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
|
||||
hdmi_default_entry = 8;
|
||||
/* If we're boosting the current, set bit 31 of trans1 */
|
||||
if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
|
||||
dev_priv->vbt.ddi_port_info[port].dp_boost_level)
|
||||
@ -456,7 +489,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
|
||||
|
||||
n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
|
||||
n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
|
||||
hdmi_default_entry = 7;
|
||||
} else if (IS_HASWELL(dev_priv)) {
|
||||
ddi_translations_fdi = hsw_ddi_translations_fdi;
|
||||
ddi_translations_dp = hsw_ddi_translations_dp;
|
||||
@ -464,7 +496,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
|
||||
ddi_translations_hdmi = hsw_ddi_translations_hdmi;
|
||||
n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
|
||||
n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
|
||||
hdmi_default_entry = 6;
|
||||
} else {
|
||||
WARN(1, "ddi translation table missing\n");
|
||||
ddi_translations_edp = bdw_ddi_translations_dp;
|
||||
@ -474,7 +505,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
|
||||
n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
|
||||
n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
|
||||
n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
|
||||
hdmi_default_entry = 7;
|
||||
}
|
||||
|
||||
switch (encoder->type) {
|
||||
@ -505,11 +535,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
|
||||
if (encoder->type != INTEL_OUTPUT_HDMI)
|
||||
return;
|
||||
|
||||
/* Choose a good default if VBT is badly populated */
|
||||
if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
|
||||
hdmi_level >= n_hdmi_entries)
|
||||
hdmi_level = hdmi_default_entry;
|
||||
|
||||
/* Entry 9 is for HDMI: */
|
||||
I915_WRITE(DDI_BUF_TRANS_LO(port, i),
|
||||
ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
|
||||
@ -1379,14 +1404,30 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
|
||||
TRANS_CLK_SEL_DISABLED);
|
||||
}
|
||||
|
||||
static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
|
||||
u32 level, enum port port, int type)
|
||||
static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
|
||||
enum port port, uint8_t iboost)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = I915_READ(DISPIO_CR_TX_BMU_CR0);
|
||||
tmp &= ~(BALANCE_LEG_MASK(port) | BALANCE_LEG_DISABLE(port));
|
||||
if (iboost)
|
||||
tmp |= iboost << BALANCE_LEG_SHIFT(port);
|
||||
else
|
||||
tmp |= BALANCE_LEG_DISABLE(port);
|
||||
I915_WRITE(DISPIO_CR_TX_BMU_CR0, tmp);
|
||||
}
|
||||
|
||||
static void skl_ddi_set_iboost(struct intel_encoder *encoder, u32 level)
|
||||
{
|
||||
struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base);
|
||||
struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
|
||||
enum port port = intel_dig_port->port;
|
||||
int type = encoder->type;
|
||||
const struct ddi_buf_trans *ddi_translations;
|
||||
uint8_t iboost;
|
||||
uint8_t dp_iboost, hdmi_iboost;
|
||||
int n_entries;
|
||||
u32 reg;
|
||||
|
||||
/* VBT may override standard boost values */
|
||||
dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
|
||||
@ -1428,16 +1469,10 @@ static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
|
||||
return;
|
||||
}
|
||||
|
||||
reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
|
||||
reg &= ~BALANCE_LEG_MASK(port);
|
||||
reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
|
||||
_skl_ddi_set_iboost(dev_priv, port, iboost);
|
||||
|
||||
if (iboost)
|
||||
reg |= iboost << BALANCE_LEG_SHIFT(port);
|
||||
else
|
||||
reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
|
||||
|
||||
I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
|
||||
if (port == PORT_A && intel_dig_port->max_lanes == 4)
|
||||
_skl_ddi_set_iboost(dev_priv, PORT_E, iboost);
|
||||
}
|
||||
|
||||
static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
|
||||
@ -1568,7 +1603,7 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
|
||||
level = translate_signal_level(signal_levels);
|
||||
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
|
||||
skl_ddi_set_iboost(dev_priv, level, port, encoder->type);
|
||||
skl_ddi_set_iboost(encoder, level);
|
||||
else if (IS_BROXTON(dev_priv))
|
||||
bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type);
|
||||
|
||||
@ -1637,6 +1672,10 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
|
||||
intel_dp_stop_link_train(intel_dp);
|
||||
} else if (type == INTEL_OUTPUT_HDMI) {
|
||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
|
||||
int level = intel_ddi_hdmi_level(dev_priv, port);
|
||||
|
||||
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
|
||||
skl_ddi_set_iboost(intel_encoder, level);
|
||||
|
||||
intel_hdmi->set_infoframes(encoder,
|
||||
crtc->config->has_hdmi_sink,
|
||||
|
@ -3093,40 +3093,110 @@ static void intel_update_primary_planes(struct drm_device *dev)
|
||||
|
||||
for_each_crtc(dev, crtc) {
|
||||
struct intel_plane *plane = to_intel_plane(crtc->primary);
|
||||
struct intel_plane_state *plane_state;
|
||||
|
||||
drm_modeset_lock_crtc(crtc, &plane->base);
|
||||
plane_state = to_intel_plane_state(plane->base.state);
|
||||
struct intel_plane_state *plane_state =
|
||||
to_intel_plane_state(plane->base.state);
|
||||
|
||||
if (plane_state->visible)
|
||||
plane->update_plane(&plane->base,
|
||||
to_intel_crtc_state(crtc->state),
|
||||
plane_state);
|
||||
|
||||
drm_modeset_unlock_crtc(crtc);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
__intel_display_resume(struct drm_device *dev,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_crtc *crtc;
|
||||
int i, ret;
|
||||
|
||||
intel_modeset_setup_hw_state(dev);
|
||||
i915_redisable_vga(dev);
|
||||
|
||||
if (!state)
|
||||
return 0;
|
||||
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
/*
|
||||
* Force recalculation even if we restore
|
||||
* current state. With fast modeset this may not result
|
||||
* in a modeset when the state is compatible.
|
||||
*/
|
||||
crtc_state->mode_changed = true;
|
||||
}
|
||||
|
||||
/* ignore any reset values/BIOS leftovers in the WM registers */
|
||||
to_intel_atomic_state(state)->skip_intermediate_wm = true;
|
||||
|
||||
ret = drm_atomic_commit(state);
|
||||
|
||||
WARN_ON(ret == -EDEADLK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void intel_prepare_reset(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_modeset_acquire_ctx *ctx = &dev_priv->reset_ctx;
|
||||
struct drm_atomic_state *state;
|
||||
int ret;
|
||||
|
||||
/* no reset support for gen2 */
|
||||
if (IS_GEN2(dev_priv))
|
||||
return;
|
||||
|
||||
/* reset doesn't touch the display */
|
||||
/*
|
||||
* Need mode_config.mutex so that we don't
|
||||
* trample ongoing ->detect() and whatnot.
|
||||
*/
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_modeset_acquire_init(ctx, 0);
|
||||
while (1) {
|
||||
ret = drm_modeset_lock_all_ctx(dev, ctx);
|
||||
if (ret != -EDEADLK)
|
||||
break;
|
||||
|
||||
drm_modeset_backoff(ctx);
|
||||
}
|
||||
|
||||
/* reset doesn't touch the display, but flips might get nuked anyway, */
|
||||
if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
|
||||
return;
|
||||
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
/*
|
||||
* Disabling the crtcs gracefully seems nicer. Also the
|
||||
* g33 docs say we should at least disable all the planes.
|
||||
*/
|
||||
intel_display_suspend(&dev_priv->drm);
|
||||
state = drm_atomic_helper_duplicate_state(dev, ctx);
|
||||
if (IS_ERR(state)) {
|
||||
ret = PTR_ERR(state);
|
||||
state = NULL;
|
||||
DRM_ERROR("Duplicating state failed with %i\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = drm_atomic_helper_disable_all(dev, ctx);
|
||||
if (ret) {
|
||||
DRM_ERROR("Suspending crtc's failed with %i\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
dev_priv->modeset_restore_state = state;
|
||||
state->acquire_ctx = ctx;
|
||||
return;
|
||||
|
||||
err:
|
||||
drm_atomic_state_free(state);
|
||||
}
|
||||
|
||||
void intel_finish_reset(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_modeset_acquire_ctx *ctx = &dev_priv->reset_ctx;
|
||||
struct drm_atomic_state *state = dev_priv->modeset_restore_state;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Flips in the rings will be nuked by the reset,
|
||||
* so complete all pending flips so that user space
|
||||
@ -3138,6 +3208,8 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
|
||||
if (IS_GEN2(dev_priv))
|
||||
return;
|
||||
|
||||
dev_priv->modeset_restore_state = NULL;
|
||||
|
||||
/* reset doesn't touch the display */
|
||||
if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) {
|
||||
/*
|
||||
@ -3149,29 +3221,32 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
|
||||
* FIXME: Atomic will make this obsolete since we won't schedule
|
||||
* CS-based flips (which might get lost in gpu resets) any more.
|
||||
*/
|
||||
intel_update_primary_planes(&dev_priv->drm);
|
||||
return;
|
||||
intel_update_primary_planes(dev);
|
||||
} else {
|
||||
/*
|
||||
* The display has been reset as well,
|
||||
* so need a full re-initialization.
|
||||
*/
|
||||
intel_runtime_pm_disable_interrupts(dev_priv);
|
||||
intel_runtime_pm_enable_interrupts(dev_priv);
|
||||
|
||||
intel_modeset_init_hw(dev);
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
if (dev_priv->display.hpd_irq_setup)
|
||||
dev_priv->display.hpd_irq_setup(dev_priv);
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
ret = __intel_display_resume(dev, state);
|
||||
if (ret)
|
||||
DRM_ERROR("Restoring old state failed with %i\n", ret);
|
||||
|
||||
intel_hpd_init(dev_priv);
|
||||
}
|
||||
|
||||
/*
|
||||
* The display has been reset as well,
|
||||
* so need a full re-initialization.
|
||||
*/
|
||||
intel_runtime_pm_disable_interrupts(dev_priv);
|
||||
intel_runtime_pm_enable_interrupts(dev_priv);
|
||||
|
||||
intel_modeset_init_hw(&dev_priv->drm);
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
if (dev_priv->display.hpd_irq_setup)
|
||||
dev_priv->display.hpd_irq_setup(dev_priv);
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
intel_display_resume(&dev_priv->drm);
|
||||
|
||||
intel_hpd_init(dev_priv);
|
||||
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
drm_modeset_drop_locks(ctx);
|
||||
drm_modeset_acquire_fini(ctx);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
}
|
||||
|
||||
static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
|
||||
@ -16156,9 +16231,10 @@ void intel_display_resume(struct drm_device *dev)
|
||||
struct drm_atomic_state *state = dev_priv->modeset_restore_state;
|
||||
struct drm_modeset_acquire_ctx ctx;
|
||||
int ret;
|
||||
bool setup = false;
|
||||
|
||||
dev_priv->modeset_restore_state = NULL;
|
||||
if (state)
|
||||
state->acquire_ctx = &ctx;
|
||||
|
||||
/*
|
||||
* This is a cludge because with real atomic modeset mode_config.mutex
|
||||
@ -16169,43 +16245,17 @@ void intel_display_resume(struct drm_device *dev)
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_modeset_acquire_init(&ctx, 0);
|
||||
|
||||
retry:
|
||||
ret = drm_modeset_lock_all_ctx(dev, &ctx);
|
||||
while (1) {
|
||||
ret = drm_modeset_lock_all_ctx(dev, &ctx);
|
||||
if (ret != -EDEADLK)
|
||||
break;
|
||||
|
||||
if (ret == 0 && !setup) {
|
||||
setup = true;
|
||||
|
||||
intel_modeset_setup_hw_state(dev);
|
||||
i915_redisable_vga(dev);
|
||||
}
|
||||
|
||||
if (ret == 0 && state) {
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_crtc *crtc;
|
||||
int i;
|
||||
|
||||
state->acquire_ctx = &ctx;
|
||||
|
||||
/* ignore any reset values/BIOS leftovers in the WM registers */
|
||||
to_intel_atomic_state(state)->skip_intermediate_wm = true;
|
||||
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
/*
|
||||
* Force recalculation even if we restore
|
||||
* current state. With fast modeset this may not result
|
||||
* in a modeset when the state is compatible.
|
||||
*/
|
||||
crtc_state->mode_changed = true;
|
||||
}
|
||||
|
||||
ret = drm_atomic_commit(state);
|
||||
}
|
||||
|
||||
if (ret == -EDEADLK) {
|
||||
drm_modeset_backoff(&ctx);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
ret = __intel_display_resume(dev, state);
|
||||
|
||||
drm_modeset_drop_locks(&ctx);
|
||||
drm_modeset_acquire_fini(&ctx);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
@ -1230,12 +1230,29 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv)
|
||||
if (i915.enable_fbc >= 0)
|
||||
return !!i915.enable_fbc;
|
||||
|
||||
if (!HAS_FBC(dev_priv))
|
||||
return 0;
|
||||
|
||||
if (IS_BROADWELL(dev_priv))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool need_fbc_vtd_wa(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
#ifdef CONFIG_INTEL_IOMMU
|
||||
/* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */
|
||||
if (intel_iommu_gfx_mapped &&
|
||||
(IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))) {
|
||||
DRM_INFO("Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_fbc_init - Initialize FBC
|
||||
* @dev_priv: the i915 device
|
||||
@ -1253,6 +1270,9 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
|
||||
fbc->active = false;
|
||||
fbc->work.scheduled = false;
|
||||
|
||||
if (need_fbc_vtd_wa(dev_priv))
|
||||
mkwrite_device_info(dev_priv)->has_fbc = false;
|
||||
|
||||
i915.enable_fbc = intel_sanitize_fbc_option(dev_priv);
|
||||
DRM_DEBUG_KMS("Sanitized enable_fbc value: %d\n", i915.enable_fbc);
|
||||
|
||||
|
@ -3344,6 +3344,8 @@ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
|
||||
plane_bytes_per_line *= 4;
|
||||
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
|
||||
plane_blocks_per_line /= 4;
|
||||
} else if (tiling == DRM_FORMAT_MOD_NONE) {
|
||||
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1;
|
||||
} else {
|
||||
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
|
||||
}
|
||||
@ -6574,9 +6576,7 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
|
||||
|
||||
void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
return;
|
||||
else if (IS_VALLEYVIEW(dev_priv))
|
||||
if (IS_VALLEYVIEW(dev_priv))
|
||||
valleyview_cleanup_gt_powersave(dev_priv);
|
||||
|
||||
if (!i915.enable_rc6)
|
||||
|
@ -1178,8 +1178,8 @@ static int bxt_init_workarounds(struct intel_engine_cs *engine)
|
||||
I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) |
|
||||
L3_HIGH_PRIO_CREDITS(2));
|
||||
|
||||
/* WaInsertDummyPushConstPs:bxt */
|
||||
if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0))
|
||||
/* WaToEnableHwFixForPushConstHWBug:bxt */
|
||||
if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
|
||||
WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
|
||||
GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
|
||||
|
||||
@ -1222,8 +1222,8 @@ static int kbl_init_workarounds(struct intel_engine_cs *engine)
|
||||
I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
|
||||
GEN8_LQSC_RO_PERF_DIS);
|
||||
|
||||
/* WaInsertDummyPushConstPs:kbl */
|
||||
if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
|
||||
/* WaToEnableHwFixForPushConstHWBug:kbl */
|
||||
if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
|
||||
WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
|
||||
GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user