diff options
41 files changed, 1118 insertions, 619 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 9c924614c418..dc8e374a0b55 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -707,7 +707,7 @@ int drm_fb_helper_set_par(struct fb_info *info) | |||
707 | 707 | ||
708 | if (crtc->fb == fb_helper->crtc_info[i].mode_set.fb) { | 708 | if (crtc->fb == fb_helper->crtc_info[i].mode_set.fb) { |
709 | mutex_lock(&dev->mode_config.mutex); | 709 | mutex_lock(&dev->mode_config.mutex); |
710 | ret = crtc->funcs->set_config(&fb_helper->crtc_info->mode_set); | 710 | ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set); |
711 | mutex_unlock(&dev->mode_config.mutex); | 711 | mutex_unlock(&dev->mode_config.mutex); |
712 | if (ret) | 712 | if (ret) |
713 | return ret; | 713 | return ret; |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 251bc0e3b5ec..8ac7fbf6b2b7 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -257,6 +257,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
257 | 257 | ||
258 | INIT_LIST_HEAD(&priv->lhead); | 258 | INIT_LIST_HEAD(&priv->lhead); |
259 | INIT_LIST_HEAD(&priv->fbs); | 259 | INIT_LIST_HEAD(&priv->fbs); |
260 | INIT_LIST_HEAD(&priv->event_list); | ||
261 | init_waitqueue_head(&priv->event_wait); | ||
262 | priv->event_space = 4096; /* set aside 4k for event buffer */ | ||
260 | 263 | ||
261 | if (dev->driver->driver_features & DRIVER_GEM) | 264 | if (dev->driver->driver_features & DRIVER_GEM) |
262 | drm_gem_open(dev, priv); | 265 | drm_gem_open(dev, priv); |
@@ -413,6 +416,30 @@ static void drm_master_release(struct drm_device *dev, struct file *filp) | |||
413 | } | 416 | } |
414 | } | 417 | } |
415 | 418 | ||
419 | static void drm_events_release(struct drm_file *file_priv) | ||
420 | { | ||
421 | struct drm_device *dev = file_priv->minor->dev; | ||
422 | struct drm_pending_event *e, *et; | ||
423 | struct drm_pending_vblank_event *v, *vt; | ||
424 | unsigned long flags; | ||
425 | |||
426 | spin_lock_irqsave(&dev->event_lock, flags); | ||
427 | |||
428 | /* Remove pending flips */ | ||
429 | list_for_each_entry_safe(v, vt, &dev->vblank_event_list, base.link) | ||
430 | if (v->base.file_priv == file_priv) { | ||
431 | list_del(&v->base.link); | ||
432 | drm_vblank_put(dev, v->pipe); | ||
433 | v->base.destroy(&v->base); | ||
434 | } | ||
435 | |||
436 | /* Remove unconsumed events */ | ||
437 | list_for_each_entry_safe(e, et, &file_priv->event_list, link) | ||
438 | e->destroy(e); | ||
439 | |||
440 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
441 | } | ||
442 | |||
416 | /** | 443 | /** |
417 | * Release file. | 444 | * Release file. |
418 | * | 445 | * |
@@ -451,6 +478,8 @@ int drm_release(struct inode *inode, struct file *filp) | |||
451 | if (file_priv->minor->master) | 478 | if (file_priv->minor->master) |
452 | drm_master_release(dev, filp); | 479 | drm_master_release(dev, filp); |
453 | 480 | ||
481 | drm_events_release(file_priv); | ||
482 | |||
454 | if (dev->driver->driver_features & DRIVER_GEM) | 483 | if (dev->driver->driver_features & DRIVER_GEM) |
455 | drm_gem_release(dev, file_priv); | 484 | drm_gem_release(dev, file_priv); |
456 | 485 | ||
@@ -544,9 +573,74 @@ int drm_release(struct inode *inode, struct file *filp) | |||
544 | } | 573 | } |
545 | EXPORT_SYMBOL(drm_release); | 574 | EXPORT_SYMBOL(drm_release); |
546 | 575 | ||
547 | /** No-op. */ | 576 | static bool |
577 | drm_dequeue_event(struct drm_file *file_priv, | ||
578 | size_t total, size_t max, struct drm_pending_event **out) | ||
579 | { | ||
580 | struct drm_device *dev = file_priv->minor->dev; | ||
581 | struct drm_pending_event *e; | ||
582 | unsigned long flags; | ||
583 | bool ret = false; | ||
584 | |||
585 | spin_lock_irqsave(&dev->event_lock, flags); | ||
586 | |||
587 | *out = NULL; | ||
588 | if (list_empty(&file_priv->event_list)) | ||
589 | goto out; | ||
590 | e = list_first_entry(&file_priv->event_list, | ||
591 | struct drm_pending_event, link); | ||
592 | if (e->event->length + total > max) | ||
593 | goto out; | ||
594 | |||
595 | file_priv->event_space += e->event->length; | ||
596 | list_del(&e->link); | ||
597 | *out = e; | ||
598 | ret = true; | ||
599 | |||
600 | out: | ||
601 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
602 | return ret; | ||
603 | } | ||
604 | |||
605 | ssize_t drm_read(struct file *filp, char __user *buffer, | ||
606 | size_t count, loff_t *offset) | ||
607 | { | ||
608 | struct drm_file *file_priv = filp->private_data; | ||
609 | struct drm_pending_event *e; | ||
610 | size_t total; | ||
611 | ssize_t ret; | ||
612 | |||
613 | ret = wait_event_interruptible(file_priv->event_wait, | ||
614 | !list_empty(&file_priv->event_list)); | ||
615 | if (ret < 0) | ||
616 | return ret; | ||
617 | |||
618 | total = 0; | ||
619 | while (drm_dequeue_event(file_priv, total, count, &e)) { | ||
620 | if (copy_to_user(buffer + total, | ||
621 | e->event, e->event->length)) { | ||
622 | total = -EFAULT; | ||
623 | break; | ||
624 | } | ||
625 | |||
626 | total += e->event->length; | ||
627 | e->destroy(e); | ||
628 | } | ||
629 | |||
630 | return total; | ||
631 | } | ||
632 | EXPORT_SYMBOL(drm_read); | ||
633 | |||
548 | unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) | 634 | unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) |
549 | { | 635 | { |
550 | return 0; | 636 | struct drm_file *file_priv = filp->private_data; |
637 | unsigned int mask = 0; | ||
638 | |||
639 | poll_wait(filp, &file_priv->event_wait, wait); | ||
640 | |||
641 | if (!list_empty(&file_priv->event_list)) | ||
642 | mask |= POLLIN | POLLRDNORM; | ||
643 | |||
644 | return mask; | ||
551 | } | 645 | } |
552 | EXPORT_SYMBOL(drm_poll); | 646 | EXPORT_SYMBOL(drm_poll); |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 0a6f0b3bdc78..72754aca7abf 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -550,6 +550,62 @@ out: | |||
550 | return ret; | 550 | return ret; |
551 | } | 551 | } |
552 | 552 | ||
553 | static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | ||
554 | union drm_wait_vblank *vblwait, | ||
555 | struct drm_file *file_priv) | ||
556 | { | ||
557 | struct drm_pending_vblank_event *e; | ||
558 | struct timeval now; | ||
559 | unsigned long flags; | ||
560 | unsigned int seq; | ||
561 | |||
562 | e = kzalloc(sizeof *e, GFP_KERNEL); | ||
563 | if (e == NULL) | ||
564 | return -ENOMEM; | ||
565 | |||
566 | e->pipe = pipe; | ||
567 | e->event.base.type = DRM_EVENT_VBLANK; | ||
568 | e->event.base.length = sizeof e->event; | ||
569 | e->event.user_data = vblwait->request.signal; | ||
570 | e->base.event = &e->event.base; | ||
571 | e->base.file_priv = file_priv; | ||
572 | e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; | ||
573 | |||
574 | do_gettimeofday(&now); | ||
575 | spin_lock_irqsave(&dev->event_lock, flags); | ||
576 | |||
577 | if (file_priv->event_space < sizeof e->event) { | ||
578 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
579 | kfree(e); | ||
580 | return -ENOMEM; | ||
581 | } | ||
582 | |||
583 | file_priv->event_space -= sizeof e->event; | ||
584 | seq = drm_vblank_count(dev, pipe); | ||
585 | if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) && | ||
586 | (seq - vblwait->request.sequence) <= (1 << 23)) { | ||
587 | vblwait->request.sequence = seq + 1; | ||
588 | } | ||
589 | |||
590 | DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n", | ||
591 | vblwait->request.sequence, seq, pipe); | ||
592 | |||
593 | e->event.sequence = vblwait->request.sequence; | ||
594 | if ((seq - vblwait->request.sequence) <= (1 << 23)) { | ||
595 | e->event.tv_sec = now.tv_sec; | ||
596 | e->event.tv_usec = now.tv_usec; | ||
597 | drm_vblank_put(dev, e->pipe); | ||
598 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); | ||
599 | wake_up_interruptible(&e->base.file_priv->event_wait); | ||
600 | } else { | ||
601 | list_add_tail(&e->base.link, &dev->vblank_event_list); | ||
602 | } | ||
603 | |||
604 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
605 | |||
606 | return 0; | ||
607 | } | ||
608 | |||
553 | /** | 609 | /** |
554 | * Wait for VBLANK. | 610 | * Wait for VBLANK. |
555 | * | 611 | * |
@@ -609,6 +665,9 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
609 | goto done; | 665 | goto done; |
610 | } | 666 | } |
611 | 667 | ||
668 | if (flags & _DRM_VBLANK_EVENT) | ||
669 | return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); | ||
670 | |||
612 | if ((flags & _DRM_VBLANK_NEXTONMISS) && | 671 | if ((flags & _DRM_VBLANK_NEXTONMISS) && |
613 | (seq - vblwait->request.sequence) <= (1<<23)) { | 672 | (seq - vblwait->request.sequence) <= (1<<23)) { |
614 | vblwait->request.sequence = seq + 1; | 673 | vblwait->request.sequence = seq + 1; |
@@ -641,6 +700,38 @@ done: | |||
641 | return ret; | 700 | return ret; |
642 | } | 701 | } |
643 | 702 | ||
703 | void drm_handle_vblank_events(struct drm_device *dev, int crtc) | ||
704 | { | ||
705 | struct drm_pending_vblank_event *e, *t; | ||
706 | struct timeval now; | ||
707 | unsigned long flags; | ||
708 | unsigned int seq; | ||
709 | |||
710 | do_gettimeofday(&now); | ||
711 | seq = drm_vblank_count(dev, crtc); | ||
712 | |||
713 | spin_lock_irqsave(&dev->event_lock, flags); | ||
714 | |||
715 | list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { | ||
716 | if (e->pipe != crtc) | ||
717 | continue; | ||
718 | if ((seq - e->event.sequence) > (1<<23)) | ||
719 | continue; | ||
720 | |||
721 | DRM_DEBUG("vblank event on %d, current %d\n", | ||
722 | e->event.sequence, seq); | ||
723 | |||
724 | e->event.sequence = seq; | ||
725 | e->event.tv_sec = now.tv_sec; | ||
726 | e->event.tv_usec = now.tv_usec; | ||
727 | drm_vblank_put(dev, e->pipe); | ||
728 | list_move_tail(&e->base.link, &e->base.file_priv->event_list); | ||
729 | wake_up_interruptible(&e->base.file_priv->event_wait); | ||
730 | } | ||
731 | |||
732 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
733 | } | ||
734 | |||
644 | /** | 735 | /** |
645 | * drm_handle_vblank - handle a vblank event | 736 | * drm_handle_vblank - handle a vblank event |
646 | * @dev: DRM device | 737 | * @dev: DRM device |
@@ -651,7 +742,11 @@ done: | |||
651 | */ | 742 | */ |
652 | void drm_handle_vblank(struct drm_device *dev, int crtc) | 743 | void drm_handle_vblank(struct drm_device *dev, int crtc) |
653 | { | 744 | { |
745 | if (!dev->num_crtcs) | ||
746 | return; | ||
747 | |||
654 | atomic_inc(&dev->_vblank_count[crtc]); | 748 | atomic_inc(&dev->_vblank_count[crtc]); |
655 | DRM_WAKEUP(&dev->vbl_queue[crtc]); | 749 | DRM_WAKEUP(&dev->vbl_queue[crtc]); |
750 | drm_handle_vblank_events(dev, crtc); | ||
656 | } | 751 | } |
657 | EXPORT_SYMBOL(drm_handle_vblank); | 752 | EXPORT_SYMBOL(drm_handle_vblank); |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 55bb8a82d612..adb864dfef3e 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -220,9 +220,11 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | |||
220 | INIT_LIST_HEAD(&dev->ctxlist); | 220 | INIT_LIST_HEAD(&dev->ctxlist); |
221 | INIT_LIST_HEAD(&dev->vmalist); | 221 | INIT_LIST_HEAD(&dev->vmalist); |
222 | INIT_LIST_HEAD(&dev->maplist); | 222 | INIT_LIST_HEAD(&dev->maplist); |
223 | INIT_LIST_HEAD(&dev->vblank_event_list); | ||
223 | 224 | ||
224 | spin_lock_init(&dev->count_lock); | 225 | spin_lock_init(&dev->count_lock); |
225 | spin_lock_init(&dev->drw_lock); | 226 | spin_lock_init(&dev->drw_lock); |
227 | spin_lock_init(&dev->event_lock); | ||
226 | init_timer(&dev->timer); | 228 | init_timer(&dev->timer); |
227 | mutex_init(&dev->struct_mutex); | 229 | mutex_init(&dev->struct_mutex); |
228 | mutex_init(&dev->ctxlist_mutex); | 230 | mutex_init(&dev->ctxlist_mutex); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7f436ec075f6..2fa217862058 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -333,6 +333,7 @@ static struct drm_driver driver = { | |||
333 | .mmap = drm_gem_mmap, | 333 | .mmap = drm_gem_mmap, |
334 | .poll = drm_poll, | 334 | .poll = drm_poll, |
335 | .fasync = drm_fasync, | 335 | .fasync = drm_fasync, |
336 | .read = drm_read, | ||
336 | #ifdef CONFIG_COMPAT | 337 | #ifdef CONFIG_COMPAT |
337 | .compat_ioctl = i915_compat_ioctl, | 338 | .compat_ioctl = i915_compat_ioctl, |
338 | #endif | 339 | #endif |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 5d402086bc47..c11ddddfb3b6 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
@@ -2314,7 +2314,7 @@ typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT { | |||
2314 | UCHAR ucSS_Step; | 2314 | UCHAR ucSS_Step; |
2315 | UCHAR ucSS_Delay; | 2315 | UCHAR ucSS_Delay; |
2316 | UCHAR ucSS_Id; | 2316 | UCHAR ucSS_Id; |
2317 | UCHAR ucRecommandedRef_Div; | 2317 | UCHAR ucRecommendedRef_Div; |
2318 | UCHAR ucSS_Range; /* it was reserved for V11 */ | 2318 | UCHAR ucSS_Range; /* it was reserved for V11 */ |
2319 | } ATOM_SPREAD_SPECTRUM_ASSIGNMENT; | 2319 | } ATOM_SPREAD_SPECTRUM_ASSIGNMENT; |
2320 | 2320 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 14fa9701aeb3..c15287a590ff 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -31,10 +31,6 @@ | |||
31 | #include "atom.h" | 31 | #include "atom.h" |
32 | #include "atom-bits.h" | 32 | #include "atom-bits.h" |
33 | 33 | ||
34 | /* evil but including atombios.h is much worse */ | ||
35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | ||
36 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, | ||
37 | int32_t *pixel_clock); | ||
38 | static void atombios_overscan_setup(struct drm_crtc *crtc, | 34 | static void atombios_overscan_setup(struct drm_crtc *crtc, |
39 | struct drm_display_mode *mode, | 35 | struct drm_display_mode *mode, |
40 | struct drm_display_mode *adjusted_mode) | 36 | struct drm_display_mode *adjusted_mode) |
@@ -248,18 +244,18 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
248 | 244 | ||
249 | switch (mode) { | 245 | switch (mode) { |
250 | case DRM_MODE_DPMS_ON: | 246 | case DRM_MODE_DPMS_ON: |
247 | atombios_enable_crtc(crtc, 1); | ||
251 | if (ASIC_IS_DCE3(rdev)) | 248 | if (ASIC_IS_DCE3(rdev)) |
252 | atombios_enable_crtc_memreq(crtc, 1); | 249 | atombios_enable_crtc_memreq(crtc, 1); |
253 | atombios_enable_crtc(crtc, 1); | ||
254 | atombios_blank_crtc(crtc, 0); | 250 | atombios_blank_crtc(crtc, 0); |
255 | break; | 251 | break; |
256 | case DRM_MODE_DPMS_STANDBY: | 252 | case DRM_MODE_DPMS_STANDBY: |
257 | case DRM_MODE_DPMS_SUSPEND: | 253 | case DRM_MODE_DPMS_SUSPEND: |
258 | case DRM_MODE_DPMS_OFF: | 254 | case DRM_MODE_DPMS_OFF: |
259 | atombios_blank_crtc(crtc, 1); | 255 | atombios_blank_crtc(crtc, 1); |
260 | atombios_enable_crtc(crtc, 0); | ||
261 | if (ASIC_IS_DCE3(rdev)) | 256 | if (ASIC_IS_DCE3(rdev)) |
262 | atombios_enable_crtc_memreq(crtc, 0); | 257 | atombios_enable_crtc_memreq(crtc, 0); |
258 | atombios_enable_crtc(crtc, 0); | ||
263 | break; | 259 | break; |
264 | } | 260 | } |
265 | 261 | ||
@@ -270,59 +266,147 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
270 | 266 | ||
271 | static void | 267 | static void |
272 | atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, | 268 | atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, |
273 | SET_CRTC_USING_DTD_TIMING_PARAMETERS * crtc_param) | 269 | struct drm_display_mode *mode) |
274 | { | 270 | { |
271 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
275 | struct drm_device *dev = crtc->dev; | 272 | struct drm_device *dev = crtc->dev; |
276 | struct radeon_device *rdev = dev->dev_private; | 273 | struct radeon_device *rdev = dev->dev_private; |
277 | SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param; | 274 | SET_CRTC_USING_DTD_TIMING_PARAMETERS args; |
278 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); | 275 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); |
276 | u16 misc = 0; | ||
279 | 277 | ||
280 | conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size); | 278 | memset(&args, 0, sizeof(args)); |
281 | conv_param.usH_Blanking_Time = | 279 | args.usH_Size = cpu_to_le16(mode->crtc_hdisplay); |
282 | cpu_to_le16(crtc_param->usH_Blanking_Time); | 280 | args.usH_Blanking_Time = |
283 | conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size); | 281 | cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay); |
284 | conv_param.usV_Blanking_Time = | 282 | args.usV_Size = cpu_to_le16(mode->crtc_vdisplay); |
285 | cpu_to_le16(crtc_param->usV_Blanking_Time); | 283 | args.usV_Blanking_Time = |
286 | conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset); | 284 | cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay); |
287 | conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); | 285 | args.usH_SyncOffset = |
288 | conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset); | 286 | cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay); |
289 | conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); | 287 | args.usH_SyncWidth = |
290 | conv_param.susModeMiscInfo.usAccess = | 288 | cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); |
291 | cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); | 289 | args.usV_SyncOffset = |
292 | conv_param.ucCRTC = crtc_param->ucCRTC; | 290 | cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay); |
291 | args.usV_SyncWidth = | ||
292 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); | ||
293 | /*args.ucH_Border = mode->hborder;*/ | ||
294 | /*args.ucV_Border = mode->vborder;*/ | ||
295 | |||
296 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
297 | misc |= ATOM_VSYNC_POLARITY; | ||
298 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
299 | misc |= ATOM_HSYNC_POLARITY; | ||
300 | if (mode->flags & DRM_MODE_FLAG_CSYNC) | ||
301 | misc |= ATOM_COMPOSITESYNC; | ||
302 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
303 | misc |= ATOM_INTERLACE; | ||
304 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
305 | misc |= ATOM_DOUBLE_CLOCK_MODE; | ||
306 | |||
307 | args.susModeMiscInfo.usAccess = cpu_to_le16(misc); | ||
308 | args.ucCRTC = radeon_crtc->crtc_id; | ||
293 | 309 | ||
294 | printk("executing set crtc dtd timing\n"); | 310 | printk("executing set crtc dtd timing\n"); |
295 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); | 311 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
296 | } | 312 | } |
297 | 313 | ||
298 | void atombios_crtc_set_timing(struct drm_crtc *crtc, | 314 | static void atombios_crtc_set_timing(struct drm_crtc *crtc, |
299 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION * | 315 | struct drm_display_mode *mode) |
300 | crtc_param) | ||
301 | { | 316 | { |
317 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
302 | struct drm_device *dev = crtc->dev; | 318 | struct drm_device *dev = crtc->dev; |
303 | struct radeon_device *rdev = dev->dev_private; | 319 | struct radeon_device *rdev = dev->dev_private; |
304 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param; | 320 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args; |
305 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); | 321 | int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); |
322 | u16 misc = 0; | ||
306 | 323 | ||
307 | conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total); | 324 | memset(&args, 0, sizeof(args)); |
308 | conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp); | 325 | args.usH_Total = cpu_to_le16(mode->crtc_htotal); |
309 | conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart); | 326 | args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay); |
310 | conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); | 327 | args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start); |
311 | conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total); | 328 | args.usH_SyncWidth = |
312 | conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp); | 329 | cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); |
313 | conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart); | 330 | args.usV_Total = cpu_to_le16(mode->crtc_vtotal); |
314 | conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth); | 331 | args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay); |
315 | conv_param.susModeMiscInfo.usAccess = | 332 | args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start); |
316 | cpu_to_le16(crtc_param->susModeMiscInfo.usAccess); | 333 | args.usV_SyncWidth = |
317 | conv_param.ucCRTC = crtc_param->ucCRTC; | 334 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
318 | conv_param.ucOverscanRight = crtc_param->ucOverscanRight; | 335 | |
319 | conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft; | 336 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
320 | conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom; | 337 | misc |= ATOM_VSYNC_POLARITY; |
321 | conv_param.ucOverscanTop = crtc_param->ucOverscanTop; | 338 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
322 | conv_param.ucReserved = crtc_param->ucReserved; | 339 | misc |= ATOM_HSYNC_POLARITY; |
340 | if (mode->flags & DRM_MODE_FLAG_CSYNC) | ||
341 | misc |= ATOM_COMPOSITESYNC; | ||
342 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
343 | misc |= ATOM_INTERLACE; | ||
344 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
345 | misc |= ATOM_DOUBLE_CLOCK_MODE; | ||
346 | |||
347 | args.susModeMiscInfo.usAccess = cpu_to_le16(misc); | ||
348 | args.ucCRTC = radeon_crtc->crtc_id; | ||
323 | 349 | ||
324 | printk("executing set crtc timing\n"); | 350 | printk("executing set crtc timing\n"); |
325 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); | 351 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
352 | } | ||
353 | |||
354 | static void atombios_set_ss(struct drm_crtc *crtc, int enable) | ||
355 | { | ||
356 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
357 | struct drm_device *dev = crtc->dev; | ||
358 | struct radeon_device *rdev = dev->dev_private; | ||
359 | struct drm_encoder *encoder = NULL; | ||
360 | struct radeon_encoder *radeon_encoder = NULL; | ||
361 | struct radeon_encoder_atom_dig *dig = NULL; | ||
362 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); | ||
363 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION args; | ||
364 | ENABLE_LVDS_SS_PARAMETERS legacy_args; | ||
365 | uint16_t percentage = 0; | ||
366 | uint8_t type = 0, step = 0, delay = 0, range = 0; | ||
367 | |||
368 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
369 | if (encoder->crtc == crtc) { | ||
370 | radeon_encoder = to_radeon_encoder(encoder); | ||
371 | /* only enable spread spectrum on LVDS */ | ||
372 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | ||
373 | dig = radeon_encoder->enc_priv; | ||
374 | if (dig && dig->ss) { | ||
375 | percentage = dig->ss->percentage; | ||
376 | type = dig->ss->type; | ||
377 | step = dig->ss->step; | ||
378 | delay = dig->ss->delay; | ||
379 | range = dig->ss->range; | ||
380 | } else if (enable) | ||
381 | return; | ||
382 | } else if (enable) | ||
383 | return; | ||
384 | break; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | if (!radeon_encoder) | ||
389 | return; | ||
390 | |||
391 | if (ASIC_IS_AVIVO(rdev)) { | ||
392 | memset(&args, 0, sizeof(args)); | ||
393 | args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); | ||
394 | args.ucSpreadSpectrumType = type; | ||
395 | args.ucSpreadSpectrumStep = step; | ||
396 | args.ucSpreadSpectrumDelay = delay; | ||
397 | args.ucSpreadSpectrumRange = range; | ||
398 | args.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; | ||
399 | args.ucEnable = enable; | ||
400 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
401 | } else { | ||
402 | memset(&legacy_args, 0, sizeof(legacy_args)); | ||
403 | legacy_args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); | ||
404 | legacy_args.ucSpreadSpectrumType = type; | ||
405 | legacy_args.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; | ||
406 | legacy_args.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; | ||
407 | legacy_args.ucEnable = enable; | ||
408 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&legacy_args); | ||
409 | } | ||
326 | } | 410 | } |
327 | 411 | ||
328 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | 412 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) |
@@ -333,12 +417,13 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
333 | struct drm_encoder *encoder = NULL; | 417 | struct drm_encoder *encoder = NULL; |
334 | struct radeon_encoder *radeon_encoder = NULL; | 418 | struct radeon_encoder *radeon_encoder = NULL; |
335 | uint8_t frev, crev; | 419 | uint8_t frev, crev; |
336 | int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); | 420 | int index; |
337 | SET_PIXEL_CLOCK_PS_ALLOCATION args; | 421 | SET_PIXEL_CLOCK_PS_ALLOCATION args; |
338 | PIXEL_CLOCK_PARAMETERS *spc1_ptr; | 422 | PIXEL_CLOCK_PARAMETERS *spc1_ptr; |
339 | PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; | 423 | PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; |
340 | PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; | 424 | PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; |
341 | uint32_t sclock = mode->clock; | 425 | uint32_t pll_clock = mode->clock; |
426 | uint32_t adjusted_clock; | ||
342 | uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | 427 | uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; |
343 | struct radeon_pll *pll; | 428 | struct radeon_pll *pll; |
344 | int pll_flags = 0; | 429 | int pll_flags = 0; |
@@ -346,8 +431,6 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
346 | memset(&args, 0, sizeof(args)); | 431 | memset(&args, 0, sizeof(args)); |
347 | 432 | ||
348 | if (ASIC_IS_AVIVO(rdev)) { | 433 | if (ASIC_IS_AVIVO(rdev)) { |
349 | uint32_t ss_cntl; | ||
350 | |||
351 | if ((rdev->family == CHIP_RS600) || | 434 | if ((rdev->family == CHIP_RS600) || |
352 | (rdev->family == CHIP_RS690) || | 435 | (rdev->family == CHIP_RS690) || |
353 | (rdev->family == CHIP_RS740)) | 436 | (rdev->family == CHIP_RS740)) |
@@ -358,15 +441,6 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
358 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 441 | pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
359 | else | 442 | else |
360 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 443 | pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
361 | |||
362 | /* disable spread spectrum clocking for now -- thanks Hedy Lamarr */ | ||
363 | if (radeon_crtc->crtc_id == 0) { | ||
364 | ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); | ||
365 | WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl & ~1); | ||
366 | } else { | ||
367 | ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL); | ||
368 | WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl & ~1); | ||
369 | } | ||
370 | } else { | 444 | } else { |
371 | pll_flags |= RADEON_PLL_LEGACY; | 445 | pll_flags |= RADEON_PLL_LEGACY; |
372 | 446 | ||
@@ -393,14 +467,43 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
393 | } | 467 | } |
394 | } | 468 | } |
395 | 469 | ||
470 | /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock | ||
471 | * accordingly based on the encoder/transmitter to work around | ||
472 | * special hw requirements. | ||
473 | */ | ||
474 | if (ASIC_IS_DCE3(rdev)) { | ||
475 | ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args; | ||
476 | |||
477 | if (!encoder) | ||
478 | return; | ||
479 | |||
480 | memset(&adjust_pll_args, 0, sizeof(adjust_pll_args)); | ||
481 | adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10); | ||
482 | adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id; | ||
483 | adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder); | ||
484 | |||
485 | index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); | ||
486 | atom_execute_table(rdev->mode_info.atom_context, | ||
487 | index, (uint32_t *)&adjust_pll_args); | ||
488 | adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10; | ||
489 | } else { | ||
490 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | ||
491 | if (ASIC_IS_AVIVO(rdev) && | ||
492 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)) | ||
493 | adjusted_clock = mode->clock * 2; | ||
494 | else | ||
495 | adjusted_clock = mode->clock; | ||
496 | } | ||
497 | |||
396 | if (radeon_crtc->crtc_id == 0) | 498 | if (radeon_crtc->crtc_id == 0) |
397 | pll = &rdev->clock.p1pll; | 499 | pll = &rdev->clock.p1pll; |
398 | else | 500 | else |
399 | pll = &rdev->clock.p2pll; | 501 | pll = &rdev->clock.p2pll; |
400 | 502 | ||
401 | radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div, | 503 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
402 | &ref_div, &post_div, pll_flags); | 504 | &ref_div, &post_div, pll_flags); |
403 | 505 | ||
506 | index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); | ||
404 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, | 507 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, |
405 | &crev); | 508 | &crev); |
406 | 509 | ||
@@ -409,7 +512,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
409 | switch (crev) { | 512 | switch (crev) { |
410 | case 1: | 513 | case 1: |
411 | spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; | 514 | spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; |
412 | spc1_ptr->usPixelClock = cpu_to_le16(sclock); | 515 | spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); |
413 | spc1_ptr->usRefDiv = cpu_to_le16(ref_div); | 516 | spc1_ptr->usRefDiv = cpu_to_le16(ref_div); |
414 | spc1_ptr->usFbDiv = cpu_to_le16(fb_div); | 517 | spc1_ptr->usFbDiv = cpu_to_le16(fb_div); |
415 | spc1_ptr->ucFracFbDiv = frac_fb_div; | 518 | spc1_ptr->ucFracFbDiv = frac_fb_div; |
@@ -422,7 +525,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
422 | case 2: | 525 | case 2: |
423 | spc2_ptr = | 526 | spc2_ptr = |
424 | (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; | 527 | (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; |
425 | spc2_ptr->usPixelClock = cpu_to_le16(sclock); | 528 | spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); |
426 | spc2_ptr->usRefDiv = cpu_to_le16(ref_div); | 529 | spc2_ptr->usRefDiv = cpu_to_le16(ref_div); |
427 | spc2_ptr->usFbDiv = cpu_to_le16(fb_div); | 530 | spc2_ptr->usFbDiv = cpu_to_le16(fb_div); |
428 | spc2_ptr->ucFracFbDiv = frac_fb_div; | 531 | spc2_ptr->ucFracFbDiv = frac_fb_div; |
@@ -437,7 +540,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
437 | return; | 540 | return; |
438 | spc3_ptr = | 541 | spc3_ptr = |
439 | (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; | 542 | (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; |
440 | spc3_ptr->usPixelClock = cpu_to_le16(sclock); | 543 | spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); |
441 | spc3_ptr->usRefDiv = cpu_to_le16(ref_div); | 544 | spc3_ptr->usRefDiv = cpu_to_le16(ref_div); |
442 | spc3_ptr->usFbDiv = cpu_to_le16(fb_div); | 545 | spc3_ptr->usFbDiv = cpu_to_le16(fb_div); |
443 | spc3_ptr->ucFracFbDiv = frac_fb_div; | 546 | spc3_ptr->ucFracFbDiv = frac_fb_div; |
@@ -527,6 +630,16 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
527 | WREG32(AVIVO_D1VGA_CONTROL, 0); | 630 | WREG32(AVIVO_D1VGA_CONTROL, 0); |
528 | else | 631 | else |
529 | WREG32(AVIVO_D2VGA_CONTROL, 0); | 632 | WREG32(AVIVO_D2VGA_CONTROL, 0); |
633 | |||
634 | if (rdev->family >= CHIP_RV770) { | ||
635 | if (radeon_crtc->crtc_id) { | ||
636 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | ||
637 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | ||
638 | } else { | ||
639 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | ||
640 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | ||
641 | } | ||
642 | } | ||
530 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | 643 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
531 | (u32) fb_location); | 644 | (u32) fb_location); |
532 | WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + | 645 | WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + |
@@ -563,6 +676,10 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
563 | radeon_fb = to_radeon_framebuffer(old_fb); | 676 | radeon_fb = to_radeon_framebuffer(old_fb); |
564 | radeon_gem_object_unpin(radeon_fb->obj); | 677 | radeon_gem_object_unpin(radeon_fb->obj); |
565 | } | 678 | } |
679 | |||
680 | /* Bytes per pixel may have changed */ | ||
681 | radeon_bandwidth_update(rdev); | ||
682 | |||
566 | return 0; | 683 | return 0; |
567 | } | 684 | } |
568 | 685 | ||
@@ -574,134 +691,24 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
574 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 691 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
575 | struct drm_device *dev = crtc->dev; | 692 | struct drm_device *dev = crtc->dev; |
576 | struct radeon_device *rdev = dev->dev_private; | 693 | struct radeon_device *rdev = dev->dev_private; |
577 | struct drm_encoder *encoder; | ||
578 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; | ||
579 | int need_tv_timings = 0; | ||
580 | bool ret; | ||
581 | 694 | ||
582 | /* TODO color tiling */ | 695 | /* TODO color tiling */ |
583 | memset(&crtc_timing, 0, sizeof(crtc_timing)); | ||
584 | |||
585 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
586 | /* find tv std */ | ||
587 | if (encoder->crtc == crtc) { | ||
588 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
589 | |||
590 | if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { | ||
591 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
592 | if (tv_dac) { | ||
593 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
594 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
595 | tv_dac->tv_std == TV_STD_PAL_M) | ||
596 | need_tv_timings = 1; | ||
597 | else | ||
598 | need_tv_timings = 2; | ||
599 | break; | ||
600 | } | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | |||
605 | crtc_timing.ucCRTC = radeon_crtc->crtc_id; | ||
606 | if (need_tv_timings) { | ||
607 | ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1, | ||
608 | &crtc_timing, &adjusted_mode->clock); | ||
609 | if (ret == false) | ||
610 | need_tv_timings = 0; | ||
611 | } | ||
612 | |||
613 | if (!need_tv_timings) { | ||
614 | crtc_timing.usH_Total = adjusted_mode->crtc_htotal; | ||
615 | crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; | ||
616 | crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; | ||
617 | crtc_timing.usH_SyncWidth = | ||
618 | adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; | ||
619 | |||
620 | crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; | ||
621 | crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; | ||
622 | crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; | ||
623 | crtc_timing.usV_SyncWidth = | ||
624 | adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; | ||
625 | |||
626 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
627 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; | ||
628 | |||
629 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
630 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; | ||
631 | |||
632 | if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) | ||
633 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; | ||
634 | |||
635 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
636 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; | ||
637 | |||
638 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
639 | crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; | ||
640 | } | ||
641 | 696 | ||
697 | atombios_set_ss(crtc, 0); | ||
642 | atombios_crtc_set_pll(crtc, adjusted_mode); | 698 | atombios_crtc_set_pll(crtc, adjusted_mode); |
643 | atombios_crtc_set_timing(crtc, &crtc_timing); | 699 | atombios_set_ss(crtc, 1); |
700 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
644 | 701 | ||
645 | if (ASIC_IS_AVIVO(rdev)) | 702 | if (ASIC_IS_AVIVO(rdev)) |
646 | atombios_crtc_set_base(crtc, x, y, old_fb); | 703 | atombios_crtc_set_base(crtc, x, y, old_fb); |
647 | else { | 704 | else { |
648 | if (radeon_crtc->crtc_id == 0) { | 705 | if (radeon_crtc->crtc_id == 0) |
649 | SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing; | 706 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
650 | memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing)); | ||
651 | |||
652 | /* setup FP shadow regs on R4xx */ | ||
653 | crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id; | ||
654 | crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay; | ||
655 | crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay; | ||
656 | crtc_dtd_timing.usH_Blanking_Time = | ||
657 | adjusted_mode->crtc_hblank_end - | ||
658 | adjusted_mode->crtc_hdisplay; | ||
659 | crtc_dtd_timing.usV_Blanking_Time = | ||
660 | adjusted_mode->crtc_vblank_end - | ||
661 | adjusted_mode->crtc_vdisplay; | ||
662 | crtc_dtd_timing.usH_SyncOffset = | ||
663 | adjusted_mode->crtc_hsync_start - | ||
664 | adjusted_mode->crtc_hdisplay; | ||
665 | crtc_dtd_timing.usV_SyncOffset = | ||
666 | adjusted_mode->crtc_vsync_start - | ||
667 | adjusted_mode->crtc_vdisplay; | ||
668 | crtc_dtd_timing.usH_SyncWidth = | ||
669 | adjusted_mode->crtc_hsync_end - | ||
670 | adjusted_mode->crtc_hsync_start; | ||
671 | crtc_dtd_timing.usV_SyncWidth = | ||
672 | adjusted_mode->crtc_vsync_end - | ||
673 | adjusted_mode->crtc_vsync_start; | ||
674 | /* crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder; */ | ||
675 | /* crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder; */ | ||
676 | |||
677 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
678 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
679 | ATOM_VSYNC_POLARITY; | ||
680 | |||
681 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
682 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
683 | ATOM_HSYNC_POLARITY; | ||
684 | |||
685 | if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) | ||
686 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
687 | ATOM_COMPOSITESYNC; | ||
688 | |||
689 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
690 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
691 | ATOM_INTERLACE; | ||
692 | |||
693 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) | ||
694 | crtc_dtd_timing.susModeMiscInfo.usAccess |= | ||
695 | ATOM_DOUBLE_CLOCK_MODE; | ||
696 | |||
697 | atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing); | ||
698 | } | ||
699 | radeon_crtc_set_base(crtc, x, y, old_fb); | 707 | radeon_crtc_set_base(crtc, x, y, old_fb); |
700 | radeon_legacy_atom_set_surface(crtc); | 708 | radeon_legacy_atom_set_surface(crtc); |
701 | } | 709 | } |
702 | atombios_overscan_setup(crtc, mode, adjusted_mode); | 710 | atombios_overscan_setup(crtc, mode, adjusted_mode); |
703 | atombios_scaler_setup(crtc); | 711 | atombios_scaler_setup(crtc); |
704 | radeon_bandwidth_update(rdev); | ||
705 | return 0; | 712 | return 0; |
706 | } | 713 | } |
707 | 714 | ||
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 161094c07d94..c9e93eabcf16 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -186,7 +186,7 @@ static inline uint32_t r100_irq_ack(struct radeon_device *rdev) | |||
186 | 186 | ||
187 | int r100_irq_process(struct radeon_device *rdev) | 187 | int r100_irq_process(struct radeon_device *rdev) |
188 | { | 188 | { |
189 | uint32_t status; | 189 | uint32_t status, msi_rearm; |
190 | 190 | ||
191 | status = r100_irq_ack(rdev); | 191 | status = r100_irq_ack(rdev); |
192 | if (!status) { | 192 | if (!status) { |
@@ -209,6 +209,21 @@ int r100_irq_process(struct radeon_device *rdev) | |||
209 | } | 209 | } |
210 | status = r100_irq_ack(rdev); | 210 | status = r100_irq_ack(rdev); |
211 | } | 211 | } |
212 | if (rdev->msi_enabled) { | ||
213 | switch (rdev->family) { | ||
214 | case CHIP_RS400: | ||
215 | case CHIP_RS480: | ||
216 | msi_rearm = RREG32(RADEON_AIC_CNTL) & ~RS400_MSI_REARM; | ||
217 | WREG32(RADEON_AIC_CNTL, msi_rearm); | ||
218 | WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); | ||
219 | break; | ||
220 | default: | ||
221 | msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; | ||
222 | WREG32(RADEON_MSI_REARM_EN, msi_rearm); | ||
223 | WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); | ||
224 | break; | ||
225 | } | ||
226 | } | ||
212 | return IRQ_HANDLED; | 227 | return IRQ_HANDLED; |
213 | } | 228 | } |
214 | 229 | ||
@@ -240,7 +255,7 @@ int r100_wb_init(struct radeon_device *rdev) | |||
240 | int r; | 255 | int r; |
241 | 256 | ||
242 | if (rdev->wb.wb_obj == NULL) { | 257 | if (rdev->wb.wb_obj == NULL) { |
243 | r = radeon_object_create(rdev, NULL, 4096, | 258 | r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, |
244 | true, | 259 | true, |
245 | RADEON_GEM_DOMAIN_GTT, | 260 | RADEON_GEM_DOMAIN_GTT, |
246 | false, &rdev->wb.wb_obj); | 261 | false, &rdev->wb.wb_obj); |
@@ -563,19 +578,19 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
563 | indirect1_start = 16; | 578 | indirect1_start = 16; |
564 | /* cp setup */ | 579 | /* cp setup */ |
565 | WREG32(0x718, pre_write_timer | (pre_write_limit << 28)); | 580 | WREG32(0x718, pre_write_timer | (pre_write_limit << 28)); |
566 | WREG32(RADEON_CP_RB_CNTL, | 581 | tmp = (REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | |
567 | #ifdef __BIG_ENDIAN | ||
568 | RADEON_BUF_SWAP_32BIT | | ||
569 | #endif | ||
570 | REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | | ||
571 | REG_SET(RADEON_RB_BLKSZ, rb_blksz) | | 582 | REG_SET(RADEON_RB_BLKSZ, rb_blksz) | |
572 | REG_SET(RADEON_MAX_FETCH, max_fetch) | | 583 | REG_SET(RADEON_MAX_FETCH, max_fetch) | |
573 | RADEON_RB_NO_UPDATE); | 584 | RADEON_RB_NO_UPDATE); |
585 | #ifdef __BIG_ENDIAN | ||
586 | tmp |= RADEON_BUF_SWAP_32BIT; | ||
587 | #endif | ||
588 | WREG32(RADEON_CP_RB_CNTL, tmp); | ||
589 | |||
574 | /* Set ring address */ | 590 | /* Set ring address */ |
575 | DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr); | 591 | DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr); |
576 | WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr); | 592 | WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr); |
577 | /* Force read & write ptr to 0 */ | 593 | /* Force read & write ptr to 0 */ |
578 | tmp = RREG32(RADEON_CP_RB_CNTL); | ||
579 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); | 594 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); |
580 | WREG32(RADEON_CP_RB_RPTR_WR, 0); | 595 | WREG32(RADEON_CP_RB_RPTR_WR, 0); |
581 | WREG32(RADEON_CP_RB_WPTR, 0); | 596 | WREG32(RADEON_CP_RB_WPTR, 0); |
@@ -2364,7 +2379,7 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
2364 | /* | 2379 | /* |
2365 | Find the total latency for the display data. | 2380 | Find the total latency for the display data. |
2366 | */ | 2381 | */ |
2367 | disp_latency_overhead.full = rfixed_const(80); | 2382 | disp_latency_overhead.full = rfixed_const(8); |
2368 | disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff); | 2383 | disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff); |
2369 | mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full; | 2384 | mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full; |
2370 | mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full; | 2385 | mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full; |
@@ -2562,8 +2577,11 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
2562 | static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) | 2577 | static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) |
2563 | { | 2578 | { |
2564 | DRM_ERROR("pitch %d\n", t->pitch); | 2579 | DRM_ERROR("pitch %d\n", t->pitch); |
2580 | DRM_ERROR("use_pitch %d\n", t->use_pitch); | ||
2565 | DRM_ERROR("width %d\n", t->width); | 2581 | DRM_ERROR("width %d\n", t->width); |
2582 | DRM_ERROR("width_11 %d\n", t->width_11); | ||
2566 | DRM_ERROR("height %d\n", t->height); | 2583 | DRM_ERROR("height %d\n", t->height); |
2584 | DRM_ERROR("height_11 %d\n", t->height_11); | ||
2567 | DRM_ERROR("num levels %d\n", t->num_levels); | 2585 | DRM_ERROR("num levels %d\n", t->num_levels); |
2568 | DRM_ERROR("depth %d\n", t->txdepth); | 2586 | DRM_ERROR("depth %d\n", t->txdepth); |
2569 | DRM_ERROR("bpp %d\n", t->cpp); | 2587 | DRM_ERROR("bpp %d\n", t->cpp); |
@@ -2623,15 +2641,17 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, | |||
2623 | else | 2641 | else |
2624 | w = track->textures[u].pitch / (1 << i); | 2642 | w = track->textures[u].pitch / (1 << i); |
2625 | } else { | 2643 | } else { |
2626 | w = track->textures[u].width / (1 << i); | 2644 | w = track->textures[u].width; |
2627 | if (rdev->family >= CHIP_RV515) | 2645 | if (rdev->family >= CHIP_RV515) |
2628 | w |= track->textures[u].width_11; | 2646 | w |= track->textures[u].width_11; |
2647 | w = w / (1 << i); | ||
2629 | if (track->textures[u].roundup_w) | 2648 | if (track->textures[u].roundup_w) |
2630 | w = roundup_pow_of_two(w); | 2649 | w = roundup_pow_of_two(w); |
2631 | } | 2650 | } |
2632 | h = track->textures[u].height / (1 << i); | 2651 | h = track->textures[u].height; |
2633 | if (rdev->family >= CHIP_RV515) | 2652 | if (rdev->family >= CHIP_RV515) |
2634 | h |= track->textures[u].height_11; | 2653 | h |= track->textures[u].height_11; |
2654 | h = h / (1 << i); | ||
2635 | if (track->textures[u].roundup_h) | 2655 | if (track->textures[u].roundup_h) |
2636 | h = roundup_pow_of_two(h); | 2656 | h = roundup_pow_of_two(h); |
2637 | size += w * h; | 2657 | size += w * h; |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index e08c4a8974ca..2f43ee8e4048 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -113,7 +113,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) | |||
113 | tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; | 113 | tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; |
114 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); | 114 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); |
115 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location); | 115 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location); |
116 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 4096; | 116 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - RADEON_GPU_PAGE_SIZE; |
117 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp); | 117 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp); |
118 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); | 118 | WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); |
119 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); | 119 | WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 868add6e166d..7baa73955563 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
@@ -384,9 +384,16 @@ | |||
384 | # define AVIVO_D1GRPH_TILED (1 << 20) | 384 | # define AVIVO_D1GRPH_TILED (1 << 20) |
385 | # define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) | 385 | # define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) |
386 | 386 | ||
387 | /* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2 | ||
388 | * block and vice versa. This applies to GRPH, CUR, etc. | ||
389 | */ | ||
387 | #define AVIVO_D1GRPH_LUT_SEL 0x6108 | 390 | #define AVIVO_D1GRPH_LUT_SEL 0x6108 |
388 | #define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 | 391 | #define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 |
392 | #define R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 | ||
393 | #define R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 | ||
389 | #define AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 | 394 | #define AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 |
395 | #define R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c | ||
396 | #define R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c | ||
390 | #define AVIVO_D1GRPH_PITCH 0x6120 | 397 | #define AVIVO_D1GRPH_PITCH 0x6120 |
391 | #define AVIVO_D1GRPH_SURFACE_OFFSET_X 0x6124 | 398 | #define AVIVO_D1GRPH_SURFACE_OFFSET_X 0x6124 |
392 | #define AVIVO_D1GRPH_SURFACE_OFFSET_Y 0x6128 | 399 | #define AVIVO_D1GRPH_SURFACE_OFFSET_Y 0x6128 |
@@ -404,6 +411,8 @@ | |||
404 | # define AVIVO_D1CURSOR_MODE_MASK (3 << 8) | 411 | # define AVIVO_D1CURSOR_MODE_MASK (3 << 8) |
405 | # define AVIVO_D1CURSOR_MODE_24BPP 2 | 412 | # define AVIVO_D1CURSOR_MODE_24BPP 2 |
406 | #define AVIVO_D1CUR_SURFACE_ADDRESS 0x6408 | 413 | #define AVIVO_D1CUR_SURFACE_ADDRESS 0x6408 |
414 | #define R700_D1CUR_SURFACE_ADDRESS_HIGH 0x6c0c | ||
415 | #define R700_D2CUR_SURFACE_ADDRESS_HIGH 0x640c | ||
407 | #define AVIVO_D1CUR_SIZE 0x6410 | 416 | #define AVIVO_D1CUR_SIZE 0x6410 |
408 | #define AVIVO_D1CUR_POSITION 0x6414 | 417 | #define AVIVO_D1CUR_POSITION 0x6414 |
409 | #define AVIVO_D1CUR_HOT_SPOT 0x6418 | 418 | #define AVIVO_D1CUR_HOT_SPOT 0x6418 |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 609719490ec2..00cd0500ca7f 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -339,11 +339,10 @@ int r600_mc_init(struct radeon_device *rdev) | |||
339 | { | 339 | { |
340 | fixed20_12 a; | 340 | fixed20_12 a; |
341 | u32 tmp; | 341 | u32 tmp; |
342 | int chansize; | 342 | int chansize, numchan; |
343 | int r; | 343 | int r; |
344 | 344 | ||
345 | /* Get VRAM informations */ | 345 | /* Get VRAM informations */ |
346 | rdev->mc.vram_width = 128; | ||
347 | rdev->mc.vram_is_ddr = true; | 346 | rdev->mc.vram_is_ddr = true; |
348 | tmp = RREG32(RAMCFG); | 347 | tmp = RREG32(RAMCFG); |
349 | if (tmp & CHANSIZE_OVERRIDE) { | 348 | if (tmp & CHANSIZE_OVERRIDE) { |
@@ -353,17 +352,23 @@ int r600_mc_init(struct radeon_device *rdev) | |||
353 | } else { | 352 | } else { |
354 | chansize = 32; | 353 | chansize = 32; |
355 | } | 354 | } |
356 | if (rdev->family == CHIP_R600) { | 355 | tmp = RREG32(CHMAP); |
357 | rdev->mc.vram_width = 8 * chansize; | 356 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { |
358 | } else if (rdev->family == CHIP_RV670) { | 357 | case 0: |
359 | rdev->mc.vram_width = 4 * chansize; | 358 | default: |
360 | } else if ((rdev->family == CHIP_RV610) || | 359 | numchan = 1; |
361 | (rdev->family == CHIP_RV620)) { | 360 | break; |
362 | rdev->mc.vram_width = chansize; | 361 | case 1: |
363 | } else if ((rdev->family == CHIP_RV630) || | 362 | numchan = 2; |
364 | (rdev->family == CHIP_RV635)) { | 363 | break; |
365 | rdev->mc.vram_width = 2 * chansize; | 364 | case 2: |
365 | numchan = 4; | ||
366 | break; | ||
367 | case 3: | ||
368 | numchan = 8; | ||
369 | break; | ||
366 | } | 370 | } |
371 | rdev->mc.vram_width = numchan * chansize; | ||
367 | /* Could aper size report 0 ? */ | 372 | /* Could aper size report 0 ? */ |
368 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 373 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
369 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 374 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
@@ -404,35 +409,29 @@ int r600_mc_init(struct radeon_device *rdev) | |||
404 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | 409 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; |
405 | } | 410 | } |
406 | } else { | 411 | } else { |
407 | if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) { | 412 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
408 | rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) & | 413 | rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) & |
409 | 0xFFFF) << 24; | 414 | 0xFFFF) << 24; |
410 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | 415 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size; |
411 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size; | 416 | if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) { |
412 | if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) { | 417 | /* Enough place after vram */ |
413 | /* Enough place after vram */ | 418 | rdev->mc.gtt_location = tmp; |
414 | rdev->mc.gtt_location = tmp; | 419 | } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) { |
415 | } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) { | 420 | /* Enough place before vram */ |
416 | /* Enough place before vram */ | 421 | rdev->mc.gtt_location = 0; |
422 | } else { | ||
423 | /* Not enough place after or before shrink | ||
424 | * gart size | ||
425 | */ | ||
426 | if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) { | ||
417 | rdev->mc.gtt_location = 0; | 427 | rdev->mc.gtt_location = 0; |
428 | rdev->mc.gtt_size = rdev->mc.vram_location; | ||
418 | } else { | 429 | } else { |
419 | /* Not enough place after or before shrink | 430 | rdev->mc.gtt_location = tmp; |
420 | * gart size | 431 | rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp; |
421 | */ | ||
422 | if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) { | ||
423 | rdev->mc.gtt_location = 0; | ||
424 | rdev->mc.gtt_size = rdev->mc.vram_location; | ||
425 | } else { | ||
426 | rdev->mc.gtt_location = tmp; | ||
427 | rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp; | ||
428 | } | ||
429 | } | 432 | } |
430 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
431 | } else { | ||
432 | rdev->mc.vram_location = 0x00000000UL; | ||
433 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
434 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
435 | } | 433 | } |
434 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
436 | } | 435 | } |
437 | rdev->mc.vram_start = rdev->mc.vram_location; | 436 | rdev->mc.vram_start = rdev->mc.vram_location; |
438 | rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; | 437 | rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; |
@@ -1267,19 +1266,17 @@ int r600_cp_resume(struct radeon_device *rdev) | |||
1267 | 1266 | ||
1268 | /* Set ring buffer size */ | 1267 | /* Set ring buffer size */ |
1269 | rb_bufsz = drm_order(rdev->cp.ring_size / 8); | 1268 | rb_bufsz = drm_order(rdev->cp.ring_size / 8); |
1269 | tmp = RB_NO_UPDATE | (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; | ||
1270 | #ifdef __BIG_ENDIAN | 1270 | #ifdef __BIG_ENDIAN |
1271 | WREG32(CP_RB_CNTL, BUF_SWAP_32BIT | RB_NO_UPDATE | | 1271 | tmp |= BUF_SWAP_32BIT; |
1272 | (drm_order(4096/8) << 8) | rb_bufsz); | ||
1273 | #else | ||
1274 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | (drm_order(4096/8) << 8) | rb_bufsz); | ||
1275 | #endif | 1272 | #endif |
1273 | WREG32(CP_RB_CNTL, tmp); | ||
1276 | WREG32(CP_SEM_WAIT_TIMER, 0x4); | 1274 | WREG32(CP_SEM_WAIT_TIMER, 0x4); |
1277 | 1275 | ||
1278 | /* Set the write pointer delay */ | 1276 | /* Set the write pointer delay */ |
1279 | WREG32(CP_RB_WPTR_DELAY, 0); | 1277 | WREG32(CP_RB_WPTR_DELAY, 0); |
1280 | 1278 | ||
1281 | /* Initialize the ring buffer's read and write pointers */ | 1279 | /* Initialize the ring buffer's read and write pointers */ |
1282 | tmp = RREG32(CP_RB_CNTL); | ||
1283 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); | 1280 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); |
1284 | WREG32(CP_RB_RPTR_WR, 0); | 1281 | WREG32(CP_RB_RPTR_WR, 0); |
1285 | WREG32(CP_RB_WPTR, 0); | 1282 | WREG32(CP_RB_WPTR, 0); |
@@ -1400,7 +1397,7 @@ int r600_wb_enable(struct radeon_device *rdev) | |||
1400 | int r; | 1397 | int r; |
1401 | 1398 | ||
1402 | if (rdev->wb.wb_obj == NULL) { | 1399 | if (rdev->wb.wb_obj == NULL) { |
1403 | r = radeon_object_create(rdev, NULL, 4096, true, | 1400 | r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true, |
1404 | RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj); | 1401 | RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj); |
1405 | if (r) { | 1402 | if (r) { |
1406 | dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r); | 1403 | dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r); |
@@ -1450,8 +1447,8 @@ int r600_copy_blit(struct radeon_device *rdev, | |||
1450 | uint64_t src_offset, uint64_t dst_offset, | 1447 | uint64_t src_offset, uint64_t dst_offset, |
1451 | unsigned num_pages, struct radeon_fence *fence) | 1448 | unsigned num_pages, struct radeon_fence *fence) |
1452 | { | 1449 | { |
1453 | r600_blit_prepare_copy(rdev, num_pages * 4096); | 1450 | r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); |
1454 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * 4096); | 1451 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); |
1455 | r600_blit_done_copy(rdev, fence); | 1452 | r600_blit_done_copy(rdev, fence); |
1456 | return 0; | 1453 | return 0; |
1457 | } | 1454 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c index dec501081608..5ea432347589 100644 --- a/drivers/gpu/drm/radeon/r600_blit.c +++ b/drivers/gpu/drm/radeon/r600_blit.c | |||
@@ -582,6 +582,8 @@ r600_blit_copy(struct drm_device *dev, | |||
582 | u64 vb_addr; | 582 | u64 vb_addr; |
583 | u32 *vb; | 583 | u32 *vb; |
584 | 584 | ||
585 | vb = r600_nomm_get_vb_ptr(dev); | ||
586 | |||
585 | if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { | 587 | if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { |
586 | max_bytes = 8192; | 588 | max_bytes = 8192; |
587 | 589 | ||
@@ -617,8 +619,8 @@ r600_blit_copy(struct drm_device *dev, | |||
617 | if (!dev_priv->blit_vb) | 619 | if (!dev_priv->blit_vb) |
618 | return; | 620 | return; |
619 | set_shaders(dev); | 621 | set_shaders(dev); |
622 | vb = r600_nomm_get_vb_ptr(dev); | ||
620 | } | 623 | } |
621 | vb = r600_nomm_get_vb_ptr(dev); | ||
622 | 624 | ||
623 | vb[0] = i2f(dst_x); | 625 | vb[0] = i2f(dst_x); |
624 | vb[1] = 0; | 626 | vb[1] = 0; |
@@ -706,8 +708,8 @@ r600_blit_copy(struct drm_device *dev, | |||
706 | return; | 708 | return; |
707 | 709 | ||
708 | set_shaders(dev); | 710 | set_shaders(dev); |
711 | vb = r600_nomm_get_vb_ptr(dev); | ||
709 | } | 712 | } |
710 | vb = r600_nomm_get_vb_ptr(dev); | ||
711 | 713 | ||
712 | vb[0] = i2f(dst_x / 4); | 714 | vb[0] = i2f(dst_x / 4); |
713 | vb[1] = 0; | 715 | vb[1] = 0; |
@@ -772,6 +774,7 @@ r600_blit_swap(struct drm_device *dev, | |||
772 | { | 774 | { |
773 | drm_radeon_private_t *dev_priv = dev->dev_private; | 775 | drm_radeon_private_t *dev_priv = dev->dev_private; |
774 | int cb_format, tex_format; | 776 | int cb_format, tex_format; |
777 | int sx2, sy2, dx2, dy2; | ||
775 | u64 vb_addr; | 778 | u64 vb_addr; |
776 | u32 *vb; | 779 | u32 *vb; |
777 | 780 | ||
@@ -786,16 +789,10 @@ r600_blit_swap(struct drm_device *dev, | |||
786 | } | 789 | } |
787 | vb = r600_nomm_get_vb_ptr(dev); | 790 | vb = r600_nomm_get_vb_ptr(dev); |
788 | 791 | ||
789 | if (cpp == 4) { | 792 | sx2 = sx + w; |
790 | cb_format = COLOR_8_8_8_8; | 793 | sy2 = sy + h; |
791 | tex_format = FMT_8_8_8_8; | 794 | dx2 = dx + w; |
792 | } else if (cpp == 2) { | 795 | dy2 = dy + h; |
793 | cb_format = COLOR_5_6_5; | ||
794 | tex_format = FMT_5_6_5; | ||
795 | } else { | ||
796 | cb_format = COLOR_8; | ||
797 | tex_format = FMT_8; | ||
798 | } | ||
799 | 796 | ||
800 | vb[0] = i2f(dx); | 797 | vb[0] = i2f(dx); |
801 | vb[1] = i2f(dy); | 798 | vb[1] = i2f(dy); |
@@ -803,31 +800,46 @@ r600_blit_swap(struct drm_device *dev, | |||
803 | vb[3] = i2f(sy); | 800 | vb[3] = i2f(sy); |
804 | 801 | ||
805 | vb[4] = i2f(dx); | 802 | vb[4] = i2f(dx); |
806 | vb[5] = i2f(dy + h); | 803 | vb[5] = i2f(dy2); |
807 | vb[6] = i2f(sx); | 804 | vb[6] = i2f(sx); |
808 | vb[7] = i2f(sy + h); | 805 | vb[7] = i2f(sy2); |
806 | |||
807 | vb[8] = i2f(dx2); | ||
808 | vb[9] = i2f(dy2); | ||
809 | vb[10] = i2f(sx2); | ||
810 | vb[11] = i2f(sy2); | ||
809 | 811 | ||
810 | vb[8] = i2f(dx + w); | 812 | switch(cpp) { |
811 | vb[9] = i2f(dy + h); | 813 | case 4: |
812 | vb[10] = i2f(sx + w); | 814 | cb_format = COLOR_8_8_8_8; |
813 | vb[11] = i2f(sy + h); | 815 | tex_format = FMT_8_8_8_8; |
816 | break; | ||
817 | case 2: | ||
818 | cb_format = COLOR_5_6_5; | ||
819 | tex_format = FMT_5_6_5; | ||
820 | break; | ||
821 | default: | ||
822 | cb_format = COLOR_8; | ||
823 | tex_format = FMT_8; | ||
824 | break; | ||
825 | } | ||
814 | 826 | ||
815 | /* src */ | 827 | /* src */ |
816 | set_tex_resource(dev_priv, tex_format, | 828 | set_tex_resource(dev_priv, tex_format, |
817 | src_pitch / cpp, | 829 | src_pitch / cpp, |
818 | sy + h, src_pitch / cpp, | 830 | sy2, src_pitch / cpp, |
819 | src_gpu_addr); | 831 | src_gpu_addr); |
820 | 832 | ||
821 | cp_set_surface_sync(dev_priv, | 833 | cp_set_surface_sync(dev_priv, |
822 | R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr); | 834 | R600_TC_ACTION_ENA, src_pitch * sy2, src_gpu_addr); |
823 | 835 | ||
824 | /* dst */ | 836 | /* dst */ |
825 | set_render_target(dev_priv, cb_format, | 837 | set_render_target(dev_priv, cb_format, |
826 | dst_pitch / cpp, dy + h, | 838 | dst_pitch / cpp, dy2, |
827 | dst_gpu_addr); | 839 | dst_gpu_addr); |
828 | 840 | ||
829 | /* scissors */ | 841 | /* scissors */ |
830 | set_scissors(dev_priv, dx, dy, dx + w, dy + h); | 842 | set_scissors(dev_priv, dx, dy, dx2, dy2); |
831 | 843 | ||
832 | /* Vertex buffer setup */ | 844 | /* Vertex buffer setup */ |
833 | vb_addr = dev_priv->gart_buffers_offset + | 845 | vb_addr = dev_priv->gart_buffers_offset + |
@@ -840,7 +852,7 @@ r600_blit_swap(struct drm_device *dev, | |||
840 | 852 | ||
841 | cp_set_surface_sync(dev_priv, | 853 | cp_set_surface_sync(dev_priv, |
842 | R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, | 854 | R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, |
843 | dst_pitch * (dy + h), dst_gpu_addr); | 855 | dst_pitch * dy2, dst_gpu_addr); |
844 | 856 | ||
845 | dev_priv->blit_vb->used += 12 * 4; | 857 | dev_priv->blit_vb->used += 12 * 4; |
846 | } | 858 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 93108bb31d1d..acae33e2ad51 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -610,6 +610,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
610 | 610 | ||
611 | DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr, | 611 | DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr, |
612 | size_bytes, rdev->r600_blit.vb_used); | 612 | size_bytes, rdev->r600_blit.vb_used); |
613 | vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); | ||
613 | if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { | 614 | if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { |
614 | max_bytes = 8192; | 615 | max_bytes = 8192; |
615 | 616 | ||
@@ -652,7 +653,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
652 | vb = r600_nomm_get_vb_ptr(dev); | 653 | vb = r600_nomm_get_vb_ptr(dev); |
653 | #endif | 654 | #endif |
654 | } | 655 | } |
655 | vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); | ||
656 | 656 | ||
657 | vb[0] = i2f(dst_x); | 657 | vb[0] = i2f(dst_x); |
658 | vb[1] = 0; | 658 | vb[1] = 0; |
@@ -747,7 +747,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
747 | vb = r600_nomm_get_vb_ptr(dev); | 747 | vb = r600_nomm_get_vb_ptr(dev); |
748 | } | 748 | } |
749 | #endif | 749 | #endif |
750 | vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); | ||
751 | 750 | ||
752 | vb[0] = i2f(dst_x / 4); | 751 | vb[0] = i2f(dst_x / 4); |
753 | vb[1] = 0; | 752 | vb[1] = 0; |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 9b64d47f1f82..00d9642198a3 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -271,6 +271,10 @@ | |||
271 | #define PCIE_PORT_INDEX 0x0038 | 271 | #define PCIE_PORT_INDEX 0x0038 |
272 | #define PCIE_PORT_DATA 0x003C | 272 | #define PCIE_PORT_DATA 0x003C |
273 | 273 | ||
274 | #define CHMAP 0x2004 | ||
275 | #define NOOFCHAN_SHIFT 12 | ||
276 | #define NOOFCHAN_MASK 0x00003000 | ||
277 | |||
274 | #define RAMCFG 0x2408 | 278 | #define RAMCFG 0x2408 |
275 | #define NOOFBANK_SHIFT 0 | 279 | #define NOOFBANK_SHIFT 0 |
276 | #define NOOFBANK_MASK 0x00000001 | 280 | #define NOOFBANK_MASK 0x00000001 |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5ab35b81c86b..620a7c8ca016 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -276,6 +276,8 @@ union radeon_gart_table { | |||
276 | struct radeon_gart_table_vram vram; | 276 | struct radeon_gart_table_vram vram; |
277 | }; | 277 | }; |
278 | 278 | ||
279 | #define RADEON_GPU_PAGE_SIZE 4096 | ||
280 | |||
279 | struct radeon_gart { | 281 | struct radeon_gart { |
280 | dma_addr_t table_addr; | 282 | dma_addr_t table_addr; |
281 | unsigned num_gpu_pages; | 283 | unsigned num_gpu_pages; |
@@ -783,6 +785,7 @@ struct radeon_device { | |||
783 | const struct firmware *me_fw; /* all family ME firmware */ | 785 | const struct firmware *me_fw; /* all family ME firmware */ |
784 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ | 786 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ |
785 | struct r600_blit r600_blit; | 787 | struct r600_blit r600_blit; |
788 | int msi_enabled; /* msi enabled */ | ||
786 | }; | 789 | }; |
787 | 790 | ||
788 | int radeon_device_init(struct radeon_device *rdev, | 791 | int radeon_device_init(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5b6c08cee40e..1c9a9c461762 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -641,8 +641,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
641 | le16_to_cpu(firmware_info->info.usReferenceClock); | 641 | le16_to_cpu(firmware_info->info.usReferenceClock); |
642 | p1pll->reference_div = 0; | 642 | p1pll->reference_div = 0; |
643 | 643 | ||
644 | p1pll->pll_out_min = | 644 | if (crev < 2) |
645 | le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output); | 645 | p1pll->pll_out_min = |
646 | le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output); | ||
647 | else | ||
648 | p1pll->pll_out_min = | ||
649 | le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output); | ||
646 | p1pll->pll_out_max = | 650 | p1pll->pll_out_max = |
647 | le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); | 651 | le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); |
648 | 652 | ||
@@ -651,6 +655,16 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
651 | p1pll->pll_out_min = 64800; | 655 | p1pll->pll_out_min = 64800; |
652 | else | 656 | else |
653 | p1pll->pll_out_min = 20000; | 657 | p1pll->pll_out_min = 20000; |
658 | } else if (p1pll->pll_out_min > 64800) { | ||
659 | /* Limiting the pll output range is a good thing generally as | ||
660 | * it limits the number of possible pll combinations for a given | ||
661 | * frequency presumably to the ones that work best on each card. | ||
662 | * However, certain duallink DVI monitors seem to like | ||
663 | * pll combinations that would be limited by this at least on | ||
664 | * pre-DCE 3.0 r6xx hardware. This might need to be adjusted per | ||
665 | * family. | ||
666 | */ | ||
667 | p1pll->pll_out_min = 64800; | ||
654 | } | 668 | } |
655 | 669 | ||
656 | p1pll->pll_in_min = | 670 | p1pll->pll_in_min = |
@@ -767,6 +781,46 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, | |||
767 | return false; | 781 | return false; |
768 | } | 782 | } |
769 | 783 | ||
784 | static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct | ||
785 | radeon_encoder | ||
786 | *encoder, | ||
787 | int id) | ||
788 | { | ||
789 | struct drm_device *dev = encoder->base.dev; | ||
790 | struct radeon_device *rdev = dev->dev_private; | ||
791 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
792 | int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info); | ||
793 | uint16_t data_offset; | ||
794 | struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; | ||
795 | uint8_t frev, crev; | ||
796 | struct radeon_atom_ss *ss = NULL; | ||
797 | |||
798 | if (id > ATOM_MAX_SS_ENTRY) | ||
799 | return NULL; | ||
800 | |||
801 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | ||
802 | &crev, &data_offset); | ||
803 | |||
804 | ss_info = | ||
805 | (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); | ||
806 | |||
807 | if (ss_info) { | ||
808 | ss = | ||
809 | kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL); | ||
810 | |||
811 | if (!ss) | ||
812 | return NULL; | ||
813 | |||
814 | ss->percentage = le16_to_cpu(ss_info->asSS_Info[id].usSpreadSpectrumPercentage); | ||
815 | ss->type = ss_info->asSS_Info[id].ucSpreadSpectrumType; | ||
816 | ss->step = ss_info->asSS_Info[id].ucSS_Step; | ||
817 | ss->delay = ss_info->asSS_Info[id].ucSS_Delay; | ||
818 | ss->range = ss_info->asSS_Info[id].ucSS_Range; | ||
819 | ss->refdiv = ss_info->asSS_Info[id].ucRecommendedRef_Div; | ||
820 | } | ||
821 | return ss; | ||
822 | } | ||
823 | |||
770 | union lvds_info { | 824 | union lvds_info { |
771 | struct _ATOM_LVDS_INFO info; | 825 | struct _ATOM_LVDS_INFO info; |
772 | struct _ATOM_LVDS_INFO_V12 info_12; | 826 | struct _ATOM_LVDS_INFO_V12 info_12; |
@@ -798,27 +852,31 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
798 | if (!lvds) | 852 | if (!lvds) |
799 | return NULL; | 853 | return NULL; |
800 | 854 | ||
801 | lvds->native_mode.dotclock = | 855 | lvds->native_mode.clock = |
802 | le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10; | 856 | le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10; |
803 | lvds->native_mode.panel_xres = | 857 | lvds->native_mode.hdisplay = |
804 | le16_to_cpu(lvds_info->info.sLCDTiming.usHActive); | 858 | le16_to_cpu(lvds_info->info.sLCDTiming.usHActive); |
805 | lvds->native_mode.panel_yres = | 859 | lvds->native_mode.vdisplay = |
806 | le16_to_cpu(lvds_info->info.sLCDTiming.usVActive); | 860 | le16_to_cpu(lvds_info->info.sLCDTiming.usVActive); |
807 | lvds->native_mode.hblank = | 861 | lvds->native_mode.htotal = lvds->native_mode.hdisplay + |
808 | le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time); | 862 | le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time); |
809 | lvds->native_mode.hoverplus = | 863 | lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + |
810 | le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset); | 864 | le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset); |
811 | lvds->native_mode.hsync_width = | 865 | lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + |
812 | le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth); | 866 | le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth); |
813 | lvds->native_mode.vblank = | 867 | lvds->native_mode.vtotal = lvds->native_mode.vdisplay + |
814 | le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); | 868 | le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); |
815 | lvds->native_mode.voverplus = | 869 | lvds->native_mode.vsync_start = lvds->native_mode.vdisplay + |
816 | le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset); | 870 | le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); |
817 | lvds->native_mode.vsync_width = | 871 | lvds->native_mode.vsync_end = lvds->native_mode.vsync_start + |
818 | le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); | 872 | le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); |
819 | lvds->panel_pwr_delay = | 873 | lvds->panel_pwr_delay = |
820 | le16_to_cpu(lvds_info->info.usOffDelayInMs); | 874 | le16_to_cpu(lvds_info->info.usOffDelayInMs); |
821 | lvds->lvds_misc = lvds_info->info.ucLVDS_Misc; | 875 | lvds->lvds_misc = lvds_info->info.ucLVDS_Misc; |
876 | /* set crtc values */ | ||
877 | drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); | ||
878 | |||
879 | lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id); | ||
822 | 880 | ||
823 | encoder->native_mode = lvds->native_mode; | 881 | encoder->native_mode = lvds->native_mode; |
824 | } | 882 | } |
@@ -857,8 +915,7 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder) | |||
857 | } | 915 | } |
858 | 916 | ||
859 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | 917 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
860 | SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, | 918 | struct drm_display_mode *mode) |
861 | int32_t *pixel_clock) | ||
862 | { | 919 | { |
863 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 920 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
864 | ATOM_ANALOG_TV_INFO *tv_info; | 921 | ATOM_ANALOG_TV_INFO *tv_info; |
@@ -866,7 +923,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
866 | ATOM_DTD_FORMAT *dtd_timings; | 923 | ATOM_DTD_FORMAT *dtd_timings; |
867 | int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); | 924 | int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); |
868 | u8 frev, crev; | 925 | u8 frev, crev; |
869 | uint16_t data_offset; | 926 | u16 data_offset, misc; |
870 | 927 | ||
871 | atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); | 928 | atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); |
872 | 929 | ||
@@ -876,28 +933,37 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
876 | if (index > MAX_SUPPORTED_TV_TIMING) | 933 | if (index > MAX_SUPPORTED_TV_TIMING) |
877 | return false; | 934 | return false; |
878 | 935 | ||
879 | crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); | 936 | mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); |
880 | crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); | 937 | mode->crtc_hdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); |
881 | crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); | 938 | mode->crtc_hsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); |
882 | crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); | 939 | mode->crtc_hsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) + |
883 | 940 | le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); | |
884 | crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); | 941 | |
885 | crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); | 942 | mode->crtc_vtotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); |
886 | crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); | 943 | mode->crtc_vdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); |
887 | crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); | 944 | mode->crtc_vsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); |
888 | 945 | mode->crtc_vsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) + | |
889 | crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo; | 946 | le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); |
890 | 947 | ||
891 | crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight); | 948 | mode->flags = 0; |
892 | crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft); | 949 | misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess); |
893 | crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom); | 950 | if (misc & ATOM_VSYNC_POLARITY) |
894 | crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop); | 951 | mode->flags |= DRM_MODE_FLAG_NVSYNC; |
895 | *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; | 952 | if (misc & ATOM_HSYNC_POLARITY) |
953 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
954 | if (misc & ATOM_COMPOSITESYNC) | ||
955 | mode->flags |= DRM_MODE_FLAG_CSYNC; | ||
956 | if (misc & ATOM_INTERLACE) | ||
957 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
958 | if (misc & ATOM_DOUBLE_CLOCK_MODE) | ||
959 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; | ||
960 | |||
961 | mode->clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; | ||
896 | 962 | ||
897 | if (index == 1) { | 963 | if (index == 1) { |
898 | /* PAL timings appear to have wrong values for totals */ | 964 | /* PAL timings appear to have wrong values for totals */ |
899 | crtc_timing->usH_Total -= 1; | 965 | mode->crtc_htotal -= 1; |
900 | crtc_timing->usV_Total -= 1; | 966 | mode->crtc_vtotal -= 1; |
901 | } | 967 | } |
902 | break; | 968 | break; |
903 | case 2: | 969 | case 2: |
@@ -906,17 +972,36 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
906 | return false; | 972 | return false; |
907 | 973 | ||
908 | dtd_timings = &tv_info_v1_2->aModeTimings[index]; | 974 | dtd_timings = &tv_info_v1_2->aModeTimings[index]; |
909 | crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time); | 975 | mode->crtc_htotal = le16_to_cpu(dtd_timings->usHActive) + |
910 | crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive); | 976 | le16_to_cpu(dtd_timings->usHBlanking_Time); |
911 | crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset); | 977 | mode->crtc_hdisplay = le16_to_cpu(dtd_timings->usHActive); |
912 | crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth); | 978 | mode->crtc_hsync_start = le16_to_cpu(dtd_timings->usHActive) + |
913 | crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time); | 979 | le16_to_cpu(dtd_timings->usHSyncOffset); |
914 | crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive); | 980 | mode->crtc_hsync_end = mode->crtc_hsync_start + |
915 | crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset); | 981 | le16_to_cpu(dtd_timings->usHSyncWidth); |
916 | crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth); | 982 | |
917 | 983 | mode->crtc_vtotal = le16_to_cpu(dtd_timings->usVActive) + | |
918 | crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); | 984 | le16_to_cpu(dtd_timings->usVBlanking_Time); |
919 | *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10; | 985 | mode->crtc_vdisplay = le16_to_cpu(dtd_timings->usVActive); |
986 | mode->crtc_vsync_start = le16_to_cpu(dtd_timings->usVActive) + | ||
987 | le16_to_cpu(dtd_timings->usVSyncOffset); | ||
988 | mode->crtc_vsync_end = mode->crtc_vsync_start + | ||
989 | le16_to_cpu(dtd_timings->usVSyncWidth); | ||
990 | |||
991 | mode->flags = 0; | ||
992 | misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); | ||
993 | if (misc & ATOM_VSYNC_POLARITY) | ||
994 | mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
995 | if (misc & ATOM_HSYNC_POLARITY) | ||
996 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
997 | if (misc & ATOM_COMPOSITESYNC) | ||
998 | mode->flags |= DRM_MODE_FLAG_CSYNC; | ||
999 | if (misc & ATOM_INTERLACE) | ||
1000 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
1001 | if (misc & ATOM_DOUBLE_CLOCK_MODE) | ||
1002 | mode->flags |= DRM_MODE_FLAG_DBLSCAN; | ||
1003 | |||
1004 | mode->clock = le16_to_cpu(dtd_timings->usPixClk) * 10; | ||
920 | break; | 1005 | break; |
921 | } | 1006 | } |
922 | return true; | 1007 | return true; |
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 2e938f7496fb..10bd50a7db87 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
@@ -63,7 +63,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, | |||
63 | if (r) { | 63 | if (r) { |
64 | goto out_cleanup; | 64 | goto out_cleanup; |
65 | } | 65 | } |
66 | r = radeon_copy_dma(rdev, saddr, daddr, size / 4096, fence); | 66 | r = radeon_copy_dma(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence); |
67 | if (r) { | 67 | if (r) { |
68 | goto out_cleanup; | 68 | goto out_cleanup; |
69 | } | 69 | } |
@@ -88,7 +88,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, | |||
88 | if (r) { | 88 | if (r) { |
89 | goto out_cleanup; | 89 | goto out_cleanup; |
90 | } | 90 | } |
91 | r = radeon_copy_blit(rdev, saddr, daddr, size / 4096, fence); | 91 | r = radeon_copy_blit(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence); |
92 | if (r) { | 92 | if (r) { |
93 | goto out_cleanup; | 93 | goto out_cleanup; |
94 | } | 94 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 34a9b9119518..906921740c60 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -50,19 +50,16 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev) | |||
50 | vram_base = drm_get_resource_start(rdev->ddev, 0); | 50 | vram_base = drm_get_resource_start(rdev->ddev, 0); |
51 | bios = ioremap(vram_base, size); | 51 | bios = ioremap(vram_base, size); |
52 | if (!bios) { | 52 | if (!bios) { |
53 | DRM_ERROR("Unable to mmap vram\n"); | ||
54 | return false; | 53 | return false; |
55 | } | 54 | } |
56 | 55 | ||
57 | if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { | 56 | if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { |
58 | iounmap(bios); | 57 | iounmap(bios); |
59 | DRM_ERROR("bad rom signature\n"); | ||
60 | return false; | 58 | return false; |
61 | } | 59 | } |
62 | rdev->bios = kmalloc(size, GFP_KERNEL); | 60 | rdev->bios = kmalloc(size, GFP_KERNEL); |
63 | if (rdev->bios == NULL) { | 61 | if (rdev->bios == NULL) { |
64 | iounmap(bios); | 62 | iounmap(bios); |
65 | DRM_ERROR("kmalloc failed\n"); | ||
66 | return false; | 63 | return false; |
67 | } | 64 | } |
68 | memcpy(rdev->bios, bios, size); | 65 | memcpy(rdev->bios, bios, size); |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 748265a105b3..a36ede002ee4 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -808,25 +808,25 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct | |||
808 | lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf; | 808 | lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf; |
809 | 809 | ||
810 | if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) | 810 | if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) |
811 | lvds->native_mode.panel_yres = | 811 | lvds->native_mode.vdisplay = |
812 | ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> | 812 | ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> |
813 | RADEON_VERT_PANEL_SHIFT) + 1; | 813 | RADEON_VERT_PANEL_SHIFT) + 1; |
814 | else | 814 | else |
815 | lvds->native_mode.panel_yres = | 815 | lvds->native_mode.vdisplay = |
816 | (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1; | 816 | (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1; |
817 | 817 | ||
818 | if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) | 818 | if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) |
819 | lvds->native_mode.panel_xres = | 819 | lvds->native_mode.hdisplay = |
820 | (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >> | 820 | (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >> |
821 | RADEON_HORZ_PANEL_SHIFT) + 1) * 8; | 821 | RADEON_HORZ_PANEL_SHIFT) + 1) * 8; |
822 | else | 822 | else |
823 | lvds->native_mode.panel_xres = | 823 | lvds->native_mode.hdisplay = |
824 | ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8; | 824 | ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8; |
825 | 825 | ||
826 | if ((lvds->native_mode.panel_xres < 640) || | 826 | if ((lvds->native_mode.hdisplay < 640) || |
827 | (lvds->native_mode.panel_yres < 480)) { | 827 | (lvds->native_mode.vdisplay < 480)) { |
828 | lvds->native_mode.panel_xres = 640; | 828 | lvds->native_mode.hdisplay = 640; |
829 | lvds->native_mode.panel_yres = 480; | 829 | lvds->native_mode.vdisplay = 480; |
830 | } | 830 | } |
831 | 831 | ||
832 | ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3; | 832 | ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3; |
@@ -846,8 +846,8 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct | |||
846 | lvds->panel_vcc_delay = 200; | 846 | lvds->panel_vcc_delay = 200; |
847 | 847 | ||
848 | DRM_INFO("Panel info derived from registers\n"); | 848 | DRM_INFO("Panel info derived from registers\n"); |
849 | DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres, | 849 | DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay, |
850 | lvds->native_mode.panel_yres); | 850 | lvds->native_mode.vdisplay); |
851 | 851 | ||
852 | return lvds; | 852 | return lvds; |
853 | } | 853 | } |
@@ -882,11 +882,11 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder | |||
882 | 882 | ||
883 | DRM_INFO("Panel ID String: %s\n", stmp); | 883 | DRM_INFO("Panel ID String: %s\n", stmp); |
884 | 884 | ||
885 | lvds->native_mode.panel_xres = RBIOS16(lcd_info + 0x19); | 885 | lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19); |
886 | lvds->native_mode.panel_yres = RBIOS16(lcd_info + 0x1b); | 886 | lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b); |
887 | 887 | ||
888 | DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres, | 888 | DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay, |
889 | lvds->native_mode.panel_yres); | 889 | lvds->native_mode.vdisplay); |
890 | 890 | ||
891 | lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); | 891 | lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); |
892 | if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0) | 892 | if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0) |
@@ -944,27 +944,25 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder | |||
944 | if (tmp == 0) | 944 | if (tmp == 0) |
945 | break; | 945 | break; |
946 | 946 | ||
947 | if ((RBIOS16(tmp) == lvds->native_mode.panel_xres) && | 947 | if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) && |
948 | (RBIOS16(tmp + 2) == | 948 | (RBIOS16(tmp + 2) == |
949 | lvds->native_mode.panel_yres)) { | 949 | lvds->native_mode.vdisplay)) { |
950 | lvds->native_mode.hblank = | 950 | lvds->native_mode.htotal = RBIOS16(tmp + 17) * 8; |
951 | (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8; | 951 | lvds->native_mode.hsync_start = RBIOS16(tmp + 21) * 8; |
952 | lvds->native_mode.hoverplus = | 952 | lvds->native_mode.hsync_end = (RBIOS8(tmp + 23) + |
953 | (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - | 953 | RBIOS16(tmp + 21)) * 8; |
954 | 1) * 8; | 954 | |
955 | lvds->native_mode.hsync_width = | 955 | lvds->native_mode.vtotal = RBIOS16(tmp + 24); |
956 | RBIOS8(tmp + 23) * 8; | 956 | lvds->native_mode.vsync_start = RBIOS16(tmp + 28) & 0x7ff; |
957 | 957 | lvds->native_mode.vsync_end = | |
958 | lvds->native_mode.vblank = (RBIOS16(tmp + 24) - | 958 | ((RBIOS16(tmp + 28) & 0xf800) >> 11) + |
959 | RBIOS16(tmp + 26)); | 959 | (RBIOS16(tmp + 28) & 0x7ff); |
960 | lvds->native_mode.voverplus = | 960 | |
961 | ((RBIOS16(tmp + 28) & 0x7ff) - | 961 | lvds->native_mode.clock = RBIOS16(tmp + 9) * 10; |
962 | RBIOS16(tmp + 26)); | ||
963 | lvds->native_mode.vsync_width = | ||
964 | ((RBIOS16(tmp + 28) & 0xf800) >> 11); | ||
965 | lvds->native_mode.dotclock = | ||
966 | RBIOS16(tmp + 9) * 10; | ||
967 | lvds->native_mode.flags = 0; | 962 | lvds->native_mode.flags = 0; |
963 | /* set crtc values */ | ||
964 | drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); | ||
965 | |||
968 | } | 966 | } |
969 | } | 967 | } |
970 | } else { | 968 | } else { |
@@ -1581,6 +1579,23 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev, | |||
1581 | return true; | 1579 | return true; |
1582 | } | 1580 | } |
1583 | 1581 | ||
1582 | static bool radeon_apply_legacy_tv_quirks(struct drm_device *dev) | ||
1583 | { | ||
1584 | /* Acer 5102 has non-existent TV port */ | ||
1585 | if (dev->pdev->device == 0x5975 && | ||
1586 | dev->pdev->subsystem_vendor == 0x1025 && | ||
1587 | dev->pdev->subsystem_device == 0x009f) | ||
1588 | return false; | ||
1589 | |||
1590 | /* HP dc5750 has non-existent TV port */ | ||
1591 | if (dev->pdev->device == 0x5974 && | ||
1592 | dev->pdev->subsystem_vendor == 0x103c && | ||
1593 | dev->pdev->subsystem_device == 0x280a) | ||
1594 | return false; | ||
1595 | |||
1596 | return true; | ||
1597 | } | ||
1598 | |||
1584 | bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | 1599 | bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) |
1585 | { | 1600 | { |
1586 | struct radeon_device *rdev = dev->dev_private; | 1601 | struct radeon_device *rdev = dev->dev_private; |
@@ -1628,8 +1643,9 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1628 | break; | 1643 | break; |
1629 | } | 1644 | } |
1630 | 1645 | ||
1631 | radeon_apply_legacy_quirks(dev, i, &connector, | 1646 | if (!radeon_apply_legacy_quirks(dev, i, &connector, |
1632 | &ddc_i2c); | 1647 | &ddc_i2c)) |
1648 | continue; | ||
1633 | 1649 | ||
1634 | switch (connector) { | 1650 | switch (connector) { |
1635 | case CONNECTOR_PROPRIETARY_LEGACY: | 1651 | case CONNECTOR_PROPRIETARY_LEGACY: |
@@ -1774,8 +1790,25 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1774 | DRM_MODE_CONNECTOR_DVII, | 1790 | DRM_MODE_CONNECTOR_DVII, |
1775 | &ddc_i2c); | 1791 | &ddc_i2c); |
1776 | } else { | 1792 | } else { |
1777 | DRM_DEBUG("No connector info found\n"); | 1793 | uint16_t crt_info = |
1778 | return false; | 1794 | combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); |
1795 | DRM_DEBUG("Found CRT table, assuming VGA connector\n"); | ||
1796 | if (crt_info) { | ||
1797 | radeon_add_legacy_encoder(dev, | ||
1798 | radeon_get_encoder_id(dev, | ||
1799 | ATOM_DEVICE_CRT1_SUPPORT, | ||
1800 | 1), | ||
1801 | ATOM_DEVICE_CRT1_SUPPORT); | ||
1802 | ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); | ||
1803 | radeon_add_legacy_connector(dev, | ||
1804 | 0, | ||
1805 | ATOM_DEVICE_CRT1_SUPPORT, | ||
1806 | DRM_MODE_CONNECTOR_VGA, | ||
1807 | &ddc_i2c); | ||
1808 | } else { | ||
1809 | DRM_DEBUG("No connector info found\n"); | ||
1810 | return false; | ||
1811 | } | ||
1779 | } | 1812 | } |
1780 | } | 1813 | } |
1781 | 1814 | ||
@@ -1880,16 +1913,18 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
1880 | combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); | 1913 | combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); |
1881 | if (tv_info) { | 1914 | if (tv_info) { |
1882 | if (RBIOS8(tv_info + 6) == 'T') { | 1915 | if (RBIOS8(tv_info + 6) == 'T') { |
1883 | radeon_add_legacy_encoder(dev, | 1916 | if (radeon_apply_legacy_tv_quirks(dev)) { |
1884 | radeon_get_encoder_id | 1917 | radeon_add_legacy_encoder(dev, |
1885 | (dev, | 1918 | radeon_get_encoder_id |
1886 | ATOM_DEVICE_TV1_SUPPORT, | 1919 | (dev, |
1887 | 2), | 1920 | ATOM_DEVICE_TV1_SUPPORT, |
1888 | ATOM_DEVICE_TV1_SUPPORT); | 1921 | 2), |
1889 | radeon_add_legacy_connector(dev, 6, | 1922 | ATOM_DEVICE_TV1_SUPPORT); |
1890 | ATOM_DEVICE_TV1_SUPPORT, | 1923 | radeon_add_legacy_connector(dev, 6, |
1891 | DRM_MODE_CONNECTOR_SVIDEO, | 1924 | ATOM_DEVICE_TV1_SUPPORT, |
1892 | &ddc_i2c); | 1925 | DRM_MODE_CONNECTOR_SVIDEO, |
1926 | &ddc_i2c); | ||
1927 | } | ||
1893 | } | 1928 | } |
1894 | } | 1929 | } |
1895 | } | 1930 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index e376be47a4a0..ce3a785a633b 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -178,25 +178,12 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode | |||
178 | struct drm_device *dev = encoder->dev; | 178 | struct drm_device *dev = encoder->dev; |
179 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 179 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
180 | struct drm_display_mode *mode = NULL; | 180 | struct drm_display_mode *mode = NULL; |
181 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; | 181 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
182 | |||
183 | if (native_mode->panel_xres != 0 && | ||
184 | native_mode->panel_yres != 0 && | ||
185 | native_mode->dotclock != 0) { | ||
186 | mode = drm_mode_create(dev); | ||
187 | |||
188 | mode->hdisplay = native_mode->panel_xres; | ||
189 | mode->vdisplay = native_mode->panel_yres; | ||
190 | |||
191 | mode->htotal = mode->hdisplay + native_mode->hblank; | ||
192 | mode->hsync_start = mode->hdisplay + native_mode->hoverplus; | ||
193 | mode->hsync_end = mode->hsync_start + native_mode->hsync_width; | ||
194 | mode->vtotal = mode->vdisplay + native_mode->vblank; | ||
195 | mode->vsync_start = mode->vdisplay + native_mode->voverplus; | ||
196 | mode->vsync_end = mode->vsync_start + native_mode->vsync_width; | ||
197 | mode->clock = native_mode->dotclock; | ||
198 | mode->flags = 0; | ||
199 | 182 | ||
183 | if (native_mode->hdisplay != 0 && | ||
184 | native_mode->vdisplay != 0 && | ||
185 | native_mode->clock != 0) { | ||
186 | mode = drm_mode_duplicate(dev, native_mode); | ||
200 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; | 187 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
201 | drm_mode_set_name(mode); | 188 | drm_mode_set_name(mode); |
202 | 189 | ||
@@ -210,7 +197,7 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn | |||
210 | struct drm_device *dev = encoder->dev; | 197 | struct drm_device *dev = encoder->dev; |
211 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 198 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
212 | struct drm_display_mode *mode = NULL; | 199 | struct drm_display_mode *mode = NULL; |
213 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; | 200 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
214 | int i; | 201 | int i; |
215 | struct mode_size { | 202 | struct mode_size { |
216 | int w; | 203 | int w; |
@@ -236,11 +223,16 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn | |||
236 | }; | 223 | }; |
237 | 224 | ||
238 | for (i = 0; i < 17; i++) { | 225 | for (i = 0; i < 17; i++) { |
226 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) { | ||
227 | if (common_modes[i].w > 1024 || | ||
228 | common_modes[i].h > 768) | ||
229 | continue; | ||
230 | } | ||
239 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 231 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
240 | if (common_modes[i].w > native_mode->panel_xres || | 232 | if (common_modes[i].w > native_mode->hdisplay || |
241 | common_modes[i].h > native_mode->panel_yres || | 233 | common_modes[i].h > native_mode->vdisplay || |
242 | (common_modes[i].w == native_mode->panel_xres && | 234 | (common_modes[i].w == native_mode->hdisplay && |
243 | common_modes[i].h == native_mode->panel_yres)) | 235 | common_modes[i].h == native_mode->vdisplay)) |
244 | continue; | 236 | continue; |
245 | } | 237 | } |
246 | if (common_modes[i].w < 320 || common_modes[i].h < 200) | 238 | if (common_modes[i].w < 320 || common_modes[i].h < 200) |
@@ -344,28 +336,23 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, | |||
344 | struct drm_connector *connector) | 336 | struct drm_connector *connector) |
345 | { | 337 | { |
346 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 338 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
347 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; | 339 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
348 | 340 | ||
349 | /* Try to get native mode details from EDID if necessary */ | 341 | /* Try to get native mode details from EDID if necessary */ |
350 | if (!native_mode->dotclock) { | 342 | if (!native_mode->clock) { |
351 | struct drm_display_mode *t, *mode; | 343 | struct drm_display_mode *t, *mode; |
352 | 344 | ||
353 | list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { | 345 | list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { |
354 | if (mode->hdisplay == native_mode->panel_xres && | 346 | if (mode->hdisplay == native_mode->hdisplay && |
355 | mode->vdisplay == native_mode->panel_yres) { | 347 | mode->vdisplay == native_mode->vdisplay) { |
356 | native_mode->hblank = mode->htotal - mode->hdisplay; | 348 | *native_mode = *mode; |
357 | native_mode->hoverplus = mode->hsync_start - mode->hdisplay; | 349 | drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V); |
358 | native_mode->hsync_width = mode->hsync_end - mode->hsync_start; | ||
359 | native_mode->vblank = mode->vtotal - mode->vdisplay; | ||
360 | native_mode->voverplus = mode->vsync_start - mode->vdisplay; | ||
361 | native_mode->vsync_width = mode->vsync_end - mode->vsync_start; | ||
362 | native_mode->dotclock = mode->clock; | ||
363 | DRM_INFO("Determined LVDS native mode details from EDID\n"); | 350 | DRM_INFO("Determined LVDS native mode details from EDID\n"); |
364 | break; | 351 | break; |
365 | } | 352 | } |
366 | } | 353 | } |
367 | } | 354 | } |
368 | if (!native_mode->dotclock) { | 355 | if (!native_mode->clock) { |
369 | DRM_INFO("No LVDS native mode details, disabling RMX\n"); | 356 | DRM_INFO("No LVDS native mode details, disabling RMX\n"); |
370 | radeon_encoder->rmx_type = RMX_OFF; | 357 | radeon_encoder->rmx_type = RMX_OFF; |
371 | } | 358 | } |
@@ -415,8 +402,35 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector, | |||
415 | 402 | ||
416 | static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) | 403 | static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) |
417 | { | 404 | { |
418 | enum drm_connector_status ret = connector_status_connected; | 405 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
406 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | ||
407 | enum drm_connector_status ret = connector_status_disconnected; | ||
408 | |||
409 | if (encoder) { | ||
410 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
411 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | ||
412 | |||
413 | /* check if panel is valid */ | ||
414 | if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) | ||
415 | ret = connector_status_connected; | ||
416 | |||
417 | } | ||
418 | |||
419 | /* check for edid as well */ | ||
420 | if (radeon_connector->edid) | ||
421 | ret = connector_status_connected; | ||
422 | else { | ||
423 | if (radeon_connector->ddc_bus) { | ||
424 | radeon_i2c_do_lock(radeon_connector, 1); | ||
425 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, | ||
426 | &radeon_connector->ddc_bus->adapter); | ||
427 | radeon_i2c_do_lock(radeon_connector, 0); | ||
428 | if (radeon_connector->edid) | ||
429 | ret = connector_status_connected; | ||
430 | } | ||
431 | } | ||
419 | /* check acpi lid status ??? */ | 432 | /* check acpi lid status ??? */ |
433 | |||
420 | radeon_connector_update_scratch_regs(connector, ret); | 434 | radeon_connector_update_scratch_regs(connector, ret); |
421 | return ret; | 435 | return ret; |
422 | } | 436 | } |
@@ -427,6 +441,8 @@ static void radeon_connector_destroy(struct drm_connector *connector) | |||
427 | 441 | ||
428 | if (radeon_connector->ddc_bus) | 442 | if (radeon_connector->ddc_bus) |
429 | radeon_i2c_destroy(radeon_connector->ddc_bus); | 443 | radeon_i2c_destroy(radeon_connector->ddc_bus); |
444 | if (radeon_connector->edid) | ||
445 | kfree(radeon_connector->edid); | ||
430 | kfree(radeon_connector->con_priv); | 446 | kfree(radeon_connector->con_priv); |
431 | drm_sysfs_connector_remove(connector); | 447 | drm_sysfs_connector_remove(connector); |
432 | drm_connector_cleanup(connector); | 448 | drm_connector_cleanup(connector); |
@@ -514,9 +530,32 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect | |||
514 | radeon_i2c_do_lock(radeon_connector, 1); | 530 | radeon_i2c_do_lock(radeon_connector, 1); |
515 | dret = radeon_ddc_probe(radeon_connector); | 531 | dret = radeon_ddc_probe(radeon_connector); |
516 | radeon_i2c_do_lock(radeon_connector, 0); | 532 | radeon_i2c_do_lock(radeon_connector, 0); |
517 | if (dret) | 533 | if (dret) { |
518 | ret = connector_status_connected; | 534 | if (radeon_connector->edid) { |
519 | else { | 535 | kfree(radeon_connector->edid); |
536 | radeon_connector->edid = NULL; | ||
537 | } | ||
538 | radeon_i2c_do_lock(radeon_connector, 1); | ||
539 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); | ||
540 | radeon_i2c_do_lock(radeon_connector, 0); | ||
541 | |||
542 | if (!radeon_connector->edid) { | ||
543 | DRM_ERROR("DDC responded but not EDID found for %s\n", | ||
544 | drm_get_connector_name(connector)); | ||
545 | } else { | ||
546 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | ||
547 | |||
548 | /* some oems have boards with separate digital and analog connectors | ||
549 | * with a shared ddc line (often vga + hdmi) | ||
550 | */ | ||
551 | if (radeon_connector->use_digital && radeon_connector->shared_ddc) { | ||
552 | kfree(radeon_connector->edid); | ||
553 | radeon_connector->edid = NULL; | ||
554 | ret = connector_status_disconnected; | ||
555 | } else | ||
556 | ret = connector_status_connected; | ||
557 | } | ||
558 | } else { | ||
520 | if (radeon_connector->dac_load_detect) { | 559 | if (radeon_connector->dac_load_detect) { |
521 | encoder_funcs = encoder->helper_private; | 560 | encoder_funcs = encoder->helper_private; |
522 | ret = encoder_funcs->detect(encoder, connector); | 561 | ret = encoder_funcs->detect(encoder, connector); |
@@ -644,6 +683,10 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect | |||
644 | dret = radeon_ddc_probe(radeon_connector); | 683 | dret = radeon_ddc_probe(radeon_connector); |
645 | radeon_i2c_do_lock(radeon_connector, 0); | 684 | radeon_i2c_do_lock(radeon_connector, 0); |
646 | if (dret) { | 685 | if (dret) { |
686 | if (radeon_connector->edid) { | ||
687 | kfree(radeon_connector->edid); | ||
688 | radeon_connector->edid = NULL; | ||
689 | } | ||
647 | radeon_i2c_do_lock(radeon_connector, 1); | 690 | radeon_i2c_do_lock(radeon_connector, 1); |
648 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); | 691 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
649 | radeon_i2c_do_lock(radeon_connector, 0); | 692 | radeon_i2c_do_lock(radeon_connector, 0); |
@@ -654,10 +697,15 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect | |||
654 | } else { | 697 | } else { |
655 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | 698 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
656 | 699 | ||
657 | /* if this isn't a digital monitor | 700 | /* some oems have boards with separate digital and analog connectors |
658 | then we need to make sure we don't have any | 701 | * with a shared ddc line (often vga + hdmi) |
659 | TV conflicts */ | 702 | */ |
660 | ret = connector_status_connected; | 703 | if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) { |
704 | kfree(radeon_connector->edid); | ||
705 | radeon_connector->edid = NULL; | ||
706 | ret = connector_status_disconnected; | ||
707 | } else | ||
708 | ret = connector_status_connected; | ||
661 | } | 709 | } |
662 | } | 710 | } |
663 | 711 | ||
@@ -782,6 +830,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
782 | struct radeon_connector *radeon_connector; | 830 | struct radeon_connector *radeon_connector; |
783 | struct radeon_connector_atom_dig *radeon_dig_connector; | 831 | struct radeon_connector_atom_dig *radeon_dig_connector; |
784 | uint32_t subpixel_order = SubPixelNone; | 832 | uint32_t subpixel_order = SubPixelNone; |
833 | bool shared_ddc = false; | ||
785 | int ret; | 834 | int ret; |
786 | 835 | ||
787 | /* fixme - tv/cv/din */ | 836 | /* fixme - tv/cv/din */ |
@@ -795,6 +844,13 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
795 | radeon_connector->devices |= supported_device; | 844 | radeon_connector->devices |= supported_device; |
796 | return; | 845 | return; |
797 | } | 846 | } |
847 | if (radeon_connector->ddc_bus && i2c_bus->valid) { | ||
848 | if (memcmp(&radeon_connector->ddc_bus->rec, i2c_bus, | ||
849 | sizeof(struct radeon_i2c_bus_rec)) == 0) { | ||
850 | radeon_connector->shared_ddc = true; | ||
851 | shared_ddc = true; | ||
852 | } | ||
853 | } | ||
798 | } | 854 | } |
799 | 855 | ||
800 | radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); | 856 | radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); |
@@ -805,6 +861,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
805 | 861 | ||
806 | radeon_connector->connector_id = connector_id; | 862 | radeon_connector->connector_id = connector_id; |
807 | radeon_connector->devices = supported_device; | 863 | radeon_connector->devices = supported_device; |
864 | radeon_connector->shared_ddc = shared_ddc; | ||
808 | switch (connector_type) { | 865 | switch (connector_type) { |
809 | case DRM_MODE_CONNECTOR_VGA: | 866 | case DRM_MODE_CONNECTOR_VGA: |
810 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 867 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 4f7afc79dd82..0b2f9c2ad2c1 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -1941,8 +1941,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) | |||
1941 | for (t = 0; t < dev_priv->usec_timeout; t++) { | 1941 | for (t = 0; t < dev_priv->usec_timeout; t++) { |
1942 | u32 done_age = GET_SCRATCH(dev_priv, 1); | 1942 | u32 done_age = GET_SCRATCH(dev_priv, 1); |
1943 | DRM_DEBUG("done_age = %d\n", done_age); | 1943 | DRM_DEBUG("done_age = %d\n", done_age); |
1944 | for (i = start; i < dma->buf_count; i++) { | 1944 | for (i = 0; i < dma->buf_count; i++) { |
1945 | buf = dma->buflist[i]; | 1945 | buf = dma->buflist[start]; |
1946 | buf_priv = buf->dev_private; | 1946 | buf_priv = buf->dev_private; |
1947 | if (buf->file_priv == NULL || (buf->pending && | 1947 | if (buf->file_priv == NULL || (buf->pending && |
1948 | buf_priv->age <= | 1948 | buf_priv->age <= |
@@ -1951,7 +1951,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) | |||
1951 | buf->pending = 0; | 1951 | buf->pending = 0; |
1952 | return buf; | 1952 | return buf; |
1953 | } | 1953 | } |
1954 | start = 0; | 1954 | if (++start >= dma->buf_count) |
1955 | start = 0; | ||
1955 | } | 1956 | } |
1956 | 1957 | ||
1957 | if (t) { | 1958 | if (t) { |
@@ -1960,47 +1961,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) | |||
1960 | } | 1961 | } |
1961 | } | 1962 | } |
1962 | 1963 | ||
1963 | DRM_DEBUG("returning NULL!\n"); | ||
1964 | return NULL; | 1964 | return NULL; |
1965 | } | 1965 | } |
1966 | 1966 | ||
1967 | #if 0 | ||
1968 | struct drm_buf *radeon_freelist_get(struct drm_device * dev) | ||
1969 | { | ||
1970 | struct drm_device_dma *dma = dev->dma; | ||
1971 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
1972 | drm_radeon_buf_priv_t *buf_priv; | ||
1973 | struct drm_buf *buf; | ||
1974 | int i, t; | ||
1975 | int start; | ||
1976 | u32 done_age; | ||
1977 | |||
1978 | done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); | ||
1979 | if (++dev_priv->last_buf >= dma->buf_count) | ||
1980 | dev_priv->last_buf = 0; | ||
1981 | |||
1982 | start = dev_priv->last_buf; | ||
1983 | dev_priv->stats.freelist_loops++; | ||
1984 | |||
1985 | for (t = 0; t < 2; t++) { | ||
1986 | for (i = start; i < dma->buf_count; i++) { | ||
1987 | buf = dma->buflist[i]; | ||
1988 | buf_priv = buf->dev_private; | ||
1989 | if (buf->file_priv == 0 || (buf->pending && | ||
1990 | buf_priv->age <= | ||
1991 | done_age)) { | ||
1992 | dev_priv->stats.requested_bufs++; | ||
1993 | buf->pending = 0; | ||
1994 | return buf; | ||
1995 | } | ||
1996 | } | ||
1997 | start = 0; | ||
1998 | } | ||
1999 | |||
2000 | return NULL; | ||
2001 | } | ||
2002 | #endif | ||
2003 | |||
2004 | void radeon_freelist_reset(struct drm_device * dev) | 1967 | void radeon_freelist_reset(struct drm_device * dev) |
2005 | { | 1968 | { |
2006 | struct drm_device_dma *dma = dev->dma; | 1969 | struct drm_device_dma *dma = dev->dma; |
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index b13c79e38bc0..28772a37009c 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -109,9 +109,15 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, | |||
109 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 109 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
110 | struct radeon_device *rdev = crtc->dev->dev_private; | 110 | struct radeon_device *rdev = crtc->dev->dev_private; |
111 | 111 | ||
112 | if (ASIC_IS_AVIVO(rdev)) | 112 | if (ASIC_IS_AVIVO(rdev)) { |
113 | if (rdev->family >= CHIP_RV770) { | ||
114 | if (radeon_crtc->crtc_id) | ||
115 | WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, 0); | ||
116 | else | ||
117 | WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 0); | ||
118 | } | ||
113 | WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr); | 119 | WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr); |
114 | else { | 120 | } else { |
115 | radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr; | 121 | radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr; |
116 | /* offset is from DISP(2)_BASE_ADDRESS */ | 122 | /* offset is from DISP(2)_BASE_ADDRESS */ |
117 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); | 123 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index df988142e6b0..e3f9edfa40fe 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -444,20 +444,24 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) | |||
444 | return r; | 444 | return r; |
445 | } | 445 | } |
446 | 446 | ||
447 | static struct card_info atom_card_info = { | ||
448 | .dev = NULL, | ||
449 | .reg_read = cail_reg_read, | ||
450 | .reg_write = cail_reg_write, | ||
451 | .mc_read = cail_mc_read, | ||
452 | .mc_write = cail_mc_write, | ||
453 | .pll_read = cail_pll_read, | ||
454 | .pll_write = cail_pll_write, | ||
455 | }; | ||
456 | |||
457 | int radeon_atombios_init(struct radeon_device *rdev) | 447 | int radeon_atombios_init(struct radeon_device *rdev) |
458 | { | 448 | { |
459 | atom_card_info.dev = rdev->ddev; | 449 | struct card_info *atom_card_info = |
460 | rdev->mode_info.atom_context = atom_parse(&atom_card_info, rdev->bios); | 450 | kzalloc(sizeof(struct card_info), GFP_KERNEL); |
451 | |||
452 | if (!atom_card_info) | ||
453 | return -ENOMEM; | ||
454 | |||
455 | rdev->mode_info.atom_card_info = atom_card_info; | ||
456 | atom_card_info->dev = rdev->ddev; | ||
457 | atom_card_info->reg_read = cail_reg_read; | ||
458 | atom_card_info->reg_write = cail_reg_write; | ||
459 | atom_card_info->mc_read = cail_mc_read; | ||
460 | atom_card_info->mc_write = cail_mc_write; | ||
461 | atom_card_info->pll_read = cail_pll_read; | ||
462 | atom_card_info->pll_write = cail_pll_write; | ||
463 | |||
464 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); | ||
461 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); | 465 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); |
462 | return 0; | 466 | return 0; |
463 | } | 467 | } |
@@ -465,6 +469,7 @@ int radeon_atombios_init(struct radeon_device *rdev) | |||
465 | void radeon_atombios_fini(struct radeon_device *rdev) | 469 | void radeon_atombios_fini(struct radeon_device *rdev) |
466 | { | 470 | { |
467 | kfree(rdev->mode_info.atom_context); | 471 | kfree(rdev->mode_info.atom_context); |
472 | kfree(rdev->mode_info.atom_card_info); | ||
468 | } | 473 | } |
469 | 474 | ||
470 | int radeon_combios_init(struct radeon_device *rdev) | 475 | int radeon_combios_init(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 3655d91993a6..c85df4afcb7a 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -137,9 +137,6 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, | |||
137 | if (size != 256) { | 137 | if (size != 256) { |
138 | return; | 138 | return; |
139 | } | 139 | } |
140 | if (crtc->fb == NULL) { | ||
141 | return; | ||
142 | } | ||
143 | 140 | ||
144 | /* userspace palettes are always correct as is */ | 141 | /* userspace palettes are always correct as is */ |
145 | for (i = 0; i < 256; i++) { | 142 | for (i = 0; i < 256; i++) { |
@@ -147,7 +144,6 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, | |||
147 | radeon_crtc->lut_g[i] = green[i] >> 6; | 144 | radeon_crtc->lut_g[i] = green[i] >> 6; |
148 | radeon_crtc->lut_b[i] = blue[i] >> 6; | 145 | radeon_crtc->lut_b[i] = blue[i] >> 6; |
149 | } | 146 | } |
150 | |||
151 | radeon_crtc_load_lut(crtc); | 147 | radeon_crtc_load_lut(crtc); |
152 | } | 148 | } |
153 | 149 | ||
@@ -338,27 +334,19 @@ static bool radeon_setup_enc_conn(struct drm_device *dev) | |||
338 | 334 | ||
339 | int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | 335 | int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) |
340 | { | 336 | { |
341 | struct edid *edid; | ||
342 | int ret = 0; | 337 | int ret = 0; |
343 | 338 | ||
344 | if (!radeon_connector->ddc_bus) | 339 | if (!radeon_connector->ddc_bus) |
345 | return -1; | 340 | return -1; |
346 | if (!radeon_connector->edid) { | 341 | if (!radeon_connector->edid) { |
347 | radeon_i2c_do_lock(radeon_connector, 1); | 342 | radeon_i2c_do_lock(radeon_connector, 1); |
348 | edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); | 343 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
349 | radeon_i2c_do_lock(radeon_connector, 0); | 344 | radeon_i2c_do_lock(radeon_connector, 0); |
350 | } else | 345 | } |
351 | edid = radeon_connector->edid; | ||
352 | 346 | ||
353 | if (edid) { | 347 | if (radeon_connector->edid) { |
354 | /* update digital bits here */ | 348 | drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); |
355 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | 349 | ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); |
356 | radeon_connector->use_digital = 1; | ||
357 | else | ||
358 | radeon_connector->use_digital = 0; | ||
359 | drm_mode_connector_update_edid_property(&radeon_connector->base, edid); | ||
360 | ret = drm_add_edid_modes(&radeon_connector->base, edid); | ||
361 | kfree(edid); | ||
362 | return ret; | 350 | return ret; |
363 | } | 351 | } |
364 | drm_mode_connector_update_edid_property(&radeon_connector->base, NULL); | 352 | drm_mode_connector_update_edid_property(&radeon_connector->base, NULL); |
@@ -765,7 +753,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
765 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; | 753 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; |
766 | memcpy(&radeon_crtc->native_mode, | 754 | memcpy(&radeon_crtc->native_mode, |
767 | &radeon_encoder->native_mode, | 755 | &radeon_encoder->native_mode, |
768 | sizeof(struct radeon_native_mode)); | 756 | sizeof(struct drm_display_mode)); |
769 | first = false; | 757 | first = false; |
770 | } else { | 758 | } else { |
771 | if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { | 759 | if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { |
@@ -783,10 +771,10 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
783 | if (radeon_crtc->rmx_type != RMX_OFF) { | 771 | if (radeon_crtc->rmx_type != RMX_OFF) { |
784 | fixed20_12 a, b; | 772 | fixed20_12 a, b; |
785 | a.full = rfixed_const(crtc->mode.vdisplay); | 773 | a.full = rfixed_const(crtc->mode.vdisplay); |
786 | b.full = rfixed_const(radeon_crtc->native_mode.panel_xres); | 774 | b.full = rfixed_const(radeon_crtc->native_mode.hdisplay); |
787 | radeon_crtc->vsc.full = rfixed_div(a, b); | 775 | radeon_crtc->vsc.full = rfixed_div(a, b); |
788 | a.full = rfixed_const(crtc->mode.hdisplay); | 776 | a.full = rfixed_const(crtc->mode.hdisplay); |
789 | b.full = rfixed_const(radeon_crtc->native_mode.panel_yres); | 777 | b.full = rfixed_const(radeon_crtc->native_mode.vdisplay); |
790 | radeon_crtc->hsc.full = rfixed_div(a, b); | 778 | radeon_crtc->hsc.full = rfixed_div(a, b); |
791 | } else { | 779 | } else { |
792 | radeon_crtc->vsc.full = rfixed_const(1); | 780 | radeon_crtc->vsc.full = rfixed_const(1); |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index a65ab1a0dad2..2aa5994a29d5 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -31,6 +31,10 @@ | |||
31 | 31 | ||
32 | extern int atom_debug; | 32 | extern int atom_debug; |
33 | 33 | ||
34 | /* evil but including atombios.h is much worse */ | ||
35 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | ||
36 | struct drm_display_mode *mode); | ||
37 | |||
34 | uint32_t | 38 | uint32_t |
35 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) | 39 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) |
36 | { | 40 | { |
@@ -167,49 +171,17 @@ void radeon_rmx_mode_fixup(struct drm_encoder *encoder, | |||
167 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 171 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
168 | struct drm_device *dev = encoder->dev; | 172 | struct drm_device *dev = encoder->dev; |
169 | struct radeon_device *rdev = dev->dev_private; | 173 | struct radeon_device *rdev = dev->dev_private; |
170 | struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; | 174 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
171 | 175 | ||
172 | if (mode->hdisplay < native_mode->panel_xres || | 176 | if (mode->hdisplay < native_mode->hdisplay || |
173 | mode->vdisplay < native_mode->panel_yres) { | 177 | mode->vdisplay < native_mode->vdisplay) { |
174 | if (ASIC_IS_AVIVO(rdev)) { | 178 | int mode_id = adjusted_mode->base.id; |
175 | adjusted_mode->hdisplay = native_mode->panel_xres; | 179 | *adjusted_mode = *native_mode; |
176 | adjusted_mode->vdisplay = native_mode->panel_yres; | 180 | if (!ASIC_IS_AVIVO(rdev)) { |
177 | adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank; | 181 | adjusted_mode->hdisplay = mode->hdisplay; |
178 | adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus; | 182 | adjusted_mode->vdisplay = mode->vdisplay; |
179 | adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width; | ||
180 | adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank; | ||
181 | adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus; | ||
182 | adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width; | ||
183 | /* update crtc values */ | ||
184 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
185 | /* adjust crtc values */ | ||
186 | adjusted_mode->crtc_hdisplay = native_mode->panel_xres; | ||
187 | adjusted_mode->crtc_vdisplay = native_mode->panel_yres; | ||
188 | adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank; | ||
189 | adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus; | ||
190 | adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width; | ||
191 | adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank; | ||
192 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus; | ||
193 | adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width; | ||
194 | } else { | ||
195 | adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank; | ||
196 | adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus; | ||
197 | adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width; | ||
198 | adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank; | ||
199 | adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus; | ||
200 | adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width; | ||
201 | /* update crtc values */ | ||
202 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
203 | /* adjust crtc values */ | ||
204 | adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank; | ||
205 | adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus; | ||
206 | adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width; | ||
207 | adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank; | ||
208 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus; | ||
209 | adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width; | ||
210 | } | 183 | } |
211 | adjusted_mode->flags = native_mode->flags; | 184 | adjusted_mode->base.id = mode_id; |
212 | adjusted_mode->clock = native_mode->dotclock; | ||
213 | } | 185 | } |
214 | } | 186 | } |
215 | 187 | ||
@@ -219,7 +191,11 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
219 | struct drm_display_mode *adjusted_mode) | 191 | struct drm_display_mode *adjusted_mode) |
220 | { | 192 | { |
221 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 193 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
194 | struct drm_device *dev = encoder->dev; | ||
195 | struct radeon_device *rdev = dev->dev_private; | ||
222 | 196 | ||
197 | /* set the active encoder to connector routing */ | ||
198 | radeon_encoder_set_active_device(encoder); | ||
223 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 199 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
224 | 200 | ||
225 | if (radeon_encoder->rmx_type != RMX_OFF) | 201 | if (radeon_encoder->rmx_type != RMX_OFF) |
@@ -230,6 +206,18 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
230 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) | 206 | && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) |
231 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; | 207 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
232 | 208 | ||
209 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { | ||
210 | struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; | ||
211 | if (tv_dac) { | ||
212 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
213 | tv_dac->tv_std == TV_STD_NTSC_J || | ||
214 | tv_dac->tv_std == TV_STD_PAL_M) | ||
215 | radeon_atom_get_tv_timings(rdev, 0, adjusted_mode); | ||
216 | else | ||
217 | radeon_atom_get_tv_timings(rdev, 1, adjusted_mode); | ||
218 | } | ||
219 | } | ||
220 | |||
233 | return true; | 221 | return true; |
234 | } | 222 | } |
235 | 223 | ||
@@ -461,7 +449,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
461 | case 1: | 449 | case 1: |
462 | args.v1.ucMisc = 0; | 450 | args.v1.ucMisc = 0; |
463 | args.v1.ucAction = action; | 451 | args.v1.ucAction = action; |
464 | if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) | 452 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
465 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | 453 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; |
466 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 454 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
467 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 455 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
@@ -486,7 +474,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
486 | if (dig->coherent_mode) | 474 | if (dig->coherent_mode) |
487 | args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; | 475 | args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; |
488 | } | 476 | } |
489 | if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) | 477 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
490 | args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | 478 | args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; |
491 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 479 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
492 | args.v2.ucTruncate = 0; | 480 | args.v2.ucTruncate = 0; |
@@ -544,7 +532,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
544 | switch (connector->connector_type) { | 532 | switch (connector->connector_type) { |
545 | case DRM_MODE_CONNECTOR_DVII: | 533 | case DRM_MODE_CONNECTOR_DVII: |
546 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | 534 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
547 | if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) | 535 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
548 | return ATOM_ENCODER_MODE_HDMI; | 536 | return ATOM_ENCODER_MODE_HDMI; |
549 | else if (radeon_connector->use_digital) | 537 | else if (radeon_connector->use_digital) |
550 | return ATOM_ENCODER_MODE_DVI; | 538 | return ATOM_ENCODER_MODE_DVI; |
@@ -554,7 +542,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
554 | case DRM_MODE_CONNECTOR_DVID: | 542 | case DRM_MODE_CONNECTOR_DVID: |
555 | case DRM_MODE_CONNECTOR_HDMIA: | 543 | case DRM_MODE_CONNECTOR_HDMIA: |
556 | default: | 544 | default: |
557 | if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) | 545 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
558 | return ATOM_ENCODER_MODE_HDMI; | 546 | return ATOM_ENCODER_MODE_HDMI; |
559 | else | 547 | else |
560 | return ATOM_ENCODER_MODE_DVI; | 548 | return ATOM_ENCODER_MODE_DVI; |
@@ -566,7 +554,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
566 | /*if (radeon_output->MonType == MT_DP) | 554 | /*if (radeon_output->MonType == MT_DP) |
567 | return ATOM_ENCODER_MODE_DP; | 555 | return ATOM_ENCODER_MODE_DP; |
568 | else*/ | 556 | else*/ |
569 | if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) | 557 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
570 | return ATOM_ENCODER_MODE_HDMI; | 558 | return ATOM_ENCODER_MODE_HDMI; |
571 | else | 559 | else |
572 | return ATOM_ENCODER_MODE_DVI; | 560 | return ATOM_ENCODER_MODE_DVI; |
@@ -874,16 +862,9 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
874 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; | 862 | DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; |
875 | int index = 0; | 863 | int index = 0; |
876 | bool is_dig = false; | 864 | bool is_dig = false; |
877 | int devices; | ||
878 | 865 | ||
879 | memset(&args, 0, sizeof(args)); | 866 | memset(&args, 0, sizeof(args)); |
880 | 867 | ||
881 | /* on DPMS off we have no idea if active device is meaningful */ | ||
882 | if (mode != DRM_MODE_DPMS_ON && !radeon_encoder->active_device) | ||
883 | devices = radeon_encoder->devices; | ||
884 | else | ||
885 | devices = radeon_encoder->active_device; | ||
886 | |||
887 | DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", | 868 | DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", |
888 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, | 869 | radeon_encoder->encoder_id, mode, radeon_encoder->devices, |
889 | radeon_encoder->active_device); | 870 | radeon_encoder->active_device); |
@@ -914,18 +895,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
914 | break; | 895 | break; |
915 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | 896 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
916 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 897 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
917 | if (devices & (ATOM_DEVICE_TV_SUPPORT)) | 898 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
918 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | 899 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
919 | else if (devices & (ATOM_DEVICE_CV_SUPPORT)) | 900 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
920 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | 901 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); |
921 | else | 902 | else |
922 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); | 903 | index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); |
923 | break; | 904 | break; |
924 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 905 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
925 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 906 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
926 | if (devices & (ATOM_DEVICE_TV_SUPPORT)) | 907 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
927 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); | 908 | index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
928 | else if (devices & (ATOM_DEVICE_CV_SUPPORT)) | 909 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
929 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); | 910 | index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); |
930 | else | 911 | else |
931 | index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); | 912 | index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); |
@@ -1104,8 +1085,11 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, | |||
1104 | } | 1085 | } |
1105 | 1086 | ||
1106 | /* set scaler clears this on some chips */ | 1087 | /* set scaler clears this on some chips */ |
1107 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) | 1088 | if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { |
1108 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN); | 1089 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) |
1090 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | ||
1091 | AVIVO_D1MODE_INTERLEAVE_EN); | ||
1092 | } | ||
1109 | } | 1093 | } |
1110 | 1094 | ||
1111 | static void | 1095 | static void |
@@ -1268,8 +1252,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
1268 | { | 1252 | { |
1269 | radeon_atom_output_lock(encoder, true); | 1253 | radeon_atom_output_lock(encoder, true); |
1270 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 1254 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
1271 | |||
1272 | radeon_encoder_set_active_device(encoder); | ||
1273 | } | 1255 | } |
1274 | 1256 | ||
1275 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | 1257 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index a931af065dd4..a68d7566178c 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -140,15 +140,15 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
140 | WARN(1, "trying to unbind memory to unitialized GART !\n"); | 140 | WARN(1, "trying to unbind memory to unitialized GART !\n"); |
141 | return; | 141 | return; |
142 | } | 142 | } |
143 | t = offset / 4096; | 143 | t = offset / RADEON_GPU_PAGE_SIZE; |
144 | p = t / (PAGE_SIZE / 4096); | 144 | p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
145 | for (i = 0; i < pages; i++, p++) { | 145 | for (i = 0; i < pages; i++, p++) { |
146 | if (rdev->gart.pages[p]) { | 146 | if (rdev->gart.pages[p]) { |
147 | pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], | 147 | pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], |
148 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 148 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
149 | rdev->gart.pages[p] = NULL; | 149 | rdev->gart.pages[p] = NULL; |
150 | rdev->gart.pages_addr[p] = 0; | 150 | rdev->gart.pages_addr[p] = 0; |
151 | for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) { | 151 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
152 | radeon_gart_set_page(rdev, t, 0); | 152 | radeon_gart_set_page(rdev, t, 0); |
153 | } | 153 | } |
154 | } | 154 | } |
@@ -169,8 +169,8 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
169 | DRM_ERROR("trying to bind memory to unitialized GART !\n"); | 169 | DRM_ERROR("trying to bind memory to unitialized GART !\n"); |
170 | return -EINVAL; | 170 | return -EINVAL; |
171 | } | 171 | } |
172 | t = offset / 4096; | 172 | t = offset / RADEON_GPU_PAGE_SIZE; |
173 | p = t / (PAGE_SIZE / 4096); | 173 | p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
174 | 174 | ||
175 | for (i = 0; i < pages; i++, p++) { | 175 | for (i = 0; i < pages; i++, p++) { |
176 | /* we need to support large memory configurations */ | 176 | /* we need to support large memory configurations */ |
@@ -185,9 +185,9 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
185 | } | 185 | } |
186 | rdev->gart.pages[p] = pagelist[i]; | 186 | rdev->gart.pages[p] = pagelist[i]; |
187 | page_base = rdev->gart.pages_addr[p]; | 187 | page_base = rdev->gart.pages_addr[p]; |
188 | for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) { | 188 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
189 | radeon_gart_set_page(rdev, t, page_base); | 189 | radeon_gart_set_page(rdev, t, page_base); |
190 | page_base += 4096; | 190 | page_base += RADEON_GPU_PAGE_SIZE; |
191 | } | 191 | } |
192 | } | 192 | } |
193 | mb(); | 193 | mb(); |
@@ -200,14 +200,14 @@ int radeon_gart_init(struct radeon_device *rdev) | |||
200 | if (rdev->gart.pages) { | 200 | if (rdev->gart.pages) { |
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
203 | /* We need PAGE_SIZE >= 4096 */ | 203 | /* We need PAGE_SIZE >= RADEON_GPU_PAGE_SIZE */ |
204 | if (PAGE_SIZE < 4096) { | 204 | if (PAGE_SIZE < RADEON_GPU_PAGE_SIZE) { |
205 | DRM_ERROR("Page size is smaller than GPU page size!\n"); | 205 | DRM_ERROR("Page size is smaller than GPU page size!\n"); |
206 | return -EINVAL; | 206 | return -EINVAL; |
207 | } | 207 | } |
208 | /* Compute table size */ | 208 | /* Compute table size */ |
209 | rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE; | 209 | rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE; |
210 | rdev->gart.num_gpu_pages = rdev->mc.gtt_size / 4096; | 210 | rdev->gart.num_gpu_pages = rdev->mc.gtt_size / RADEON_GPU_PAGE_SIZE; |
211 | DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", | 211 | DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", |
212 | rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); | 212 | rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); |
213 | /* Allocate pages table */ | 213 | /* Allocate pages table */ |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 8e0a8759e428..a0fe6232dcb6 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -92,6 +92,13 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
92 | if (r) { | 92 | if (r) { |
93 | return r; | 93 | return r; |
94 | } | 94 | } |
95 | /* enable msi */ | ||
96 | rdev->msi_enabled = 0; | ||
97 | if (rdev->family >= CHIP_RV380) { | ||
98 | int ret = pci_enable_msi(rdev->pdev); | ||
99 | if (!ret) | ||
100 | rdev->msi_enabled = 1; | ||
101 | } | ||
95 | drm_irq_install(rdev->ddev); | 102 | drm_irq_install(rdev->ddev); |
96 | rdev->irq.installed = true; | 103 | rdev->irq.installed = true; |
97 | DRM_INFO("radeon: irq initialized.\n"); | 104 | DRM_INFO("radeon: irq initialized.\n"); |
@@ -103,5 +110,7 @@ void radeon_irq_kms_fini(struct radeon_device *rdev) | |||
103 | if (rdev->irq.installed) { | 110 | if (rdev->irq.installed) { |
104 | rdev->irq.installed = false; | 111 | rdev->irq.installed = false; |
105 | drm_irq_uninstall(rdev->ddev); | 112 | drm_irq_uninstall(rdev->ddev); |
113 | if (rdev->msi_enabled) | ||
114 | pci_disable_msi(rdev->pdev); | ||
106 | } | 115 | } |
107 | } | 116 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 36410f85d705..8d0b7aa87fa4 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -48,7 +48,7 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
48 | u32 fp_horz_stretch, fp_vert_stretch, fp_horz_vert_active; | 48 | u32 fp_horz_stretch, fp_vert_stretch, fp_horz_vert_active; |
49 | u32 fp_h_sync_strt_wid, fp_crtc_h_total_disp; | 49 | u32 fp_h_sync_strt_wid, fp_crtc_h_total_disp; |
50 | u32 fp_v_sync_strt_wid, fp_crtc_v_total_disp; | 50 | u32 fp_v_sync_strt_wid, fp_crtc_v_total_disp; |
51 | struct radeon_native_mode *native_mode = &radeon_crtc->native_mode; | 51 | struct drm_display_mode *native_mode = &radeon_crtc->native_mode; |
52 | 52 | ||
53 | fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH) & | 53 | fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH) & |
54 | (RADEON_VERT_STRETCH_RESERVED | | 54 | (RADEON_VERT_STRETCH_RESERVED | |
@@ -95,19 +95,19 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
95 | 95 | ||
96 | fp_horz_vert_active = 0; | 96 | fp_horz_vert_active = 0; |
97 | 97 | ||
98 | if (native_mode->panel_xres == 0 || | 98 | if (native_mode->hdisplay == 0 || |
99 | native_mode->panel_yres == 0) { | 99 | native_mode->vdisplay == 0) { |
100 | hscale = false; | 100 | hscale = false; |
101 | vscale = false; | 101 | vscale = false; |
102 | } else { | 102 | } else { |
103 | if (xres > native_mode->panel_xres) | 103 | if (xres > native_mode->hdisplay) |
104 | xres = native_mode->panel_xres; | 104 | xres = native_mode->hdisplay; |
105 | if (yres > native_mode->panel_yres) | 105 | if (yres > native_mode->vdisplay) |
106 | yres = native_mode->panel_yres; | 106 | yres = native_mode->vdisplay; |
107 | 107 | ||
108 | if (xres == native_mode->panel_xres) | 108 | if (xres == native_mode->hdisplay) |
109 | hscale = false; | 109 | hscale = false; |
110 | if (yres == native_mode->panel_yres) | 110 | if (yres == native_mode->vdisplay) |
111 | vscale = false; | 111 | vscale = false; |
112 | } | 112 | } |
113 | 113 | ||
@@ -119,11 +119,11 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
119 | else { | 119 | else { |
120 | inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0; | 120 | inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0; |
121 | scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX) | 121 | scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX) |
122 | / native_mode->panel_xres + 1; | 122 | / native_mode->hdisplay + 1; |
123 | fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) | | 123 | fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) | |
124 | RADEON_HORZ_STRETCH_BLEND | | 124 | RADEON_HORZ_STRETCH_BLEND | |
125 | RADEON_HORZ_STRETCH_ENABLE | | 125 | RADEON_HORZ_STRETCH_ENABLE | |
126 | ((native_mode->panel_xres/8-1) << 16)); | 126 | ((native_mode->hdisplay/8-1) << 16)); |
127 | } | 127 | } |
128 | 128 | ||
129 | if (!vscale) | 129 | if (!vscale) |
@@ -131,11 +131,11 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
131 | else { | 131 | else { |
132 | inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0; | 132 | inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0; |
133 | scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX) | 133 | scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX) |
134 | / native_mode->panel_yres + 1; | 134 | / native_mode->vdisplay + 1; |
135 | fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) | | 135 | fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) | |
136 | RADEON_VERT_STRETCH_ENABLE | | 136 | RADEON_VERT_STRETCH_ENABLE | |
137 | RADEON_VERT_STRETCH_BLEND | | 137 | RADEON_VERT_STRETCH_BLEND | |
138 | ((native_mode->panel_yres-1) << 12)); | 138 | ((native_mode->vdisplay-1) << 12)); |
139 | } | 139 | } |
140 | break; | 140 | break; |
141 | case RMX_CENTER: | 141 | case RMX_CENTER: |
@@ -175,8 +175,8 @@ static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | |||
175 | ? RADEON_CRTC_V_SYNC_POL | 175 | ? RADEON_CRTC_V_SYNC_POL |
176 | : 0))); | 176 | : 0))); |
177 | 177 | ||
178 | fp_horz_vert_active = (((native_mode->panel_yres) & 0xfff) | | 178 | fp_horz_vert_active = (((native_mode->vdisplay) & 0xfff) | |
179 | (((native_mode->panel_xres / 8) & 0x1ff) << 16)); | 179 | (((native_mode->hdisplay / 8) & 0x1ff) << 16)); |
180 | break; | 180 | break; |
181 | case RMX_OFF: | 181 | case RMX_OFF: |
182 | default: | 182 | default: |
@@ -532,6 +532,10 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
532 | radeon_fb = to_radeon_framebuffer(old_fb); | 532 | radeon_fb = to_radeon_framebuffer(old_fb); |
533 | radeon_gem_object_unpin(radeon_fb->obj); | 533 | radeon_gem_object_unpin(radeon_fb->obj); |
534 | } | 534 | } |
535 | |||
536 | /* Bytes per pixel may have changed */ | ||
537 | radeon_bandwidth_update(rdev); | ||
538 | |||
535 | return 0; | 539 | return 0; |
536 | } | 540 | } |
537 | 541 | ||
@@ -664,6 +668,9 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod | |||
664 | 668 | ||
665 | WREG32(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl); | 669 | WREG32(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl); |
666 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | 670 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
671 | |||
672 | WREG32(RADEON_FP_H2_SYNC_STRT_WID, crtc_h_sync_strt_wid); | ||
673 | WREG32(RADEON_FP_V2_SYNC_STRT_WID, crtc_v_sync_strt_wid); | ||
667 | } else { | 674 | } else { |
668 | uint32_t crtc_gen_cntl; | 675 | uint32_t crtc_gen_cntl; |
669 | uint32_t crtc_ext_cntl; | 676 | uint32_t crtc_ext_cntl; |
@@ -1015,14 +1022,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
1015 | int x, int y, struct drm_framebuffer *old_fb) | 1022 | int x, int y, struct drm_framebuffer *old_fb) |
1016 | { | 1023 | { |
1017 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1024 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1018 | struct drm_device *dev = crtc->dev; | ||
1019 | struct radeon_device *rdev = dev->dev_private; | ||
1020 | 1025 | ||
1021 | /* TODO TV */ | 1026 | /* TODO TV */ |
1022 | radeon_crtc_set_base(crtc, x, y, old_fb); | 1027 | radeon_crtc_set_base(crtc, x, y, old_fb); |
1023 | radeon_set_crtc_timing(crtc, adjusted_mode); | 1028 | radeon_set_crtc_timing(crtc, adjusted_mode); |
1024 | radeon_set_pll(crtc, adjusted_mode); | 1029 | radeon_set_pll(crtc, adjusted_mode); |
1025 | radeon_bandwidth_update(rdev); | ||
1026 | if (radeon_crtc->crtc_id == 0) { | 1030 | if (radeon_crtc->crtc_id == 0) { |
1027 | radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode); | 1031 | radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode); |
1028 | } else { | 1032 | } else { |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 6ceb958fd194..00382122869b 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -107,8 +107,6 @@ static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) | |||
107 | else | 107 | else |
108 | radeon_combios_output_lock(encoder, true); | 108 | radeon_combios_output_lock(encoder, true); |
109 | radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); | 109 | radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); |
110 | |||
111 | radeon_encoder_set_active_device(encoder); | ||
112 | } | 110 | } |
113 | 111 | ||
114 | static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) | 112 | static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) |
@@ -192,6 +190,8 @@ static bool radeon_legacy_lvds_mode_fixup(struct drm_encoder *encoder, | |||
192 | { | 190 | { |
193 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 191 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
194 | 192 | ||
193 | /* set the active encoder to connector routing */ | ||
194 | radeon_encoder_set_active_device(encoder); | ||
195 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 195 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
196 | 196 | ||
197 | if (radeon_encoder->rmx_type != RMX_OFF) | 197 | if (radeon_encoder->rmx_type != RMX_OFF) |
@@ -218,7 +218,8 @@ static bool radeon_legacy_primary_dac_mode_fixup(struct drm_encoder *encoder, | |||
218 | struct drm_display_mode *mode, | 218 | struct drm_display_mode *mode, |
219 | struct drm_display_mode *adjusted_mode) | 219 | struct drm_display_mode *adjusted_mode) |
220 | { | 220 | { |
221 | 221 | /* set the active encoder to connector routing */ | |
222 | radeon_encoder_set_active_device(encoder); | ||
222 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 223 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
223 | 224 | ||
224 | return true; | 225 | return true; |
@@ -272,7 +273,6 @@ static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) | |||
272 | else | 273 | else |
273 | radeon_combios_output_lock(encoder, true); | 274 | radeon_combios_output_lock(encoder, true); |
274 | radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); | 275 | radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); |
275 | radeon_encoder_set_active_device(encoder); | ||
276 | } | 276 | } |
277 | 277 | ||
278 | static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) | 278 | static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) |
@@ -468,7 +468,6 @@ static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) | |||
468 | else | 468 | else |
469 | radeon_combios_output_lock(encoder, true); | 469 | radeon_combios_output_lock(encoder, true); |
470 | radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); | 470 | radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); |
471 | radeon_encoder_set_active_device(encoder); | ||
472 | } | 471 | } |
473 | 472 | ||
474 | static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) | 473 | static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) |
@@ -543,6 +542,14 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, | |||
543 | 542 | ||
544 | fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); | 543 | fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); |
545 | 544 | ||
545 | fp_gen_cntl &= ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN | | ||
546 | RADEON_FP_DFP_SYNC_SEL | | ||
547 | RADEON_FP_CRT_SYNC_SEL | | ||
548 | RADEON_FP_CRTC_LOCK_8DOT | | ||
549 | RADEON_FP_USE_SHADOW_EN | | ||
550 | RADEON_FP_CRTC_USE_SHADOW_VEND | | ||
551 | RADEON_FP_CRT_SYNC_ALT); | ||
552 | |||
546 | if (1) /* FIXME rgbBits == 8 */ | 553 | if (1) /* FIXME rgbBits == 8 */ |
547 | fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ | 554 | fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ |
548 | else | 555 | else |
@@ -556,7 +563,7 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, | |||
556 | else | 563 | else |
557 | fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; | 564 | fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; |
558 | } else | 565 | } else |
559 | fp_gen_cntl |= RADEON_FP_SEL_CRTC1; | 566 | fp_gen_cntl &= ~RADEON_FP_SEL_CRTC2; |
560 | } else { | 567 | } else { |
561 | if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) { | 568 | if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) { |
562 | fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; | 569 | fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; |
@@ -593,7 +600,8 @@ static bool radeon_legacy_tmds_ext_mode_fixup(struct drm_encoder *encoder, | |||
593 | struct drm_display_mode *mode, | 600 | struct drm_display_mode *mode, |
594 | struct drm_display_mode *adjusted_mode) | 601 | struct drm_display_mode *adjusted_mode) |
595 | { | 602 | { |
596 | 603 | /* set the active encoder to connector routing */ | |
604 | radeon_encoder_set_active_device(encoder); | ||
597 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 605 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
598 | 606 | ||
599 | return true; | 607 | return true; |
@@ -636,7 +644,6 @@ static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) | |||
636 | else | 644 | else |
637 | radeon_combios_output_lock(encoder, true); | 645 | radeon_combios_output_lock(encoder, true); |
638 | radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); | 646 | radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); |
639 | radeon_encoder_set_active_device(encoder); | ||
640 | } | 647 | } |
641 | 648 | ||
642 | static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) | 649 | static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) |
@@ -735,7 +742,8 @@ static bool radeon_legacy_tv_dac_mode_fixup(struct drm_encoder *encoder, | |||
735 | struct drm_display_mode *mode, | 742 | struct drm_display_mode *mode, |
736 | struct drm_display_mode *adjusted_mode) | 743 | struct drm_display_mode *adjusted_mode) |
737 | { | 744 | { |
738 | 745 | /* set the active encoder to connector routing */ | |
746 | radeon_encoder_set_active_device(encoder); | ||
739 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 747 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
740 | 748 | ||
741 | return true; | 749 | return true; |
@@ -839,7 +847,6 @@ static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) | |||
839 | else | 847 | else |
840 | radeon_combios_output_lock(encoder, true); | 848 | radeon_combios_output_lock(encoder, true); |
841 | radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); | 849 | radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); |
842 | radeon_encoder_set_active_device(encoder); | ||
843 | } | 850 | } |
844 | 851 | ||
845 | static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) | 852 | static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index e61226817ccf..ccb783868ad6 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -172,6 +172,7 @@ enum radeon_connector_table { | |||
172 | 172 | ||
173 | struct radeon_mode_info { | 173 | struct radeon_mode_info { |
174 | struct atom_context *atom_context; | 174 | struct atom_context *atom_context; |
175 | struct card_info *atom_card_info; | ||
175 | enum radeon_connector_table connector_table; | 176 | enum radeon_connector_table connector_table; |
176 | bool mode_config_initialized; | 177 | bool mode_config_initialized; |
177 | struct radeon_crtc *crtcs[2]; | 178 | struct radeon_crtc *crtcs[2]; |
@@ -186,17 +187,6 @@ struct radeon_mode_info { | |||
186 | 187 | ||
187 | }; | 188 | }; |
188 | 189 | ||
189 | struct radeon_native_mode { | ||
190 | /* preferred mode */ | ||
191 | uint32_t panel_xres, panel_yres; | ||
192 | uint32_t hoverplus, hsync_width; | ||
193 | uint32_t hblank; | ||
194 | uint32_t voverplus, vsync_width; | ||
195 | uint32_t vblank; | ||
196 | uint32_t dotclock; | ||
197 | uint32_t flags; | ||
198 | }; | ||
199 | |||
200 | #define MAX_H_CODE_TIMING_LEN 32 | 190 | #define MAX_H_CODE_TIMING_LEN 32 |
201 | #define MAX_V_CODE_TIMING_LEN 32 | 191 | #define MAX_V_CODE_TIMING_LEN 32 |
202 | 192 | ||
@@ -228,7 +218,7 @@ struct radeon_crtc { | |||
228 | enum radeon_rmx_type rmx_type; | 218 | enum radeon_rmx_type rmx_type; |
229 | fixed20_12 vsc; | 219 | fixed20_12 vsc; |
230 | fixed20_12 hsc; | 220 | fixed20_12 hsc; |
231 | struct radeon_native_mode native_mode; | 221 | struct drm_display_mode native_mode; |
232 | }; | 222 | }; |
233 | 223 | ||
234 | struct radeon_encoder_primary_dac { | 224 | struct radeon_encoder_primary_dac { |
@@ -248,7 +238,7 @@ struct radeon_encoder_lvds { | |||
248 | bool use_bios_dividers; | 238 | bool use_bios_dividers; |
249 | uint32_t lvds_gen_cntl; | 239 | uint32_t lvds_gen_cntl; |
250 | /* panel mode */ | 240 | /* panel mode */ |
251 | struct radeon_native_mode native_mode; | 241 | struct drm_display_mode native_mode; |
252 | }; | 242 | }; |
253 | 243 | ||
254 | struct radeon_encoder_tv_dac { | 244 | struct radeon_encoder_tv_dac { |
@@ -271,6 +261,16 @@ struct radeon_encoder_int_tmds { | |||
271 | struct radeon_tmds_pll tmds_pll[4]; | 261 | struct radeon_tmds_pll tmds_pll[4]; |
272 | }; | 262 | }; |
273 | 263 | ||
264 | /* spread spectrum */ | ||
265 | struct radeon_atom_ss { | ||
266 | uint16_t percentage; | ||
267 | uint8_t type; | ||
268 | uint8_t step; | ||
269 | uint8_t delay; | ||
270 | uint8_t range; | ||
271 | uint8_t refdiv; | ||
272 | }; | ||
273 | |||
274 | struct radeon_encoder_atom_dig { | 274 | struct radeon_encoder_atom_dig { |
275 | /* atom dig */ | 275 | /* atom dig */ |
276 | bool coherent_mode; | 276 | bool coherent_mode; |
@@ -278,8 +278,9 @@ struct radeon_encoder_atom_dig { | |||
278 | /* atom lvds */ | 278 | /* atom lvds */ |
279 | uint32_t lvds_misc; | 279 | uint32_t lvds_misc; |
280 | uint16_t panel_pwr_delay; | 280 | uint16_t panel_pwr_delay; |
281 | struct radeon_atom_ss *ss; | ||
281 | /* panel mode */ | 282 | /* panel mode */ |
282 | struct radeon_native_mode native_mode; | 283 | struct drm_display_mode native_mode; |
283 | }; | 284 | }; |
284 | 285 | ||
285 | struct radeon_encoder_atom_dac { | 286 | struct radeon_encoder_atom_dac { |
@@ -294,7 +295,7 @@ struct radeon_encoder { | |||
294 | uint32_t flags; | 295 | uint32_t flags; |
295 | uint32_t pixel_clock; | 296 | uint32_t pixel_clock; |
296 | enum radeon_rmx_type rmx_type; | 297 | enum radeon_rmx_type rmx_type; |
297 | struct radeon_native_mode native_mode; | 298 | struct drm_display_mode native_mode; |
298 | void *enc_priv; | 299 | void *enc_priv; |
299 | }; | 300 | }; |
300 | 301 | ||
@@ -308,6 +309,8 @@ struct radeon_connector { | |||
308 | uint32_t connector_id; | 309 | uint32_t connector_id; |
309 | uint32_t devices; | 310 | uint32_t devices; |
310 | struct radeon_i2c_chan *ddc_bus; | 311 | struct radeon_i2c_chan *ddc_bus; |
312 | /* some systems have a an hdmi and vga port with a shared ddc line */ | ||
313 | bool shared_ddc; | ||
311 | bool use_digital; | 314 | bool use_digital; |
312 | /* we need to mind the EDID between detect | 315 | /* we need to mind the EDID between detect |
313 | and get modes due to analog/digital/tvencoder */ | 316 | and get modes due to analog/digital/tvencoder */ |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index bfa1ab9c93e1..29ab75903ec1 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -290,6 +290,8 @@ | |||
290 | #define RADEON_BUS_CNTL 0x0030 | 290 | #define RADEON_BUS_CNTL 0x0030 |
291 | # define RADEON_BUS_MASTER_DIS (1 << 6) | 291 | # define RADEON_BUS_MASTER_DIS (1 << 6) |
292 | # define RADEON_BUS_BIOS_DIS_ROM (1 << 12) | 292 | # define RADEON_BUS_BIOS_DIS_ROM (1 << 12) |
293 | # define RS600_BUS_MASTER_DIS (1 << 14) | ||
294 | # define RS600_MSI_REARM (1 << 20) /* rs600/rs690/rs740 */ | ||
293 | # define RADEON_BUS_RD_DISCARD_EN (1 << 24) | 295 | # define RADEON_BUS_RD_DISCARD_EN (1 << 24) |
294 | # define RADEON_BUS_RD_ABORT_EN (1 << 25) | 296 | # define RADEON_BUS_RD_ABORT_EN (1 << 25) |
295 | # define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28) | 297 | # define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28) |
@@ -297,6 +299,9 @@ | |||
297 | # define RADEON_BUS_READ_BURST (1 << 30) | 299 | # define RADEON_BUS_READ_BURST (1 << 30) |
298 | #define RADEON_BUS_CNTL1 0x0034 | 300 | #define RADEON_BUS_CNTL1 0x0034 |
299 | # define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) | 301 | # define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) |
302 | /* rv370/rv380, rv410, r423/r430/r480, r5xx */ | ||
303 | #define RADEON_MSI_REARM_EN 0x0160 | ||
304 | # define RV370_MSI_REARM_EN (1 << 0) | ||
300 | 305 | ||
301 | /* #define RADEON_PCIE_INDEX 0x0030 */ | 306 | /* #define RADEON_PCIE_INDEX 0x0030 */ |
302 | /* #define RADEON_PCIE_DATA 0x0034 */ | 307 | /* #define RADEON_PCIE_DATA 0x0034 */ |
@@ -3311,6 +3316,7 @@ | |||
3311 | #define RADEON_AIC_CNTL 0x01d0 | 3316 | #define RADEON_AIC_CNTL 0x01d0 |
3312 | # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) | 3317 | # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) |
3313 | # define RADEON_DIS_OUT_OF_PCI_GART_ACCESS (1 << 1) | 3318 | # define RADEON_DIS_OUT_OF_PCI_GART_ACCESS (1 << 1) |
3319 | # define RS400_MSI_REARM (1 << 3) /* rs400/rs480 */ | ||
3314 | #define RADEON_AIC_LO_ADDR 0x01dc | 3320 | #define RADEON_AIC_LO_ADDR 0x01dc |
3315 | #define RADEON_AIC_PT_BASE 0x01d8 | 3321 | #define RADEON_AIC_PT_BASE 0x01d8 |
3316 | #define RADEON_AIC_HI_ADDR 0x01e0 | 3322 | #define RADEON_AIC_HI_ADDR 0x01e0 |
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 03c33cf4e14c..f8a465d9a1cf 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
@@ -42,7 +42,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
42 | /* Number of tests = | 42 | /* Number of tests = |
43 | * (Total GTT - IB pool - writeback page - ring buffer) / test size | 43 | * (Total GTT - IB pool - writeback page - ring buffer) / test size |
44 | */ | 44 | */ |
45 | n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - 4096 - | 45 | n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE - |
46 | rdev->cp.ring_size) / size; | 46 | rdev->cp.ring_size) / size; |
47 | 47 | ||
48 | gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); | 48 | gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); |
@@ -102,7 +102,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
102 | goto out_cleanup; | 102 | goto out_cleanup; |
103 | } | 103 | } |
104 | 104 | ||
105 | r = radeon_copy(rdev, gtt_addr, vram_addr, size / 4096, fence); | 105 | r = radeon_copy(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, fence); |
106 | if (r) { | 106 | if (r) { |
107 | DRM_ERROR("Failed GTT->VRAM copy %d\n", i); | 107 | DRM_ERROR("Failed GTT->VRAM copy %d\n", i); |
108 | goto out_cleanup; | 108 | goto out_cleanup; |
@@ -145,7 +145,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
145 | goto out_cleanup; | 145 | goto out_cleanup; |
146 | } | 146 | } |
147 | 147 | ||
148 | r = radeon_copy(rdev, vram_addr, gtt_addr, size / 4096, fence); | 148 | r = radeon_copy(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, fence); |
149 | if (r) { | 149 | if (r) { |
150 | DRM_ERROR("Failed VRAM->GTT copy %d\n", i); | 150 | DRM_ERROR("Failed VRAM->GTT copy %d\n", i); |
151 | goto out_cleanup; | 151 | goto out_cleanup; |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 765bd184b6fc..1381e06d6af3 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -295,6 +295,12 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, | |||
295 | if (unlikely(r)) { | 295 | if (unlikely(r)) { |
296 | return r; | 296 | return r; |
297 | } | 297 | } |
298 | |||
299 | r = ttm_tt_set_placement_caching(bo->ttm, tmp_mem.placement); | ||
300 | if (unlikely(r)) { | ||
301 | goto out_cleanup; | ||
302 | } | ||
303 | |||
298 | r = ttm_tt_bind(bo->ttm, &tmp_mem); | 304 | r = ttm_tt_bind(bo->ttm, &tmp_mem); |
299 | if (unlikely(r)) { | 305 | if (unlikely(r)) { |
300 | goto out_cleanup; | 306 | goto out_cleanup; |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index a769c296f6a6..ca037160a582 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -418,6 +418,8 @@ int rs400_resume(struct radeon_device *rdev) | |||
418 | rs400_gart_disable(rdev); | 418 | rs400_gart_disable(rdev); |
419 | /* Resume clock before doing reset */ | 419 | /* Resume clock before doing reset */ |
420 | r300_clock_startup(rdev); | 420 | r300_clock_startup(rdev); |
421 | /* setup MC before calling post tables */ | ||
422 | rs400_mc_program(rdev); | ||
421 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 423 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
422 | if (radeon_gpu_reset(rdev)) { | 424 | if (radeon_gpu_reset(rdev)) { |
423 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | 425 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 10dfa78762da..942754c39be9 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -242,7 +242,7 @@ void rs600_irq_disable(struct radeon_device *rdev) | |||
242 | 242 | ||
243 | int rs600_irq_process(struct radeon_device *rdev) | 243 | int rs600_irq_process(struct radeon_device *rdev) |
244 | { | 244 | { |
245 | uint32_t status; | 245 | uint32_t status, msi_rearm; |
246 | uint32_t r500_disp_int; | 246 | uint32_t r500_disp_int; |
247 | 247 | ||
248 | status = rs600_irq_ack(rdev, &r500_disp_int); | 248 | status = rs600_irq_ack(rdev, &r500_disp_int); |
@@ -260,6 +260,22 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
260 | drm_handle_vblank(rdev->ddev, 1); | 260 | drm_handle_vblank(rdev->ddev, 1); |
261 | status = rs600_irq_ack(rdev, &r500_disp_int); | 261 | status = rs600_irq_ack(rdev, &r500_disp_int); |
262 | } | 262 | } |
263 | if (rdev->msi_enabled) { | ||
264 | switch (rdev->family) { | ||
265 | case CHIP_RS600: | ||
266 | case CHIP_RS690: | ||
267 | case CHIP_RS740: | ||
268 | msi_rearm = RREG32(RADEON_BUS_CNTL) & ~RS600_MSI_REARM; | ||
269 | WREG32(RADEON_BUS_CNTL, msi_rearm); | ||
270 | WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); | ||
271 | break; | ||
272 | default: | ||
273 | msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; | ||
274 | WREG32(RADEON_MSI_REARM_EN, msi_rearm); | ||
275 | WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); | ||
276 | break; | ||
277 | } | ||
278 | } | ||
263 | return IRQ_HANDLED; | 279 | return IRQ_HANDLED; |
264 | } | 280 | } |
265 | 281 | ||
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 41a34c23e6d8..03c052d892c0 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -137,6 +137,8 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev) | |||
137 | 137 | ||
138 | void rv515_vga_render_disable(struct radeon_device *rdev) | 138 | void rv515_vga_render_disable(struct radeon_device *rdev) |
139 | { | 139 | { |
140 | WREG32(R_000330_D1VGA_CONTROL, 0); | ||
141 | WREG32(R_000338_D2VGA_CONTROL, 0); | ||
140 | WREG32(R_000300_VGA_RENDER_CONTROL, | 142 | WREG32(R_000300_VGA_RENDER_CONTROL, |
141 | RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); | 143 | RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); |
142 | } | 144 | } |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 595ac638039d..ae074fdf804d 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -529,11 +529,11 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
529 | if (rdev->family == CHIP_RV770) | 529 | if (rdev->family == CHIP_RV770) |
530 | gb_tiling_config |= BANK_TILING(1); | 530 | gb_tiling_config |= BANK_TILING(1); |
531 | else | 531 | else |
532 | gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_SHIFT) >> NOOFBANK_MASK); | 532 | gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); |
533 | 533 | ||
534 | gb_tiling_config |= GROUP_SIZE(0); | 534 | gb_tiling_config |= GROUP_SIZE(0); |
535 | 535 | ||
536 | if (((mc_arb_ramcfg & NOOFROWS_MASK) & NOOFROWS_SHIFT) > 3) { | 536 | if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) { |
537 | gb_tiling_config |= ROW_TILING(3); | 537 | gb_tiling_config |= ROW_TILING(3); |
538 | gb_tiling_config |= SAMPLE_SPLIT(3); | 538 | gb_tiling_config |= SAMPLE_SPLIT(3); |
539 | } else { | 539 | } else { |
@@ -579,14 +579,14 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
579 | 579 | ||
580 | /* set HW defaults for 3D engine */ | 580 | /* set HW defaults for 3D engine */ |
581 | WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | | 581 | WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | |
582 | ROQ_IB2_START(0x2b))); | 582 | ROQ_IB2_START(0x2b))); |
583 | 583 | ||
584 | WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30)); | 584 | WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30)); |
585 | 585 | ||
586 | WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | | 586 | WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | |
587 | SYNC_GRADIENT | | 587 | SYNC_GRADIENT | |
588 | SYNC_WALKER | | 588 | SYNC_WALKER | |
589 | SYNC_ALIGNER)); | 589 | SYNC_ALIGNER)); |
590 | 590 | ||
591 | sx_debug_1 = RREG32(SX_DEBUG_1); | 591 | sx_debug_1 = RREG32(SX_DEBUG_1); |
592 | sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; | 592 | sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; |
@@ -598,9 +598,9 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
598 | WREG32(SMX_DC_CTL0, smx_dc_ctl0); | 598 | WREG32(SMX_DC_CTL0, smx_dc_ctl0); |
599 | 599 | ||
600 | WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) | | 600 | WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) | |
601 | GS_FLUSH_CTL(4) | | 601 | GS_FLUSH_CTL(4) | |
602 | ACK_FLUSH_CTL(3) | | 602 | ACK_FLUSH_CTL(3) | |
603 | SYNC_FLUSH_CTL)); | 603 | SYNC_FLUSH_CTL)); |
604 | 604 | ||
605 | if (rdev->family == CHIP_RV770) | 605 | if (rdev->family == CHIP_RV770) |
606 | WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f)); | 606 | WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f)); |
@@ -611,12 +611,12 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
611 | } | 611 | } |
612 | 612 | ||
613 | WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) | | 613 | WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) | |
614 | POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) | | 614 | POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) | |
615 | SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1))); | 615 | SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1))); |
616 | 616 | ||
617 | WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) | | 617 | WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) | |
618 | SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) | | 618 | SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) | |
619 | SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize))); | 619 | SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize))); |
620 | 620 | ||
621 | WREG32(PA_SC_MULTI_CHIP_CNTL, 0); | 621 | WREG32(PA_SC_MULTI_CHIP_CNTL, 0); |
622 | 622 | ||
@@ -774,14 +774,36 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
774 | { | 774 | { |
775 | fixed20_12 a; | 775 | fixed20_12 a; |
776 | u32 tmp; | 776 | u32 tmp; |
777 | int chansize, numchan; | ||
777 | int r; | 778 | int r; |
778 | 779 | ||
779 | /* Get VRAM informations */ | 780 | /* Get VRAM informations */ |
780 | /* FIXME: Don't know how to determine vram width, need to check | ||
781 | * vram_width usage | ||
782 | */ | ||
783 | rdev->mc.vram_width = 128; | ||
784 | rdev->mc.vram_is_ddr = true; | 781 | rdev->mc.vram_is_ddr = true; |
782 | tmp = RREG32(MC_ARB_RAMCFG); | ||
783 | if (tmp & CHANSIZE_OVERRIDE) { | ||
784 | chansize = 16; | ||
785 | } else if (tmp & CHANSIZE_MASK) { | ||
786 | chansize = 64; | ||
787 | } else { | ||
788 | chansize = 32; | ||
789 | } | ||
790 | tmp = RREG32(MC_SHARED_CHMAP); | ||
791 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { | ||
792 | case 0: | ||
793 | default: | ||
794 | numchan = 1; | ||
795 | break; | ||
796 | case 1: | ||
797 | numchan = 2; | ||
798 | break; | ||
799 | case 2: | ||
800 | numchan = 4; | ||
801 | break; | ||
802 | case 3: | ||
803 | numchan = 8; | ||
804 | break; | ||
805 | } | ||
806 | rdev->mc.vram_width = numchan * chansize; | ||
785 | /* Could aper size report 0 ? */ | 807 | /* Could aper size report 0 ? */ |
786 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 808 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
787 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 809 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 4b9c3d6396ff..a1367ab6f261 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
@@ -129,6 +129,10 @@ | |||
129 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 | 129 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 |
130 | #define HDP_TILING_CONFIG 0x2F3C | 130 | #define HDP_TILING_CONFIG 0x2F3C |
131 | 131 | ||
132 | #define MC_SHARED_CHMAP 0x2004 | ||
133 | #define NOOFCHAN_SHIFT 12 | ||
134 | #define NOOFCHAN_MASK 0x00003000 | ||
135 | |||
132 | #define MC_ARB_RAMCFG 0x2760 | 136 | #define MC_ARB_RAMCFG 0x2760 |
133 | #define NOOFBANK_SHIFT 0 | 137 | #define NOOFBANK_SHIFT 0 |
134 | #define NOOFBANK_MASK 0x00000003 | 138 | #define NOOFBANK_MASK 0x00000003 |
@@ -142,6 +146,7 @@ | |||
142 | #define CHANSIZE_MASK 0x00000100 | 146 | #define CHANSIZE_MASK 0x00000100 |
143 | #define BURSTLENGTH_SHIFT 9 | 147 | #define BURSTLENGTH_SHIFT 9 |
144 | #define BURSTLENGTH_MASK 0x00000200 | 148 | #define BURSTLENGTH_MASK 0x00000200 |
149 | #define CHANSIZE_OVERRIDE (1 << 11) | ||
145 | #define MC_VM_AGP_TOP 0x2028 | 150 | #define MC_VM_AGP_TOP 0x2028 |
146 | #define MC_VM_AGP_BOT 0x202C | 151 | #define MC_VM_AGP_BOT 0x202C |
147 | #define MC_VM_AGP_BASE 0x2030 | 152 | #define MC_VM_AGP_BASE 0x2030 |
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index a55ee1a56c16..7bcb89f39ce8 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
@@ -279,6 +279,7 @@ int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement) | |||
279 | 279 | ||
280 | return ttm_tt_set_caching(ttm, state); | 280 | return ttm_tt_set_caching(ttm, state); |
281 | } | 281 | } |
282 | EXPORT_SYMBOL(ttm_tt_set_placement_caching); | ||
282 | 283 | ||
283 | static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm) | 284 | static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm) |
284 | { | 285 | { |
diff --git a/include/drm/drm.h b/include/drm/drm.h index 7cb50bdde46d..fa6d9155873d 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h | |||
@@ -454,6 +454,7 @@ struct drm_irq_busid { | |||
454 | enum drm_vblank_seq_type { | 454 | enum drm_vblank_seq_type { |
455 | _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ | 455 | _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ |
456 | _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ | 456 | _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ |
457 | _DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */ | ||
457 | _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ | 458 | _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ |
458 | _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ | 459 | _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ |
459 | _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ | 460 | _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ |
@@ -461,8 +462,8 @@ enum drm_vblank_seq_type { | |||
461 | }; | 462 | }; |
462 | 463 | ||
463 | #define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) | 464 | #define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) |
464 | #define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \ | 465 | #define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \ |
465 | _DRM_VBLANK_NEXTONMISS) | 466 | _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS) |
466 | 467 | ||
467 | struct drm_wait_vblank_request { | 468 | struct drm_wait_vblank_request { |
468 | enum drm_vblank_seq_type type; | 469 | enum drm_vblank_seq_type type; |
@@ -698,6 +699,34 @@ struct drm_gem_open { | |||
698 | #define DRM_COMMAND_BASE 0x40 | 699 | #define DRM_COMMAND_BASE 0x40 |
699 | #define DRM_COMMAND_END 0xA0 | 700 | #define DRM_COMMAND_END 0xA0 |
700 | 701 | ||
702 | /** | ||
703 | * Header for events written back to userspace on the drm fd. The | ||
704 | * type defines the type of event, the length specifies the total | ||
705 | * length of the event (including the header), and user_data is | ||
706 | * typically a 64 bit value passed with the ioctl that triggered the | ||
707 | * event. A read on the drm fd will always only return complete | ||
708 | * events, that is, if for example the read buffer is 100 bytes, and | ||
709 | * there are two 64 byte events pending, only one will be returned. | ||
710 | * | ||
711 | * Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and | ||
712 | * up are chipset specific. | ||
713 | */ | ||
714 | struct drm_event { | ||
715 | __u32 type; | ||
716 | __u32 length; | ||
717 | }; | ||
718 | |||
719 | #define DRM_EVENT_VBLANK 0x01 | ||
720 | |||
721 | struct drm_event_vblank { | ||
722 | struct drm_event base; | ||
723 | __u64 user_data; | ||
724 | __u32 tv_sec; | ||
725 | __u32 tv_usec; | ||
726 | __u32 sequence; | ||
727 | __u32 reserved; | ||
728 | }; | ||
729 | |||
701 | /* typedef area */ | 730 | /* typedef area */ |
702 | #ifndef __KERNEL__ | 731 | #ifndef __KERNEL__ |
703 | typedef struct drm_clip_rect drm_clip_rect_t; | 732 | typedef struct drm_clip_rect drm_clip_rect_t; |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c8e64bbadbcf..b0b36838ab11 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -426,6 +426,14 @@ struct drm_buf_entry { | |||
426 | struct drm_freelist freelist; | 426 | struct drm_freelist freelist; |
427 | }; | 427 | }; |
428 | 428 | ||
429 | /* Event queued up for userspace to read */ | ||
430 | struct drm_pending_event { | ||
431 | struct drm_event *event; | ||
432 | struct list_head link; | ||
433 | struct drm_file *file_priv; | ||
434 | void (*destroy)(struct drm_pending_event *event); | ||
435 | }; | ||
436 | |||
429 | /** File private data */ | 437 | /** File private data */ |
430 | struct drm_file { | 438 | struct drm_file { |
431 | int authenticated; | 439 | int authenticated; |
@@ -449,6 +457,10 @@ struct drm_file { | |||
449 | struct drm_master *master; /* master this node is currently associated with | 457 | struct drm_master *master; /* master this node is currently associated with |
450 | N.B. not always minor->master */ | 458 | N.B. not always minor->master */ |
451 | struct list_head fbs; | 459 | struct list_head fbs; |
460 | |||
461 | wait_queue_head_t event_wait; | ||
462 | struct list_head event_list; | ||
463 | int event_space; | ||
452 | }; | 464 | }; |
453 | 465 | ||
454 | /** Wait queue */ | 466 | /** Wait queue */ |
@@ -900,6 +912,12 @@ struct drm_minor { | |||
900 | struct drm_mode_group mode_group; | 912 | struct drm_mode_group mode_group; |
901 | }; | 913 | }; |
902 | 914 | ||
915 | struct drm_pending_vblank_event { | ||
916 | struct drm_pending_event base; | ||
917 | int pipe; | ||
918 | struct drm_event_vblank event; | ||
919 | }; | ||
920 | |||
903 | /** | 921 | /** |
904 | * DRM device structure. This structure represent a complete card that | 922 | * DRM device structure. This structure represent a complete card that |
905 | * may contain multiple heads. | 923 | * may contain multiple heads. |
@@ -999,6 +1017,12 @@ struct drm_device { | |||
999 | 1017 | ||
1000 | u32 max_vblank_count; /**< size of vblank counter register */ | 1018 | u32 max_vblank_count; /**< size of vblank counter register */ |
1001 | 1019 | ||
1020 | /** | ||
1021 | * List of events | ||
1022 | */ | ||
1023 | struct list_head vblank_event_list; | ||
1024 | spinlock_t event_lock; | ||
1025 | |||
1002 | /*@} */ | 1026 | /*@} */ |
1003 | cycles_t ctx_start; | 1027 | cycles_t ctx_start; |
1004 | cycles_t lck_start; | 1028 | cycles_t lck_start; |
@@ -1135,6 +1159,8 @@ extern int drm_lastclose(struct drm_device *dev); | |||
1135 | extern int drm_open(struct inode *inode, struct file *filp); | 1159 | extern int drm_open(struct inode *inode, struct file *filp); |
1136 | extern int drm_stub_open(struct inode *inode, struct file *filp); | 1160 | extern int drm_stub_open(struct inode *inode, struct file *filp); |
1137 | extern int drm_fasync(int fd, struct file *filp, int on); | 1161 | extern int drm_fasync(int fd, struct file *filp, int on); |
1162 | extern ssize_t drm_read(struct file *filp, char __user *buffer, | ||
1163 | size_t count, loff_t *offset); | ||
1138 | extern int drm_release(struct inode *inode, struct file *filp); | 1164 | extern int drm_release(struct inode *inode, struct file *filp); |
1139 | 1165 | ||
1140 | /* Mapping support (drm_vm.h) */ | 1166 | /* Mapping support (drm_vm.h) */ |