Commit 19853301 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:
 "It's like a grab bag of one liners:

  - core: fix page flip error path, reorder object teardown.
  - usb: fix the drm_usb module license.
  - i915: VT switch on SNB with non-native modes fix, and a regression
    fix from 3.3.
  - radeon: missing unreserve on SI, AGP/VRAM setup fix (fixes radeon on
    IA64, but its a generic bug), an rn50 regression from 3.3, turn off
    MSIs on rv515 (it loses rearms every so often)."

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  nouveau: Set special lane map for the right chipset
  drm/radeon: fix load detect on rn50 with hardcoded EDIDs.
  drm: Releasing FBs before releasing GEM objects during drm_release
  drm/nouveau/pm: don't read/write beyond end of stack buffer
  drivers: gpu: drm: gma500: mdfld_dsi_output.h: Remove not unneeded include of version.h
  radeon: fix r600/agp when vram is after AGP (v3)
  drm: fix page_flip error handling
  drm/radeon/kms: fix the regression of DVI connector check
  drm/usb: fix module license on drm/usb layer.
  drm/i915: Do not set "Enable Panel Fitter" on SNB pageflips
  drm/i915: Hold mode_config lock whilst changing mode for lastclose()
  drm/radeon/si: add missing radeon_bo_unreserve in si_rlc_init() v2
  drm/radeon: disable MSI on RV515
  drm/i915: don't clobber the special upscaling lvds timings
parents 9e01297e 273a50fb
...@@ -3335,10 +3335,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, ...@@ -3335,10 +3335,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
ret = crtc->funcs->page_flip(crtc, fb, e); ret = crtc->funcs->page_flip(crtc, fb, e);
if (ret) { if (ret) {
spin_lock_irqsave(&dev->event_lock, flags); if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
file_priv->event_space += sizeof e->event; spin_lock_irqsave(&dev->event_lock, flags);
spin_unlock_irqrestore(&dev->event_lock, flags); file_priv->event_space += sizeof e->event;
kfree(e); spin_unlock_irqrestore(&dev->event_lock, flags);
kfree(e);
}
} }
out: out:
......
...@@ -507,12 +507,12 @@ int drm_release(struct inode *inode, struct file *filp) ...@@ -507,12 +507,12 @@ int drm_release(struct inode *inode, struct file *filp)
drm_events_release(file_priv); drm_events_release(file_priv);
if (dev->driver->driver_features & DRIVER_GEM)
drm_gem_release(dev, file_priv);
if (dev->driver->driver_features & DRIVER_MODESET) if (dev->driver->driver_features & DRIVER_MODESET)
drm_fb_release(file_priv); drm_fb_release(file_priv);
if (dev->driver->driver_features & DRIVER_GEM)
drm_gem_release(dev, file_priv);
mutex_lock(&dev->ctxlist_mutex); mutex_lock(&dev->ctxlist_mutex);
if (!list_empty(&dev->ctxlist)) { if (!list_empty(&dev->ctxlist)) {
struct drm_ctx_list *pos, *n; struct drm_ctx_list *pos, *n;
......
#include "drmP.h" #include "drmP.h"
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/export.h> #include <linux/module.h>
int drm_get_usb_dev(struct usb_interface *interface, int drm_get_usb_dev(struct usb_interface *interface,
const struct usb_device_id *id, const struct usb_device_id *id,
...@@ -114,3 +114,7 @@ void drm_usb_exit(struct drm_driver *driver, ...@@ -114,3 +114,7 @@ void drm_usb_exit(struct drm_driver *driver,
usb_deregister(udriver); usb_deregister(udriver);
} }
EXPORT_SYMBOL(drm_usb_exit); EXPORT_SYMBOL(drm_usb_exit);
MODULE_AUTHOR("David Airlie");
MODULE_DESCRIPTION("USB DRM support");
MODULE_LICENSE("GPL and additional rights");
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#define __MDFLD_DSI_OUTPUT_H__ #define __MDFLD_DSI_OUTPUT_H__
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/version.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm.h> #include <drm/drm.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
......
...@@ -3478,8 +3478,11 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, ...@@ -3478,8 +3478,11 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
return false; return false;
} }
/* All interlaced capable intel hw wants timings in frames. */ /* All interlaced capable intel hw wants timings in frames. Note though
drm_mode_set_crtcinfo(adjusted_mode, 0); * that intel_lvds_mode_fixup does some funny tricks with the crtc
* timings, so we need to be careful not to clobber these.*/
if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
drm_mode_set_crtcinfo(adjusted_mode, 0);
return true; return true;
} }
...@@ -7465,7 +7468,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev, ...@@ -7465,7 +7468,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
OUT_RING(fb->pitches[0] | obj->tiling_mode); OUT_RING(fb->pitches[0] | obj->tiling_mode);
OUT_RING(obj->gtt_offset); OUT_RING(obj->gtt_offset);
pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; /* Contrary to the suggestions in the documentation,
* "Enable Panel Fitter" does not seem to be required when page
* flipping with a non-native mode, and worse causes a normal
* modeset to fail.
* pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
*/
pf = 0;
pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
OUT_RING(pf | pipesrc); OUT_RING(pf | pipesrc);
ADVANCE_LP_RING(); ADVANCE_LP_RING();
......
...@@ -105,6 +105,10 @@ ...@@ -105,6 +105,10 @@
#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
#define INTEL_MODE_DP_FORCE_6BPC (0x10) #define INTEL_MODE_DP_FORCE_6BPC (0x10)
/* This flag must be set by the encoder's mode_fixup if it changes the crtc
* timings in the mode to prevent the crtc fixup from overwriting them.
* Currently only lvds needs that. */
#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)
static inline void static inline void
intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
......
...@@ -279,6 +279,8 @@ void intel_fb_restore_mode(struct drm_device *dev) ...@@ -279,6 +279,8 @@ void intel_fb_restore_mode(struct drm_device *dev)
struct drm_mode_config *config = &dev->mode_config; struct drm_mode_config *config = &dev->mode_config;
struct drm_plane *plane; struct drm_plane *plane;
mutex_lock(&dev->mode_config.mutex);
ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
if (ret) if (ret)
DRM_DEBUG("failed to restore crtc mode\n"); DRM_DEBUG("failed to restore crtc mode\n");
...@@ -286,4 +288,6 @@ void intel_fb_restore_mode(struct drm_device *dev) ...@@ -286,4 +288,6 @@ void intel_fb_restore_mode(struct drm_device *dev)
/* Be sure to shut off any planes that may be active */ /* Be sure to shut off any planes that may be active */
list_for_each_entry(plane, &config->plane_list, head) list_for_each_entry(plane, &config->plane_list, head)
plane->funcs->disable_plane(plane); plane->funcs->disable_plane(plane);
mutex_unlock(&dev->mode_config.mutex);
} }
...@@ -187,6 +187,8 @@ centre_horizontally(struct drm_display_mode *mode, ...@@ -187,6 +187,8 @@ centre_horizontally(struct drm_display_mode *mode,
mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
} }
static void static void
...@@ -208,6 +210,8 @@ centre_vertically(struct drm_display_mode *mode, ...@@ -208,6 +210,8 @@ centre_vertically(struct drm_display_mode *mode,
mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
} }
static inline u32 panel_fitter_scaling(u32 source, u32 target) static inline u32 panel_fitter_scaling(u32 source, u32 target)
...@@ -283,6 +287,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -283,6 +287,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
for_each_pipe(pipe) for_each_pipe(pipe)
I915_WRITE(BCLRPAT(pipe), 0); I915_WRITE(BCLRPAT(pipe), 0);
drm_mode_set_crtcinfo(adjusted_mode, 0);
switch (intel_lvds->fitting_mode) { switch (intel_lvds->fitting_mode) {
case DRM_MODE_SCALE_CENTER: case DRM_MODE_SCALE_CENTER:
/* /*
......
...@@ -47,8 +47,6 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, ...@@ -47,8 +47,6 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
adjusted_mode->vtotal = fixed_mode->vtotal; adjusted_mode->vtotal = fixed_mode->vtotal;
adjusted_mode->clock = fixed_mode->clock; adjusted_mode->clock = fixed_mode->clock;
drm_mode_set_crtcinfo(adjusted_mode, 0);
} }
/* adjusted_mode has been preset to be the panel's fixed mode */ /* adjusted_mode has been preset to be the panel's fixed mode */
......
...@@ -235,6 +235,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile) ...@@ -235,6 +235,7 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
return -EPERM; return -EPERM;
strncpy(string, profile, sizeof(string)); strncpy(string, profile, sizeof(string));
string[sizeof(string) - 1] = 0;
if ((ptr = strchr(string, '\n'))) if ((ptr = strchr(string, '\n')))
*ptr = '\0'; *ptr = '\0';
......
...@@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane) ...@@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane)
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */ static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */
static const u8 nv50[] = { 16, 8, 0, 24 }; static const u8 nv50[] = { 16, 8, 0, 24 };
if (dev_priv->card_type == 0xaf) if (dev_priv->chipset == 0xaf)
return nvaf[lane]; return nvaf[lane];
return nv50[lane]; return nv50[lane];
} }
......
...@@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc ...@@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc
} }
if (rdev->flags & RADEON_IS_AGP) { if (rdev->flags & RADEON_IS_AGP) {
size_bf = mc->gtt_start; size_bf = mc->gtt_start;
size_af = 0xFFFFFFFF - mc->gtt_end + 1; size_af = 0xFFFFFFFF - mc->gtt_end;
if (size_bf > size_af) { if (size_bf > size_af) {
if (mc->mc_vram_size > size_bf) { if (mc->mc_vram_size > size_bf) {
dev_warn(rdev->dev, "limiting VRAM\n"); dev_warn(rdev->dev, "limiting VRAM\n");
...@@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc ...@@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc
mc->real_vram_size = size_af; mc->real_vram_size = size_af;
mc->mc_vram_size = size_af; mc->mc_vram_size = size_af;
} }
mc->vram_start = mc->gtt_end; mc->vram_start = mc->gtt_end + 1;
} }
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
......
...@@ -970,7 +970,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ...@@ -970,7 +970,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
encoder = obj_to_encoder(obj); encoder = obj_to_encoder(obj);
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC || if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&
encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
continue; continue;
...@@ -1000,6 +1000,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ...@@ -1000,6 +1000,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
* cases the DVI port is actually a virtual KVM port connected to the service * cases the DVI port is actually a virtual KVM port connected to the service
* processor. * processor.
*/ */
out:
if ((!rdev->is_atom_bios) && if ((!rdev->is_atom_bios) &&
(ret == connector_status_disconnected) && (ret == connector_status_disconnected) &&
rdev->mode_info.bios_hardcoded_edid_size) { rdev->mode_info.bios_hardcoded_edid_size) {
...@@ -1007,7 +1008,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ...@@ -1007,7 +1008,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
ret = connector_status_connected; ret = connector_status_connected;
} }
out:
/* updated in get modes as well since we need to know if it's analog or digital */ /* updated in get modes as well since we need to know if it's analog or digital */
radeon_connector_update_scratch_regs(connector, ret); radeon_connector_update_scratch_regs(connector, ret);
return ret; return ret;
......
...@@ -147,6 +147,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev) ...@@ -147,6 +147,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev)
(rdev->pdev->subsystem_device == 0x01fd)) (rdev->pdev->subsystem_device == 0x01fd))
return true; return true;
/* RV515 seems to have MSI issues where it loses
* MSI rearms occasionally. This leads to lockups and freezes.
* disable it by default.
*/
if (rdev->family == CHIP_RV515)
return false;
if (rdev->flags & RADEON_IS_IGP) { if (rdev->flags & RADEON_IS_IGP) {
/* APUs work fine with MSIs */ /* APUs work fine with MSIs */
if (rdev->family >= CHIP_PALM) if (rdev->family >= CHIP_PALM)
......
...@@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) ...@@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
} }
if (rdev->flags & RADEON_IS_AGP) { if (rdev->flags & RADEON_IS_AGP) {
size_bf = mc->gtt_start; size_bf = mc->gtt_start;
size_af = 0xFFFFFFFF - mc->gtt_end + 1; size_af = 0xFFFFFFFF - mc->gtt_end;
if (size_bf > size_af) { if (size_bf > size_af) {
if (mc->mc_vram_size > size_bf) { if (mc->mc_vram_size > size_bf) {
dev_warn(rdev->dev, "limiting VRAM\n"); dev_warn(rdev->dev, "limiting VRAM\n");
...@@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) ...@@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
mc->real_vram_size = size_af; mc->real_vram_size = size_af;
mc->mc_vram_size = size_af; mc->mc_vram_size = size_af;
} }
mc->vram_start = mc->gtt_end; mc->vram_start = mc->gtt_end + 1;
} }
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
......
...@@ -2999,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev) ...@@ -2999,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev)
} }
r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM, r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
&rdev->rlc.save_restore_gpu_addr); &rdev->rlc.save_restore_gpu_addr);
radeon_bo_unreserve(rdev->rlc.save_restore_obj);
if (r) { if (r) {
radeon_bo_unreserve(rdev->rlc.save_restore_obj);
dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r); dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
si_rlc_fini(rdev); si_rlc_fini(rdev);
return r; return r;
...@@ -3023,9 +3023,8 @@ int si_rlc_init(struct radeon_device *rdev) ...@@ -3023,9 +3023,8 @@ int si_rlc_init(struct radeon_device *rdev)
} }
r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM, r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
&rdev->rlc.clear_state_gpu_addr); &rdev->rlc.clear_state_gpu_addr);
radeon_bo_unreserve(rdev->rlc.clear_state_obj);
if (r) { if (r) {
radeon_bo_unreserve(rdev->rlc.clear_state_obj);
dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r); dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
si_rlc_fini(rdev); si_rlc_fini(rdev);
return r; return r;
......
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