Commit 23e041db authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm/fb: fix FBIOGET/PUT_VSCREENINFO pixel clock handling
  drm: make sure page protections are updated after changing vm_flags
  drm/radeon/kms: Report vga connector is connected according to ddc_probe
  drm: mm always protect change to unused_nodes with unused_lock spinlock
  drm/radeon/kms: Disable TV load detect on RS400,RC410,RS480
  drm/radeon/kms: read back register before writing in IIO.
  drm/radeon/kms: fix handling of d1/d2 vga
  drm: work around EDIDs with bad htotal/vtotal values
  drm/radeon/kms: resume AGP by calling init.
parents f5073345 5349ef31
...@@ -662,6 +662,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, ...@@ -662,6 +662,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
return NULL; return NULL;
} }
/* Some EDIDs have bogus h/vtotal values */
if (mode->hsync_end > mode->htotal)
mode->htotal = mode->hsync_end + 1;
if (mode->vsync_end > mode->vtotal)
mode->vtotal = mode->vsync_end + 1;
drm_mode_set_name(mode); drm_mode_set_name(mode);
if (pt->misc & DRM_EDID_PT_INTERLACED) if (pt->misc & DRM_EDID_PT_INTERLACED)
......
...@@ -599,7 +599,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, ...@@ -599,7 +599,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
struct drm_framebuffer *fb = fb_helper->fb; struct drm_framebuffer *fb = fb_helper->fb;
int depth; int depth;
if (var->pixclock == -1 || !var->pixclock) if (var->pixclock != 0)
return -EINVAL; return -EINVAL;
/* Need to resize the fb object !!! */ /* Need to resize the fb object !!! */
...@@ -691,7 +691,7 @@ int drm_fb_helper_set_par(struct fb_info *info) ...@@ -691,7 +691,7 @@ int drm_fb_helper_set_par(struct fb_info *info)
int ret; int ret;
int i; int i;
if (var->pixclock != -1) { if (var->pixclock != 0) {
DRM_ERROR("PIXEL CLCOK SET\n"); DRM_ERROR("PIXEL CLCOK SET\n");
return -EINVAL; return -EINVAL;
} }
...@@ -904,7 +904,7 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev, ...@@ -904,7 +904,7 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
fb_helper->fb = fb; fb_helper->fb = fb;
if (new_fb) { if (new_fb) {
info->var.pixclock = -1; info->var.pixclock = 0;
if (register_framebuffer(info) < 0) if (register_framebuffer(info) < 0)
return -EINVAL; return -EINVAL;
} else { } else {
......
...@@ -552,7 +552,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -552,7 +552,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
vma->vm_ops = obj->dev->driver->gem_vm_ops; vma->vm_ops = obj->dev->driver->gem_vm_ops;
vma->vm_private_data = map->handle; vma->vm_private_data = map->handle;
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
/* Take a ref for this mapping of the object, so that the fault /* Take a ref for this mapping of the object, so that the fault
* handler can dereference the mmap offset's pointer to the object. * handler can dereference the mmap offset's pointer to the object.
......
...@@ -103,6 +103,11 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) ...@@ -103,6 +103,11 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
return child; return child;
} }
/* drm_mm_pre_get() - pre allocate drm_mm_node structure
* drm_mm: memory manager struct we are pre-allocating for
*
* Returns 0 on success or -ENOMEM if allocation fails.
*/
int drm_mm_pre_get(struct drm_mm *mm) int drm_mm_pre_get(struct drm_mm *mm)
{ {
struct drm_mm_node *node; struct drm_mm_node *node;
...@@ -253,12 +258,14 @@ void drm_mm_put_block(struct drm_mm_node *cur) ...@@ -253,12 +258,14 @@ void drm_mm_put_block(struct drm_mm_node *cur)
prev_node->size += next_node->size; prev_node->size += next_node->size;
list_del(&next_node->ml_entry); list_del(&next_node->ml_entry);
list_del(&next_node->fl_entry); list_del(&next_node->fl_entry);
spin_lock(&mm->unused_lock);
if (mm->num_unused < MM_UNUSED_TARGET) { if (mm->num_unused < MM_UNUSED_TARGET) {
list_add(&next_node->fl_entry, list_add(&next_node->fl_entry,
&mm->unused_nodes); &mm->unused_nodes);
++mm->num_unused; ++mm->num_unused;
} else } else
kfree(next_node); kfree(next_node);
spin_unlock(&mm->unused_lock);
} else { } else {
next_node->size += cur->size; next_node->size += cur->size;
next_node->start = cur->start; next_node->start = cur->start;
...@@ -271,11 +278,13 @@ void drm_mm_put_block(struct drm_mm_node *cur) ...@@ -271,11 +278,13 @@ void drm_mm_put_block(struct drm_mm_node *cur)
list_add(&cur->fl_entry, &mm->fl_entry); list_add(&cur->fl_entry, &mm->fl_entry);
} else { } else {
list_del(&cur->ml_entry); list_del(&cur->ml_entry);
spin_lock(&mm->unused_lock);
if (mm->num_unused < MM_UNUSED_TARGET) { if (mm->num_unused < MM_UNUSED_TARGET) {
list_add(&cur->fl_entry, &mm->unused_nodes); list_add(&cur->fl_entry, &mm->unused_nodes);
++mm->num_unused; ++mm->num_unused;
} else } else
kfree(cur); kfree(cur);
spin_unlock(&mm->unused_lock);
} }
} }
......
...@@ -107,6 +107,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, ...@@ -107,6 +107,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
base += 3; base += 3;
break; break;
case ATOM_IIO_WRITE: case ATOM_IIO_WRITE:
(void)ctx->card->reg_read(ctx->card, CU16(base + 1));
ctx->card->reg_write(ctx->card, CU16(base + 1), temp); ctx->card->reg_write(ctx->card, CU16(base + 1), temp);
base += 3; base += 3;
break; break;
......
...@@ -519,6 +519,7 @@ typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p, ...@@ -519,6 +519,7 @@ typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p,
* AGP * AGP
*/ */
int radeon_agp_init(struct radeon_device *rdev); int radeon_agp_init(struct radeon_device *rdev);
void radeon_agp_resume(struct radeon_device *rdev);
void radeon_agp_fini(struct radeon_device *rdev); void radeon_agp_fini(struct radeon_device *rdev);
......
...@@ -237,6 +237,18 @@ int radeon_agp_init(struct radeon_device *rdev) ...@@ -237,6 +237,18 @@ int radeon_agp_init(struct radeon_device *rdev)
#endif #endif
} }
void radeon_agp_resume(struct radeon_device *rdev)
{
#if __OS_HAS_AGP
int r;
if (rdev->flags & RADEON_IS_AGP) {
r = radeon_agp_init(rdev);
if (r)
dev_warn(rdev->dev, "radeon AGP reinit failed\n");
}
#endif
}
void radeon_agp_fini(struct radeon_device *rdev) void radeon_agp_fini(struct radeon_device *rdev)
{ {
#if __OS_HAS_AGP #if __OS_HAS_AGP
......
...@@ -566,8 +566,9 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect ...@@ -566,8 +566,9 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
radeon_i2c_do_lock(radeon_connector, 0); radeon_i2c_do_lock(radeon_connector, 0);
if (!radeon_connector->edid) { if (!radeon_connector->edid) {
DRM_ERROR("DDC responded but not EDID found for %s\n", DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
drm_get_connector_name(connector)); drm_get_connector_name(connector));
ret = connector_status_connected;
} else { } else {
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
...@@ -720,8 +721,8 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect ...@@ -720,8 +721,8 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
radeon_i2c_do_lock(radeon_connector, 0); radeon_i2c_do_lock(radeon_connector, 0);
if (!radeon_connector->edid) { if (!radeon_connector->edid) {
DRM_ERROR("DDC responded but not EDID found for %s\n", DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
drm_get_connector_name(connector)); drm_get_connector_name(connector));
} else { } else {
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
...@@ -1149,6 +1150,13 @@ radeon_add_legacy_connector(struct drm_device *dev, ...@@ -1149,6 +1150,13 @@ radeon_add_legacy_connector(struct drm_device *dev,
if (ret) if (ret)
goto failed; goto failed;
radeon_connector->dac_load_detect = true; radeon_connector->dac_load_detect = true;
/* RS400,RC410,RS480 chipset seems to report a lot
* of false positive on load detect, we haven't yet
* found a way to make load detect reliable on those
* chipset, thus just disable it for TV.
*/
if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480)
radeon_connector->dac_load_detect = false;
drm_connector_attach_property(&radeon_connector->base, drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property, rdev->mode_info.load_detect_property,
1); 1);
......
...@@ -688,6 +688,8 @@ int radeon_resume_kms(struct drm_device *dev) ...@@ -688,6 +688,8 @@ int radeon_resume_kms(struct drm_device *dev)
return -1; return -1;
} }
pci_set_master(dev->pdev); pci_set_master(dev->pdev);
/* resume AGP if in use */
radeon_agp_resume(rdev);
radeon_resume(rdev); radeon_resume(rdev);
radeon_restore_bios_scratch_regs(rdev); radeon_restore_bios_scratch_regs(rdev);
fb_set_suspend(rdev->fbdev_info, 0); fb_set_suspend(rdev->fbdev_info, 0);
......
...@@ -137,8 +137,6 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev) ...@@ -137,8 +137,6 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev)
void rv515_vga_render_disable(struct radeon_device *rdev) void rv515_vga_render_disable(struct radeon_device *rdev)
{ {
WREG32(R_000330_D1VGA_CONTROL, 0);
WREG32(R_000338_D2VGA_CONTROL, 0);
WREG32(R_000300_VGA_RENDER_CONTROL, WREG32(R_000300_VGA_RENDER_CONTROL,
RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL);
} }
...@@ -382,7 +380,6 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) ...@@ -382,7 +380,6 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL);
/* Stop all video */ /* Stop all video */
WREG32(R_000330_D1VGA_CONTROL, 0);
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
WREG32(R_000300_VGA_RENDER_CONTROL, 0); WREG32(R_000300_VGA_RENDER_CONTROL, 0);
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
...@@ -391,6 +388,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) ...@@ -391,6 +388,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
WREG32(R_006880_D2CRTC_CONTROL, 0); WREG32(R_006880_D2CRTC_CONTROL, 0);
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
WREG32(R_000330_D1VGA_CONTROL, 0);
WREG32(R_000338_D2VGA_CONTROL, 0);
} }
void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
...@@ -404,14 +403,14 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) ...@@ -404,14 +403,14 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control);
mdelay(1); mdelay(1);
/* Restore video state */ /* Restore video state */
WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1);
WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control);
WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control);
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control);
} }
......
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