Commit a882a4d0 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:
 "For your Friday pull request stack, nothing astounding or shattering
  this week some exynos, some intel, some radeon fixes.  One intel fix
  for a regression somwehere back in 2.6.35 land."

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/radeon/kms: use frac fb div on APUs
  drm/radeon: add a missing entry to encoder_names
  drm/i915: handle input/output sdvo timings separately in mode_set
  drm/i915: fix integer overflow in i915_gem_do_execbuffer()
  drm/i915: fix integer overflow in i915_gem_execbuffer2()
  drm/exynos: added missed vm area region mapping type.
  drm/exynos: fixed exynos_drm_gem_map_pages bug.
  drm/exynos: fixed duplicatd memory allocation bug.
  drm/i915: fixup load-detect on enabled, but not active pipe
parents 78e97a47 37d4174d
...@@ -149,22 +149,12 @@ static int exynos_drm_gem_map_pages(struct drm_gem_object *obj, ...@@ -149,22 +149,12 @@ static int exynos_drm_gem_map_pages(struct drm_gem_object *obj,
unsigned long pfn; unsigned long pfn;
if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
unsigned long usize = buf->size;
if (!buf->pages) if (!buf->pages)
return -EINTR; return -EINTR;
while (usize > 0) { pfn = page_to_pfn(buf->pages[page_offset++]);
pfn = page_to_pfn(buf->pages[page_offset++]); } else
vm_insert_mixed(vma, f_vaddr, pfn); pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset;
f_vaddr += PAGE_SIZE;
usize -= PAGE_SIZE;
}
return 0;
}
pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset;
return vm_insert_mixed(vma, f_vaddr, pfn); return vm_insert_mixed(vma, f_vaddr, pfn);
} }
...@@ -524,6 +514,8 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, ...@@ -524,6 +514,8 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
if (!buffer->pages) if (!buffer->pages)
return -EINVAL; return -EINVAL;
vma->vm_flags |= VM_MIXEDMAP;
do { do {
ret = vm_insert_page(vma, uaddr, buffer->pages[i++]); ret = vm_insert_page(vma, uaddr, buffer->pages[i++]);
if (ret) { if (ret) {
...@@ -710,7 +702,6 @@ int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv, ...@@ -710,7 +702,6 @@ int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv,
int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{ {
struct drm_gem_object *obj = vma->vm_private_data; struct drm_gem_object *obj = vma->vm_private_data;
struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
struct drm_device *dev = obj->dev; struct drm_device *dev = obj->dev;
unsigned long f_vaddr; unsigned long f_vaddr;
pgoff_t page_offset; pgoff_t page_offset;
...@@ -722,21 +713,10 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -722,21 +713,10 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
/*
* allocate all pages as desired size if user wants to allocate
* physically non-continuous memory.
*/
if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
ret = exynos_drm_gem_get_pages(obj);
if (ret < 0)
goto err;
}
ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset); ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset);
if (ret < 0) if (ret < 0)
DRM_ERROR("failed to map pages.\n"); DRM_ERROR("failed to map pages.\n");
err:
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return convert_to_vm_err_msg(ret); return convert_to_vm_err_msg(ret);
......
...@@ -1133,6 +1133,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -1133,6 +1133,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
return -EINVAL; return -EINVAL;
} }
if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) {
DRM_DEBUG("execbuf with %u cliprects\n",
args->num_cliprects);
return -EINVAL;
}
cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),
GFP_KERNEL); GFP_KERNEL);
if (cliprects == NULL) { if (cliprects == NULL) {
...@@ -1404,7 +1409,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, ...@@ -1404,7 +1409,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
struct drm_i915_gem_exec_object2 *exec2_list = NULL; struct drm_i915_gem_exec_object2 *exec2_list = NULL;
int ret; int ret;
if (args->buffer_count < 1) { if (args->buffer_count < 1 ||
args->buffer_count > UINT_MAX / sizeof(*exec2_list)) {
DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count);
return -EINVAL; return -EINVAL;
} }
......
...@@ -430,8 +430,8 @@ intel_crt_detect(struct drm_connector *connector, bool force) ...@@ -430,8 +430,8 @@ intel_crt_detect(struct drm_connector *connector, bool force)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct intel_crt *crt = intel_attached_crt(connector); struct intel_crt *crt = intel_attached_crt(connector);
struct drm_crtc *crtc;
enum drm_connector_status status; enum drm_connector_status status;
struct intel_load_detect_pipe tmp;
if (I915_HAS_HOTPLUG(dev)) { if (I915_HAS_HOTPLUG(dev)) {
if (intel_crt_detect_hotplug(connector)) { if (intel_crt_detect_hotplug(connector)) {
...@@ -450,23 +450,16 @@ intel_crt_detect(struct drm_connector *connector, bool force) ...@@ -450,23 +450,16 @@ intel_crt_detect(struct drm_connector *connector, bool force)
return connector->status; return connector->status;
/* for pre-945g platforms use load detect */ /* for pre-945g platforms use load detect */
crtc = crt->base.base.crtc; if (intel_get_load_detect_pipe(&crt->base, connector, NULL,
if (crtc && crtc->enabled) { &tmp)) {
status = intel_crt_load_detect(crt); if (intel_crt_detect_ddc(connector))
} else { status = connector_status_connected;
struct intel_load_detect_pipe tmp; else
status = intel_crt_load_detect(crt);
if (intel_get_load_detect_pipe(&crt->base, connector, NULL, intel_release_load_detect_pipe(&crt->base, connector,
&tmp)) { &tmp);
if (intel_crt_detect_ddc(connector)) } else
status = connector_status_connected; status = connector_status_unknown;
else
status = intel_crt_load_detect(crt);
intel_release_load_detect_pipe(&crt->base, connector,
&tmp);
} else
status = connector_status_unknown;
}
return status; return status;
} }
......
...@@ -731,6 +731,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, ...@@ -731,6 +731,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
uint16_t width, height; uint16_t width, height;
uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
uint16_t h_sync_offset, v_sync_offset; uint16_t h_sync_offset, v_sync_offset;
int mode_clock;
width = mode->crtc_hdisplay; width = mode->crtc_hdisplay;
height = mode->crtc_vdisplay; height = mode->crtc_vdisplay;
...@@ -745,7 +746,11 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, ...@@ -745,7 +746,11 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
dtd->part1.clock = mode->clock / 10; mode_clock = mode->clock;
mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1;
mode_clock /= 10;
dtd->part1.clock = mode_clock;
dtd->part1.h_active = width & 0xff; dtd->part1.h_active = width & 0xff;
dtd->part1.h_blank = h_blank_len & 0xff; dtd->part1.h_blank = h_blank_len & 0xff;
dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | dtd->part1.h_high = (((width >> 8) & 0xf) << 4) |
...@@ -996,7 +1001,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, ...@@ -996,7 +1001,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
u32 sdvox; u32 sdvox;
struct intel_sdvo_in_out_map in_out; struct intel_sdvo_in_out_map in_out;
struct intel_sdvo_dtd input_dtd; struct intel_sdvo_dtd input_dtd, output_dtd;
int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
int rate; int rate;
...@@ -1021,20 +1026,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, ...@@ -1021,20 +1026,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
intel_sdvo->attached_output)) intel_sdvo->attached_output))
return; return;
/* We have tried to get input timing in mode_fixup, and filled into /* lvds has a special fixed output timing. */
* adjusted_mode. if (intel_sdvo->is_lvds)
*/ intel_sdvo_get_dtd_from_mode(&output_dtd,
if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { intel_sdvo->sdvo_lvds_fixed_mode);
input_dtd = intel_sdvo->input_dtd; else
} else { intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
/* Set the output timing to the screen */ (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd);
if (!intel_sdvo_set_target_output(intel_sdvo,
intel_sdvo->attached_output))
return;
intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
(void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd);
}
/* Set the input timing to the screen. Assume always input 0. */ /* Set the input timing to the screen. Assume always input 0. */
if (!intel_sdvo_set_target_input(intel_sdvo)) if (!intel_sdvo_set_target_input(intel_sdvo))
...@@ -1052,6 +1050,10 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, ...@@ -1052,6 +1050,10 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
!intel_sdvo_set_tv_format(intel_sdvo)) !intel_sdvo_set_tv_format(intel_sdvo))
return; return;
/* We have tried to get input timing in mode_fixup, and filled into
* adjusted_mode.
*/
intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
(void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd);
switch (pixel_multiplier) { switch (pixel_multiplier) {
......
...@@ -575,6 +575,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, ...@@ -575,6 +575,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (rdev->family < CHIP_RV770) if (rdev->family < CHIP_RV770)
pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
/* use frac fb div on APUs */
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
} else { } else {
pll->flags |= RADEON_PLL_LEGACY; pll->flags |= RADEON_PLL_LEGACY;
......
...@@ -533,7 +533,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index) ...@@ -533,7 +533,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
radeon_legacy_init_crtc(dev, radeon_crtc); radeon_legacy_init_crtc(dev, radeon_crtc);
} }
static const char *encoder_names[36] = { static const char *encoder_names[37] = {
"NONE", "NONE",
"INTERNAL_LVDS", "INTERNAL_LVDS",
"INTERNAL_TMDS1", "INTERNAL_TMDS1",
...@@ -570,6 +570,7 @@ static const char *encoder_names[36] = { ...@@ -570,6 +570,7 @@ static const char *encoder_names[36] = {
"INTERNAL_UNIPHY2", "INTERNAL_UNIPHY2",
"NUTMEG", "NUTMEG",
"TRAVIS", "TRAVIS",
"INTERNAL_VCE"
}; };
static const char *connector_names[15] = { static const char *connector_names[15] = {
......
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