Commit 659a1823 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "Fixes for i915, amdgpu/radeon and imx.

  The IMX fix is for an autoloading regression found in Fedora.  The
  radeon fixes, are the same fix to amdgpu/radeon to avoid a hardware
  lockup in some circumstances with a bad mode, and a double free bug I
  took a few hours chasing down the other morning.

  The i915 fixes are across the board, all stable material, and fixing
  some hangs and suspend/resume issues, along with a live status
  regressions"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  gpu: ipu-v3: Fix imx-ipuv3-crtc module autoloading
  drm/amdgpu: make sure vertical front porch is at least 1
  drm/radeon: make sure vertical front porch is at least 1
  drm/amdgpu: set metadata pointer to NULL after freeing.
  drm/i915: Make RPS EI/thresholds multiple of 25 on SNB-BDW
  drm/i915: Fake HDMI live status
  drm/i915: Fix eDP low vswing for Broadwell
  drm/i915/ddi: Fix eDP VDD handling during booting and suspend/resume
  drm/i915: Fix system resume if PCI device remained enabled
  drm/i915: Avoid stalling on pending flips for legacy cursor updates
parents 9caa7e78 fca09716
...@@ -541,6 +541,7 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata, ...@@ -541,6 +541,7 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata,
if (!metadata_size) { if (!metadata_size) {
if (bo->metadata_size) { if (bo->metadata_size) {
kfree(bo->metadata); kfree(bo->metadata);
bo->metadata = NULL;
bo->metadata_size = 0; bo->metadata_size = 0;
} }
return 0; return 0;
......
...@@ -298,6 +298,10 @@ bool amdgpu_atombios_encoder_mode_fixup(struct drm_encoder *encoder, ...@@ -298,6 +298,10 @@ bool amdgpu_atombios_encoder_mode_fixup(struct drm_encoder *encoder,
&& (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
/* vertical FP must be at least 1 */
if (mode->crtc_vsync_start == mode->crtc_vdisplay)
adjusted_mode->crtc_vsync_start++;
/* get the native mode for scaling */ /* get the native mode for scaling */
if (amdgpu_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) if (amdgpu_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
amdgpu_panel_mode_fixup(encoder, adjusted_mode); amdgpu_panel_mode_fixup(encoder, adjusted_mode);
......
...@@ -792,7 +792,7 @@ static int i915_drm_resume(struct drm_device *dev) ...@@ -792,7 +792,7 @@ static int i915_drm_resume(struct drm_device *dev)
static int i915_drm_resume_early(struct drm_device *dev) static int i915_drm_resume_early(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int ret = 0; int ret;
/* /*
* We have a resume ordering issue with the snd-hda driver also * We have a resume ordering issue with the snd-hda driver also
...@@ -803,6 +803,36 @@ static int i915_drm_resume_early(struct drm_device *dev) ...@@ -803,6 +803,36 @@ static int i915_drm_resume_early(struct drm_device *dev)
* FIXME: This should be solved with a special hdmi sink device or * FIXME: This should be solved with a special hdmi sink device or
* similar so that power domains can be employed. * similar so that power domains can be employed.
*/ */
/*
* Note that we need to set the power state explicitly, since we
* powered off the device during freeze and the PCI core won't power
* it back up for us during thaw. Powering off the device during
* freeze is not a hard requirement though, and during the
* suspend/resume phases the PCI core makes sure we get here with the
* device powered on. So in case we change our freeze logic and keep
* the device powered we can also remove the following set power state
* call.
*/
ret = pci_set_power_state(dev->pdev, PCI_D0);
if (ret) {
DRM_ERROR("failed to set PCI D0 power state (%d)\n", ret);
goto out;
}
/*
* Note that pci_enable_device() first enables any parent bridge
* device and only then sets the power state for this device. The
* bridge enabling is a nop though, since bridge devices are resumed
* first. The order of enabling power and enabling the device is
* imposed by the PCI core as described above, so here we preserve the
* same order for the freeze/thaw phases.
*
* TODO: eventually we should remove pci_disable_device() /
* pci_enable_enable_device() from suspend/resume. Due to how they
* depend on the device enable refcount we can't anyway depend on them
* disabling/enabling the device.
*/
if (pci_enable_device(dev->pdev)) { if (pci_enable_device(dev->pdev)) {
ret = -EIO; ret = -EIO;
goto out; goto out;
......
...@@ -2907,7 +2907,14 @@ enum skl_disp_power_wells { ...@@ -2907,7 +2907,14 @@ enum skl_disp_power_wells {
#define GEN6_RP_STATE_CAP _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998) #define GEN6_RP_STATE_CAP _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998)
#define BXT_RP_STATE_CAP _MMIO(0x138170) #define BXT_RP_STATE_CAP _MMIO(0x138170)
#define INTERVAL_1_28_US(us) (((us) * 100) >> 7) /*
* Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS
* 8300) freezing up around GPU hangs. Looks as if even
* scheduling/timer interrupts start misbehaving if the RPS
* EI/thresholds are "bad", leading to a very sluggish or even
* frozen machine.
*/
#define INTERVAL_1_28_US(us) roundup(((us) * 100) >> 7, 25)
#define INTERVAL_1_33_US(us) (((us) * 3) >> 2) #define INTERVAL_1_33_US(us) (((us) * 3) >> 2)
#define INTERVAL_0_833_US(us) (((us) * 6) / 5) #define INTERVAL_0_833_US(us) (((us) * 6) / 5)
#define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \ #define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \
......
...@@ -443,9 +443,17 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) ...@@ -443,9 +443,17 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
} else if (IS_BROADWELL(dev_priv)) { } else if (IS_BROADWELL(dev_priv)) {
ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_fdi = bdw_ddi_translations_fdi;
ddi_translations_dp = bdw_ddi_translations_dp; ddi_translations_dp = bdw_ddi_translations_dp;
if (dev_priv->edp_low_vswing) {
ddi_translations_edp = bdw_ddi_translations_edp; ddi_translations_edp = bdw_ddi_translations_edp;
ddi_translations_hdmi = bdw_ddi_translations_hdmi;
n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
} else {
ddi_translations_edp = bdw_ddi_translations_dp;
n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
}
ddi_translations_hdmi = bdw_ddi_translations_hdmi;
n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
hdmi_default_entry = 7; hdmi_default_entry = 7;
...@@ -3201,12 +3209,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder, ...@@ -3201,12 +3209,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
intel_ddi_clock_get(encoder, pipe_config); intel_ddi_clock_get(encoder, pipe_config);
} }
static void intel_ddi_destroy(struct drm_encoder *encoder)
{
/* HDMI has nothing special to destroy, so we can go with this. */
intel_dp_encoder_destroy(encoder);
}
static bool intel_ddi_compute_config(struct intel_encoder *encoder, static bool intel_ddi_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config) struct intel_crtc_state *pipe_config)
{ {
...@@ -3225,7 +3227,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder, ...@@ -3225,7 +3227,8 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder,
} }
static const struct drm_encoder_funcs intel_ddi_funcs = { static const struct drm_encoder_funcs intel_ddi_funcs = {
.destroy = intel_ddi_destroy, .reset = intel_dp_encoder_reset,
.destroy = intel_dp_encoder_destroy,
}; };
static struct intel_connector * static struct intel_connector *
...@@ -3324,6 +3327,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) ...@@ -3324,6 +3327,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
intel_encoder->post_disable = intel_ddi_post_disable; intel_encoder->post_disable = intel_ddi_post_disable;
intel_encoder->get_hw_state = intel_ddi_get_hw_state; intel_encoder->get_hw_state = intel_ddi_get_hw_state;
intel_encoder->get_config = intel_ddi_get_config; intel_encoder->get_config = intel_ddi_get_config;
intel_encoder->suspend = intel_dp_encoder_suspend;
intel_dig_port->port = port; intel_dig_port->port = port;
intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
......
...@@ -13351,6 +13351,9 @@ static int intel_atomic_prepare_commit(struct drm_device *dev, ...@@ -13351,6 +13351,9 @@ static int intel_atomic_prepare_commit(struct drm_device *dev,
} }
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_crtc_in_state(state, crtc, crtc_state, i) {
if (state->legacy_cursor_update)
continue;
ret = intel_crtc_wait_for_pending_flips(crtc); ret = intel_crtc_wait_for_pending_flips(crtc);
if (ret) if (ret)
return ret; return ret;
......
...@@ -4898,7 +4898,7 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) ...@@ -4898,7 +4898,7 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
kfree(intel_dig_port); kfree(intel_dig_port);
} }
static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
{ {
struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
...@@ -4940,7 +4940,7 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) ...@@ -4940,7 +4940,7 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
edp_panel_vdd_schedule_off(intel_dp); edp_panel_vdd_schedule_off(intel_dp);
} }
static void intel_dp_encoder_reset(struct drm_encoder *encoder) void intel_dp_encoder_reset(struct drm_encoder *encoder)
{ {
struct intel_dp *intel_dp; struct intel_dp *intel_dp;
......
...@@ -1238,6 +1238,8 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp, ...@@ -1238,6 +1238,8 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp,
void intel_dp_start_link_train(struct intel_dp *intel_dp); void intel_dp_start_link_train(struct intel_dp *intel_dp);
void intel_dp_stop_link_train(struct intel_dp *intel_dp); void intel_dp_stop_link_train(struct intel_dp *intel_dp);
void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
void intel_dp_encoder_reset(struct drm_encoder *encoder);
void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
void intel_dp_encoder_destroy(struct drm_encoder *encoder); void intel_dp_encoder_destroy(struct drm_encoder *encoder);
int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc); int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc);
bool intel_dp_compute_config(struct intel_encoder *encoder, bool intel_dp_compute_config(struct intel_encoder *encoder,
......
...@@ -1415,8 +1415,16 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) ...@@ -1415,8 +1415,16 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
hdmi_to_dig_port(intel_hdmi)); hdmi_to_dig_port(intel_hdmi));
} }
if (!live_status) if (!live_status) {
DRM_DEBUG_KMS("Live status not up!"); DRM_DEBUG_KMS("HDMI live status down\n");
/*
* Live status register is not reliable on all intel platforms.
* So consider live_status only for certain platforms, for
* others, read EDID to determine presence of sink.
*/
if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv))
live_status = true;
}
intel_hdmi_unset_edid(connector); intel_hdmi_unset_edid(connector);
......
...@@ -310,6 +310,10 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, ...@@ -310,6 +310,10 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
&& (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
/* vertical FP must be at least 1 */
if (mode->crtc_vsync_start == mode->crtc_vdisplay)
adjusted_mode->crtc_vsync_start++;
/* get the native mode for scaling */ /* get the native mode for scaling */
if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
radeon_panel_mode_fixup(encoder, adjusted_mode); radeon_panel_mode_fixup(encoder, adjusted_mode);
......
...@@ -1068,7 +1068,6 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) ...@@ -1068,7 +1068,6 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
goto err_register; goto err_register;
} }
pdev->dev.of_node = of_node;
pdev->dev.parent = dev; pdev->dev.parent = dev;
ret = platform_device_add_data(pdev, &reg->pdata, ret = platform_device_add_data(pdev, &reg->pdata,
...@@ -1079,6 +1078,12 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) ...@@ -1079,6 +1078,12 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
platform_device_put(pdev); platform_device_put(pdev);
goto err_register; goto err_register;
} }
/*
* Set of_node only after calling platform_device_add. Otherwise
* the platform:imx-ipuv3-crtc modalias won't be used.
*/
pdev->dev.of_node = of_node;
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment