diff options
Diffstat (limited to 'drivers/gpu')
103 files changed, 4577 insertions, 3607 deletions
diff --git a/drivers/gpu/drm/drm_buffer.c b/drivers/gpu/drm/drm_buffer.c index 55d03ed05000..529a0dbe9fc6 100644 --- a/drivers/gpu/drm/drm_buffer.c +++ b/drivers/gpu/drm/drm_buffer.c | |||
| @@ -98,8 +98,8 @@ EXPORT_SYMBOL(drm_buffer_alloc); | |||
| 98 | * user_data: A pointer the data that is copied to the buffer. | 98 | * user_data: A pointer the data that is copied to the buffer. |
| 99 | * size: The Number of bytes to copy. | 99 | * size: The Number of bytes to copy. |
| 100 | */ | 100 | */ |
| 101 | extern int drm_buffer_copy_from_user(struct drm_buffer *buf, | 101 | int drm_buffer_copy_from_user(struct drm_buffer *buf, |
| 102 | void __user *user_data, int size) | 102 | void __user *user_data, int size) |
| 103 | { | 103 | { |
| 104 | int nr_pages = size / PAGE_SIZE + 1; | 104 | int nr_pages = size / PAGE_SIZE + 1; |
| 105 | int idx; | 105 | int idx; |
| @@ -163,7 +163,7 @@ void *drm_buffer_read_object(struct drm_buffer *buf, | |||
| 163 | { | 163 | { |
| 164 | int idx = drm_buffer_index(buf); | 164 | int idx = drm_buffer_index(buf); |
| 165 | int page = drm_buffer_page(buf); | 165 | int page = drm_buffer_page(buf); |
| 166 | void *obj = 0; | 166 | void *obj = NULL; |
| 167 | 167 | ||
| 168 | if (idx + objsize <= PAGE_SIZE) { | 168 | if (idx + objsize <= PAGE_SIZE) { |
| 169 | obj = &buf->data[page][idx]; | 169 | obj = &buf->data[page][idx]; |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 7e31d4348340..dcbeb98f195a 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
| @@ -34,6 +34,9 @@ | |||
| 34 | #include "drm_crtc_helper.h" | 34 | #include "drm_crtc_helper.h" |
| 35 | #include "drm_fb_helper.h" | 35 | #include "drm_fb_helper.h" |
| 36 | 36 | ||
| 37 | static bool drm_kms_helper_poll = true; | ||
| 38 | module_param_named(poll, drm_kms_helper_poll, bool, 0600); | ||
| 39 | |||
| 37 | static void drm_mode_validate_flag(struct drm_connector *connector, | 40 | static void drm_mode_validate_flag(struct drm_connector *connector, |
| 38 | int flags) | 41 | int flags) |
| 39 | { | 42 | { |
| @@ -99,8 +102,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
| 99 | connector->status = connector_status_disconnected; | 102 | connector->status = connector_status_disconnected; |
| 100 | if (connector->funcs->force) | 103 | if (connector->funcs->force) |
| 101 | connector->funcs->force(connector); | 104 | connector->funcs->force(connector); |
| 102 | } else | 105 | } else { |
| 103 | connector->status = connector->funcs->detect(connector); | 106 | connector->status = connector->funcs->detect(connector, true); |
| 107 | drm_kms_helper_poll_enable(dev); | ||
| 108 | } | ||
| 104 | 109 | ||
| 105 | if (connector->status == connector_status_disconnected) { | 110 | if (connector->status == connector_status_disconnected) { |
| 106 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", | 111 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", |
| @@ -110,11 +115,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
| 110 | } | 115 | } |
| 111 | 116 | ||
| 112 | count = (*connector_funcs->get_modes)(connector); | 117 | count = (*connector_funcs->get_modes)(connector); |
| 113 | if (!count) { | 118 | if (count == 0 && connector->status == connector_status_connected) |
| 114 | count = drm_add_modes_noedid(connector, 1024, 768); | 119 | count = drm_add_modes_noedid(connector, 1024, 768); |
| 115 | if (!count) | 120 | if (count == 0) |
| 116 | return 0; | 121 | goto prune; |
| 117 | } | ||
| 118 | 122 | ||
| 119 | drm_mode_connector_list_update(connector); | 123 | drm_mode_connector_list_update(connector); |
| 120 | 124 | ||
| @@ -633,13 +637,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 633 | mode_changed = true; | 637 | mode_changed = true; |
| 634 | 638 | ||
| 635 | if (mode_changed) { | 639 | if (mode_changed) { |
| 636 | old_fb = set->crtc->fb; | ||
| 637 | set->crtc->fb = set->fb; | ||
| 638 | set->crtc->enabled = (set->mode != NULL); | 640 | set->crtc->enabled = (set->mode != NULL); |
| 639 | if (set->mode != NULL) { | 641 | if (set->mode != NULL) { |
| 640 | DRM_DEBUG_KMS("attempting to set mode from" | 642 | DRM_DEBUG_KMS("attempting to set mode from" |
| 641 | " userspace\n"); | 643 | " userspace\n"); |
| 642 | drm_mode_debug_printmodeline(set->mode); | 644 | drm_mode_debug_printmodeline(set->mode); |
| 645 | old_fb = set->crtc->fb; | ||
| 646 | set->crtc->fb = set->fb; | ||
| 643 | if (!drm_crtc_helper_set_mode(set->crtc, set->mode, | 647 | if (!drm_crtc_helper_set_mode(set->crtc, set->mode, |
| 644 | set->x, set->y, | 648 | set->x, set->y, |
| 645 | old_fb)) { | 649 | old_fb)) { |
| @@ -840,6 +844,9 @@ static void output_poll_execute(struct work_struct *work) | |||
| 840 | enum drm_connector_status old_status, status; | 844 | enum drm_connector_status old_status, status; |
| 841 | bool repoll = false, changed = false; | 845 | bool repoll = false, changed = false; |
| 842 | 846 | ||
| 847 | if (!drm_kms_helper_poll) | ||
| 848 | return; | ||
| 849 | |||
| 843 | mutex_lock(&dev->mode_config.mutex); | 850 | mutex_lock(&dev->mode_config.mutex); |
| 844 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 851 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 845 | 852 | ||
| @@ -859,7 +866,7 @@ static void output_poll_execute(struct work_struct *work) | |||
| 859 | !(connector->polled & DRM_CONNECTOR_POLL_HPD)) | 866 | !(connector->polled & DRM_CONNECTOR_POLL_HPD)) |
| 860 | continue; | 867 | continue; |
| 861 | 868 | ||
| 862 | status = connector->funcs->detect(connector); | 869 | status = connector->funcs->detect(connector, false); |
| 863 | if (old_status != status) | 870 | if (old_status != status) |
| 864 | changed = true; | 871 | changed = true; |
| 865 | } | 872 | } |
| @@ -890,6 +897,9 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) | |||
| 890 | bool poll = false; | 897 | bool poll = false; |
| 891 | struct drm_connector *connector; | 898 | struct drm_connector *connector; |
| 892 | 899 | ||
| 900 | if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) | ||
| 901 | return; | ||
| 902 | |||
| 893 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 903 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 894 | if (connector->polled) | 904 | if (connector->polled) |
| 895 | poll = true; | 905 | poll = true; |
| @@ -919,8 +929,10 @@ void drm_helper_hpd_irq_event(struct drm_device *dev) | |||
| 919 | { | 929 | { |
| 920 | if (!dev->mode_config.poll_enabled) | 930 | if (!dev->mode_config.poll_enabled) |
| 921 | return; | 931 | return; |
| 932 | |||
| 922 | /* kill timer and schedule immediate execution, this doesn't block */ | 933 | /* kill timer and schedule immediate execution, this doesn't block */ |
| 923 | cancel_delayed_work(&dev->mode_config.output_poll_work); | 934 | cancel_delayed_work(&dev->mode_config.output_poll_work); |
| 924 | queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0); | 935 | if (drm_kms_helper_poll) |
| 936 | queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0); | ||
| 925 | } | 937 | } |
| 926 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); | 938 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 90288ec7c284..84da748555bc 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
| @@ -55,6 +55,9 @@ | |||
| 55 | static int drm_version(struct drm_device *dev, void *data, | 55 | static int drm_version(struct drm_device *dev, void *data, |
| 56 | struct drm_file *file_priv); | 56 | struct drm_file *file_priv); |
| 57 | 57 | ||
| 58 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ | ||
| 59 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0} | ||
| 60 | |||
| 58 | /** Ioctl table */ | 61 | /** Ioctl table */ |
| 59 | static struct drm_ioctl_desc drm_ioctls[] = { | 62 | static struct drm_ioctl_desc drm_ioctls[] = { |
| 60 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), | 63 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), |
| @@ -421,6 +424,7 @@ long drm_ioctl(struct file *filp, | |||
| 421 | int retcode = -EINVAL; | 424 | int retcode = -EINVAL; |
| 422 | char stack_kdata[128]; | 425 | char stack_kdata[128]; |
| 423 | char *kdata = NULL; | 426 | char *kdata = NULL; |
| 427 | unsigned int usize, asize; | ||
| 424 | 428 | ||
| 425 | dev = file_priv->minor->dev; | 429 | dev = file_priv->minor->dev; |
| 426 | atomic_inc(&dev->ioctl_count); | 430 | atomic_inc(&dev->ioctl_count); |
| @@ -436,11 +440,18 @@ long drm_ioctl(struct file *filp, | |||
| 436 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) | 440 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) |
| 437 | goto err_i1; | 441 | goto err_i1; |
| 438 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && | 442 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && |
| 439 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) | 443 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { |
| 444 | u32 drv_size; | ||
| 440 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; | 445 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; |
| 446 | drv_size = _IOC_SIZE(ioctl->cmd_drv); | ||
| 447 | usize = asize = _IOC_SIZE(cmd); | ||
| 448 | if (drv_size > asize) | ||
| 449 | asize = drv_size; | ||
| 450 | } | ||
| 441 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { | 451 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { |
| 442 | ioctl = &drm_ioctls[nr]; | 452 | ioctl = &drm_ioctls[nr]; |
| 443 | cmd = ioctl->cmd; | 453 | cmd = ioctl->cmd; |
| 454 | usize = asize = _IOC_SIZE(cmd); | ||
| 444 | } else | 455 | } else |
| 445 | goto err_i1; | 456 | goto err_i1; |
| 446 | 457 | ||
| @@ -460,10 +471,10 @@ long drm_ioctl(struct file *filp, | |||
| 460 | retcode = -EACCES; | 471 | retcode = -EACCES; |
| 461 | } else { | 472 | } else { |
| 462 | if (cmd & (IOC_IN | IOC_OUT)) { | 473 | if (cmd & (IOC_IN | IOC_OUT)) { |
| 463 | if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) { | 474 | if (asize <= sizeof(stack_kdata)) { |
| 464 | kdata = stack_kdata; | 475 | kdata = stack_kdata; |
| 465 | } else { | 476 | } else { |
| 466 | kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); | 477 | kdata = kmalloc(asize, GFP_KERNEL); |
| 467 | if (!kdata) { | 478 | if (!kdata) { |
| 468 | retcode = -ENOMEM; | 479 | retcode = -ENOMEM; |
| 469 | goto err_i1; | 480 | goto err_i1; |
| @@ -473,11 +484,13 @@ long drm_ioctl(struct file *filp, | |||
| 473 | 484 | ||
| 474 | if (cmd & IOC_IN) { | 485 | if (cmd & IOC_IN) { |
| 475 | if (copy_from_user(kdata, (void __user *)arg, | 486 | if (copy_from_user(kdata, (void __user *)arg, |
| 476 | _IOC_SIZE(cmd)) != 0) { | 487 | usize) != 0) { |
| 477 | retcode = -EFAULT; | 488 | retcode = -EFAULT; |
| 478 | goto err_i1; | 489 | goto err_i1; |
| 479 | } | 490 | } |
| 480 | } | 491 | } else |
| 492 | memset(kdata, 0, usize); | ||
| 493 | |||
| 481 | if (ioctl->flags & DRM_UNLOCKED) | 494 | if (ioctl->flags & DRM_UNLOCKED) |
| 482 | retcode = func(dev, kdata, file_priv); | 495 | retcode = func(dev, kdata, file_priv); |
| 483 | else { | 496 | else { |
| @@ -488,7 +501,7 @@ long drm_ioctl(struct file *filp, | |||
| 488 | 501 | ||
| 489 | if (cmd & IOC_OUT) { | 502 | if (cmd & IOC_OUT) { |
| 490 | if (copy_to_user((void __user *)arg, kdata, | 503 | if (copy_to_user((void __user *)arg, kdata, |
| 491 | _IOC_SIZE(cmd)) != 0) | 504 | usize) != 0) |
| 492 | retcode = -EFAULT; | 505 | retcode = -EFAULT; |
| 493 | } | 506 | } |
| 494 | } | 507 | } |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index de82e201d682..6a5e403f9aa1 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
| @@ -94,10 +94,11 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_conn | |||
| 94 | int i; | 94 | int i; |
| 95 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; | 95 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; |
| 96 | struct drm_fb_helper_cmdline_mode *cmdline_mode; | 96 | struct drm_fb_helper_cmdline_mode *cmdline_mode; |
| 97 | struct drm_connector *connector = fb_helper_conn->connector; | 97 | struct drm_connector *connector; |
| 98 | 98 | ||
| 99 | if (!fb_helper_conn) | 99 | if (!fb_helper_conn) |
| 100 | return false; | 100 | return false; |
| 101 | connector = fb_helper_conn->connector; | ||
| 101 | 102 | ||
| 102 | cmdline_mode = &fb_helper_conn->cmdline_mode; | 103 | cmdline_mode = &fb_helper_conn->cmdline_mode; |
| 103 | if (!mode_option) | 104 | if (!mode_option) |
| @@ -369,7 +370,7 @@ static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) | |||
| 369 | } | 370 | } |
| 370 | static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); | 371 | static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); |
| 371 | 372 | ||
| 372 | static void drm_fb_helper_sysrq(int dummy1, struct tty_struct *dummy3) | 373 | static void drm_fb_helper_sysrq(int dummy1) |
| 373 | { | 374 | { |
| 374 | schedule_work(&drm_fb_helper_restore_work); | 375 | schedule_work(&drm_fb_helper_restore_work); |
| 375 | } | 376 | } |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 3a652a65546f..b744dad5c237 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | 41 | ||
| 42 | /* from BKL pushdown: note that nothing else serializes idr_find() */ | 42 | /* from BKL pushdown: note that nothing else serializes idr_find() */ |
| 43 | DEFINE_MUTEX(drm_global_mutex); | 43 | DEFINE_MUTEX(drm_global_mutex); |
| 44 | EXPORT_SYMBOL(drm_global_mutex); | ||
| 44 | 45 | ||
| 45 | static int drm_open_helper(struct inode *inode, struct file *filp, | 46 | static int drm_open_helper(struct inode *inode, struct file *filp, |
| 46 | struct drm_device * dev); | 47 | struct drm_device * dev); |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index bf92d07510df..5663d2719063 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
| @@ -148,7 +148,7 @@ int drm_gem_object_init(struct drm_device *dev, | |||
| 148 | return -ENOMEM; | 148 | return -ENOMEM; |
| 149 | 149 | ||
| 150 | kref_init(&obj->refcount); | 150 | kref_init(&obj->refcount); |
| 151 | kref_init(&obj->handlecount); | 151 | atomic_set(&obj->handle_count, 0); |
| 152 | obj->size = size; | 152 | obj->size = size; |
| 153 | 153 | ||
| 154 | atomic_inc(&dev->object_count); | 154 | atomic_inc(&dev->object_count); |
| @@ -462,28 +462,6 @@ drm_gem_object_free(struct kref *kref) | |||
| 462 | } | 462 | } |
| 463 | EXPORT_SYMBOL(drm_gem_object_free); | 463 | EXPORT_SYMBOL(drm_gem_object_free); |
| 464 | 464 | ||
| 465 | /** | ||
| 466 | * Called after the last reference to the object has been lost. | ||
| 467 | * Must be called without holding struct_mutex | ||
| 468 | * | ||
| 469 | * Frees the object | ||
| 470 | */ | ||
| 471 | void | ||
| 472 | drm_gem_object_free_unlocked(struct kref *kref) | ||
| 473 | { | ||
| 474 | struct drm_gem_object *obj = (struct drm_gem_object *) kref; | ||
| 475 | struct drm_device *dev = obj->dev; | ||
| 476 | |||
| 477 | if (dev->driver->gem_free_object_unlocked != NULL) | ||
| 478 | dev->driver->gem_free_object_unlocked(obj); | ||
| 479 | else if (dev->driver->gem_free_object != NULL) { | ||
| 480 | mutex_lock(&dev->struct_mutex); | ||
| 481 | dev->driver->gem_free_object(obj); | ||
| 482 | mutex_unlock(&dev->struct_mutex); | ||
| 483 | } | ||
| 484 | } | ||
| 485 | EXPORT_SYMBOL(drm_gem_object_free_unlocked); | ||
| 486 | |||
| 487 | static void drm_gem_object_ref_bug(struct kref *list_kref) | 465 | static void drm_gem_object_ref_bug(struct kref *list_kref) |
| 488 | { | 466 | { |
| 489 | BUG(); | 467 | BUG(); |
| @@ -496,12 +474,8 @@ static void drm_gem_object_ref_bug(struct kref *list_kref) | |||
| 496 | * called before drm_gem_object_free or we'll be touching | 474 | * called before drm_gem_object_free or we'll be touching |
| 497 | * freed memory | 475 | * freed memory |
| 498 | */ | 476 | */ |
| 499 | void | 477 | void drm_gem_object_handle_free(struct drm_gem_object *obj) |
| 500 | drm_gem_object_handle_free(struct kref *kref) | ||
| 501 | { | 478 | { |
| 502 | struct drm_gem_object *obj = container_of(kref, | ||
| 503 | struct drm_gem_object, | ||
| 504 | handlecount); | ||
| 505 | struct drm_device *dev = obj->dev; | 479 | struct drm_device *dev = obj->dev; |
| 506 | 480 | ||
| 507 | /* Remove any name for this object */ | 481 | /* Remove any name for this object */ |
| @@ -528,6 +502,10 @@ void drm_gem_vm_open(struct vm_area_struct *vma) | |||
| 528 | struct drm_gem_object *obj = vma->vm_private_data; | 502 | struct drm_gem_object *obj = vma->vm_private_data; |
| 529 | 503 | ||
| 530 | drm_gem_object_reference(obj); | 504 | drm_gem_object_reference(obj); |
| 505 | |||
| 506 | mutex_lock(&obj->dev->struct_mutex); | ||
| 507 | drm_vm_open_locked(vma); | ||
| 508 | mutex_unlock(&obj->dev->struct_mutex); | ||
| 531 | } | 509 | } |
| 532 | EXPORT_SYMBOL(drm_gem_vm_open); | 510 | EXPORT_SYMBOL(drm_gem_vm_open); |
| 533 | 511 | ||
| @@ -535,7 +513,10 @@ void drm_gem_vm_close(struct vm_area_struct *vma) | |||
| 535 | { | 513 | { |
| 536 | struct drm_gem_object *obj = vma->vm_private_data; | 514 | struct drm_gem_object *obj = vma->vm_private_data; |
| 537 | 515 | ||
| 538 | drm_gem_object_unreference_unlocked(obj); | 516 | mutex_lock(&obj->dev->struct_mutex); |
| 517 | drm_vm_close_locked(vma); | ||
| 518 | drm_gem_object_unreference(obj); | ||
| 519 | mutex_unlock(&obj->dev->struct_mutex); | ||
| 539 | } | 520 | } |
| 540 | EXPORT_SYMBOL(drm_gem_vm_close); | 521 | EXPORT_SYMBOL(drm_gem_vm_close); |
| 541 | 522 | ||
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 2ef2c7827243..974e970ce3f8 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
| @@ -255,7 +255,7 @@ int drm_gem_one_name_info(int id, void *ptr, void *data) | |||
| 255 | 255 | ||
| 256 | seq_printf(m, "%6d %8zd %7d %8d\n", | 256 | seq_printf(m, "%6d %8zd %7d %8d\n", |
| 257 | obj->name, obj->size, | 257 | obj->name, obj->size, |
| 258 | atomic_read(&obj->handlecount.refcount), | 258 | atomic_read(&obj->handle_count), |
| 259 | atomic_read(&obj->refcount.refcount)); | 259 | atomic_read(&obj->refcount.refcount)); |
| 260 | return 0; | 260 | return 0; |
| 261 | } | 261 | } |
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index e2f70a516c34..9bf93bc9a32c 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
| @@ -92,7 +92,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | /* Contention */ | 94 | /* Contention */ |
| 95 | mutex_unlock(&drm_global_mutex); | ||
| 95 | schedule(); | 96 | schedule(); |
| 97 | mutex_lock(&drm_global_mutex); | ||
| 96 | if (signal_pending(current)) { | 98 | if (signal_pending(current)) { |
| 97 | ret = -EINTR; | 99 | ret = -EINTR; |
| 98 | break; | 100 | break; |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index da99edc50888..a6bfc302ed90 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
| @@ -285,21 +285,21 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
| 285 | 285 | ||
| 286 | EXPORT_SYMBOL(drm_mm_put_block); | 286 | EXPORT_SYMBOL(drm_mm_put_block); |
| 287 | 287 | ||
| 288 | static int check_free_mm_node(struct drm_mm_node *entry, unsigned long size, | 288 | static int check_free_hole(unsigned long start, unsigned long end, |
| 289 | unsigned alignment) | 289 | unsigned long size, unsigned alignment) |
| 290 | { | 290 | { |
| 291 | unsigned wasted = 0; | 291 | unsigned wasted = 0; |
| 292 | 292 | ||
| 293 | if (entry->size < size) | 293 | if (end - start < size) |
| 294 | return 0; | 294 | return 0; |
| 295 | 295 | ||
| 296 | if (alignment) { | 296 | if (alignment) { |
| 297 | register unsigned tmp = entry->start % alignment; | 297 | unsigned tmp = start % alignment; |
| 298 | if (tmp) | 298 | if (tmp) |
| 299 | wasted = alignment - tmp; | 299 | wasted = alignment - tmp; |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | if (entry->size >= size + wasted) { | 302 | if (end >= start + size + wasted) { |
| 303 | return 1; | 303 | return 1; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| @@ -320,7 +320,8 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, | |||
| 320 | best_size = ~0UL; | 320 | best_size = ~0UL; |
| 321 | 321 | ||
| 322 | list_for_each_entry(entry, &mm->free_stack, free_stack) { | 322 | list_for_each_entry(entry, &mm->free_stack, free_stack) { |
| 323 | if (!check_free_mm_node(entry, size, alignment)) | 323 | if (!check_free_hole(entry->start, entry->start + entry->size, |
| 324 | size, alignment)) | ||
| 324 | continue; | 325 | continue; |
| 325 | 326 | ||
| 326 | if (!best_match) | 327 | if (!best_match) |
| @@ -353,10 +354,12 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | |||
| 353 | best_size = ~0UL; | 354 | best_size = ~0UL; |
| 354 | 355 | ||
| 355 | list_for_each_entry(entry, &mm->free_stack, free_stack) { | 356 | list_for_each_entry(entry, &mm->free_stack, free_stack) { |
| 356 | if (entry->start > end || (entry->start+entry->size) < start) | 357 | unsigned long adj_start = entry->start < start ? |
| 357 | continue; | 358 | start : entry->start; |
| 359 | unsigned long adj_end = entry->start + entry->size > end ? | ||
| 360 | end : entry->start + entry->size; | ||
| 358 | 361 | ||
| 359 | if (!check_free_mm_node(entry, size, alignment)) | 362 | if (!check_free_hole(adj_start, adj_end, size, alignment)) |
| 360 | continue; | 363 | continue; |
| 361 | 364 | ||
| 362 | if (!best_match) | 365 | if (!best_match) |
| @@ -449,7 +452,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) | |||
| 449 | node->free_stack.prev = prev_free; | 452 | node->free_stack.prev = prev_free; |
| 450 | node->free_stack.next = next_free; | 453 | node->free_stack.next = next_free; |
| 451 | 454 | ||
| 452 | if (check_free_mm_node(node, mm->scan_size, mm->scan_alignment)) { | 455 | if (check_free_hole(node->start, node->start + node->size, |
| 456 | mm->scan_size, mm->scan_alignment)) { | ||
| 453 | mm->scan_hit_start = node->start; | 457 | mm->scan_hit_start = node->start; |
| 454 | mm->scan_hit_size = node->size; | 458 | mm->scan_hit_size = node->size; |
| 455 | 459 | ||
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index f1f473ea97d3..949326d2a8e5 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
| @@ -251,7 +251,10 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, | |||
| 251 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; | 251 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; |
| 252 | /* Fill in HSync values */ | 252 | /* Fill in HSync values */ |
| 253 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; | 253 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; |
| 254 | drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC; | 254 | drm_mode->hsync_start = drm_mode->hsync_end - CVT_RB_H_SYNC; |
| 255 | /* Fill in VSync values */ | ||
| 256 | drm_mode->vsync_start = drm_mode->vdisplay + CVT_RB_VFPORCH; | ||
| 257 | drm_mode->vsync_end = drm_mode->vsync_start + vsync; | ||
| 255 | } | 258 | } |
| 256 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ | 259 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ |
| 257 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; | 260 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; |
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index e20f78b542a7..f5bd9e590c80 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
| @@ -164,6 +164,8 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
| 164 | dev->hose = pdev->sysdata; | 164 | dev->hose = pdev->sysdata; |
| 165 | #endif | 165 | #endif |
| 166 | 166 | ||
| 167 | mutex_lock(&drm_global_mutex); | ||
| 168 | |||
| 167 | if ((ret = drm_fill_in_dev(dev, ent, driver))) { | 169 | if ((ret = drm_fill_in_dev(dev, ent, driver))) { |
| 168 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); | 170 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); |
| 169 | goto err_g2; | 171 | goto err_g2; |
| @@ -199,6 +201,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
| 199 | driver->name, driver->major, driver->minor, driver->patchlevel, | 201 | driver->name, driver->major, driver->minor, driver->patchlevel, |
| 200 | driver->date, pci_name(pdev), dev->primary->index); | 202 | driver->date, pci_name(pdev), dev->primary->index); |
| 201 | 203 | ||
| 204 | mutex_unlock(&drm_global_mutex); | ||
| 202 | return 0; | 205 | return 0; |
| 203 | 206 | ||
| 204 | err_g4: | 207 | err_g4: |
| @@ -210,6 +213,7 @@ err_g2: | |||
| 210 | pci_disable_device(pdev); | 213 | pci_disable_device(pdev); |
| 211 | err_g1: | 214 | err_g1: |
| 212 | kfree(dev); | 215 | kfree(dev); |
| 216 | mutex_unlock(&drm_global_mutex); | ||
| 213 | return ret; | 217 | return ret; |
| 214 | } | 218 | } |
| 215 | EXPORT_SYMBOL(drm_get_pci_dev); | 219 | EXPORT_SYMBOL(drm_get_pci_dev); |
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 460e9a3afa8d..92d1d0fb7b75 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c | |||
| @@ -53,6 +53,8 @@ int drm_get_platform_dev(struct platform_device *platdev, | |||
| 53 | dev->platformdev = platdev; | 53 | dev->platformdev = platdev; |
| 54 | dev->dev = &platdev->dev; | 54 | dev->dev = &platdev->dev; |
| 55 | 55 | ||
| 56 | mutex_lock(&drm_global_mutex); | ||
| 57 | |||
| 56 | ret = drm_fill_in_dev(dev, NULL, driver); | 58 | ret = drm_fill_in_dev(dev, NULL, driver); |
| 57 | 59 | ||
| 58 | if (ret) { | 60 | if (ret) { |
| @@ -87,6 +89,8 @@ int drm_get_platform_dev(struct platform_device *platdev, | |||
| 87 | 89 | ||
| 88 | list_add_tail(&dev->driver_item, &driver->device_list); | 90 | list_add_tail(&dev->driver_item, &driver->device_list); |
| 89 | 91 | ||
| 92 | mutex_unlock(&drm_global_mutex); | ||
| 93 | |||
| 90 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", | 94 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", |
| 91 | driver->name, driver->major, driver->minor, driver->patchlevel, | 95 | driver->name, driver->major, driver->minor, driver->patchlevel, |
| 92 | driver->date, dev->primary->index); | 96 | driver->date, dev->primary->index); |
| @@ -100,6 +104,7 @@ err_g2: | |||
| 100 | drm_put_minor(&dev->control); | 104 | drm_put_minor(&dev->control); |
| 101 | err_g1: | 105 | err_g1: |
| 102 | kfree(dev); | 106 | kfree(dev); |
| 107 | mutex_unlock(&drm_global_mutex); | ||
| 103 | return ret; | 108 | return ret; |
| 104 | } | 109 | } |
| 105 | EXPORT_SYMBOL(drm_get_platform_dev); | 110 | EXPORT_SYMBOL(drm_get_platform_dev); |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 86118a742231..85da4c40694c 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
| @@ -159,7 +159,7 @@ static ssize_t status_show(struct device *device, | |||
| 159 | struct drm_connector *connector = to_drm_connector(device); | 159 | struct drm_connector *connector = to_drm_connector(device); |
| 160 | enum drm_connector_status status; | 160 | enum drm_connector_status status; |
| 161 | 161 | ||
| 162 | status = connector->funcs->detect(connector); | 162 | status = connector->funcs->detect(connector, true); |
| 163 | return snprintf(buf, PAGE_SIZE, "%s\n", | 163 | return snprintf(buf, PAGE_SIZE, "%s\n", |
| 164 | drm_get_connector_status_name(status)); | 164 | drm_get_connector_status_name(status)); |
| 165 | } | 165 | } |
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 3778360eceea..5df450683aab 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c | |||
| @@ -138,7 +138,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 138 | break; | 138 | break; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | if (!agpmem) | 141 | if (&agpmem->head == &dev->agp->memory) |
| 142 | goto vm_fault_error; | 142 | goto vm_fault_error; |
| 143 | 143 | ||
| 144 | /* | 144 | /* |
| @@ -433,15 +433,7 @@ static void drm_vm_open(struct vm_area_struct *vma) | |||
| 433 | mutex_unlock(&dev->struct_mutex); | 433 | mutex_unlock(&dev->struct_mutex); |
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | /** | 436 | void drm_vm_close_locked(struct vm_area_struct *vma) |
| 437 | * \c close method for all virtual memory types. | ||
| 438 | * | ||
| 439 | * \param vma virtual memory area. | ||
| 440 | * | ||
| 441 | * Search the \p vma private data entry in drm_device::vmalist, unlink it, and | ||
| 442 | * free it. | ||
| 443 | */ | ||
| 444 | static void drm_vm_close(struct vm_area_struct *vma) | ||
| 445 | { | 437 | { |
| 446 | struct drm_file *priv = vma->vm_file->private_data; | 438 | struct drm_file *priv = vma->vm_file->private_data; |
| 447 | struct drm_device *dev = priv->minor->dev; | 439 | struct drm_device *dev = priv->minor->dev; |
| @@ -451,7 +443,6 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
| 451 | vma->vm_start, vma->vm_end - vma->vm_start); | 443 | vma->vm_start, vma->vm_end - vma->vm_start); |
| 452 | atomic_dec(&dev->vma_count); | 444 | atomic_dec(&dev->vma_count); |
| 453 | 445 | ||
| 454 | mutex_lock(&dev->struct_mutex); | ||
| 455 | list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { | 446 | list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { |
| 456 | if (pt->vma == vma) { | 447 | if (pt->vma == vma) { |
| 457 | list_del(&pt->head); | 448 | list_del(&pt->head); |
| @@ -459,6 +450,23 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
| 459 | break; | 450 | break; |
| 460 | } | 451 | } |
| 461 | } | 452 | } |
| 453 | } | ||
| 454 | |||
| 455 | /** | ||
| 456 | * \c close method for all virtual memory types. | ||
| 457 | * | ||
| 458 | * \param vma virtual memory area. | ||
| 459 | * | ||
| 460 | * Search the \p vma private data entry in drm_device::vmalist, unlink it, and | ||
| 461 | * free it. | ||
| 462 | */ | ||
| 463 | static void drm_vm_close(struct vm_area_struct *vma) | ||
| 464 | { | ||
| 465 | struct drm_file *priv = vma->vm_file->private_data; | ||
| 466 | struct drm_device *dev = priv->minor->dev; | ||
| 467 | |||
| 468 | mutex_lock(&dev->struct_mutex); | ||
| 469 | drm_vm_close_locked(vma); | ||
| 462 | mutex_unlock(&dev->struct_mutex); | 470 | mutex_unlock(&dev->struct_mutex); |
| 463 | } | 471 | } |
| 464 | 472 | ||
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 0e6c131313d9..fb07e73581e8 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
| @@ -116,7 +116,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
| 116 | static const struct file_operations i810_buffer_fops = { | 116 | static const struct file_operations i810_buffer_fops = { |
| 117 | .open = drm_open, | 117 | .open = drm_open, |
| 118 | .release = drm_release, | 118 | .release = drm_release, |
| 119 | .unlocked_ioctl = drm_ioctl, | 119 | .unlocked_ioctl = i810_ioctl, |
| 120 | .mmap = i810_mmap_buffers, | 120 | .mmap = i810_mmap_buffers, |
| 121 | .fasync = drm_fasync, | 121 | .fasync = drm_fasync, |
| 122 | }; | 122 | }; |
| @@ -1255,21 +1255,21 @@ long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 1255 | } | 1255 | } |
| 1256 | 1256 | ||
| 1257 | struct drm_ioctl_desc i810_ioctls[] = { | 1257 | struct drm_ioctl_desc i810_ioctls[] = { |
| 1258 | DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1258 | DRM_IOCTL_DEF_DRV(I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
| 1259 | DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), | 1259 | DRM_IOCTL_DEF_DRV(I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), |
| 1260 | DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), | 1260 | DRM_IOCTL_DEF_DRV(I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), |
| 1261 | DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), | 1261 | DRM_IOCTL_DEF_DRV(I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 1262 | DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), | 1262 | DRM_IOCTL_DEF_DRV(I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), |
| 1263 | DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), | 1263 | DRM_IOCTL_DEF_DRV(I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), |
| 1264 | DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), | 1264 | DRM_IOCTL_DEF_DRV(I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), |
| 1265 | DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), | 1265 | DRM_IOCTL_DEF_DRV(I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), |
| 1266 | DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), | 1266 | DRM_IOCTL_DEF_DRV(I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), |
| 1267 | DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), | 1267 | DRM_IOCTL_DEF_DRV(I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), |
| 1268 | DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), | 1268 | DRM_IOCTL_DEF_DRV(I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), |
| 1269 | DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), | 1269 | DRM_IOCTL_DEF_DRV(I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), |
| 1270 | DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1270 | DRM_IOCTL_DEF_DRV(I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
| 1271 | DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), | 1271 | DRM_IOCTL_DEF_DRV(I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), |
| 1272 | DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), | 1272 | DRM_IOCTL_DEF_DRV(I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), |
| 1273 | }; | 1273 | }; |
| 1274 | 1274 | ||
| 1275 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); | 1275 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); |
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 5168862c9227..cc92c7e6236f 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c | |||
| @@ -118,7 +118,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
| 118 | static const struct file_operations i830_buffer_fops = { | 118 | static const struct file_operations i830_buffer_fops = { |
| 119 | .open = drm_open, | 119 | .open = drm_open, |
| 120 | .release = drm_release, | 120 | .release = drm_release, |
| 121 | .unlocked_ioctl = drm_ioctl, | 121 | .unlocked_ioctl = i830_ioctl, |
| 122 | .mmap = i830_mmap_buffers, | 122 | .mmap = i830_mmap_buffers, |
| 123 | .fasync = drm_fasync, | 123 | .fasync = drm_fasync, |
| 124 | }; | 124 | }; |
| @@ -1524,20 +1524,20 @@ long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 1524 | } | 1524 | } |
| 1525 | 1525 | ||
| 1526 | struct drm_ioctl_desc i830_ioctls[] = { | 1526 | struct drm_ioctl_desc i830_ioctls[] = { |
| 1527 | DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1527 | DRM_IOCTL_DEF_DRV(I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
| 1528 | DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), | 1528 | DRM_IOCTL_DEF_DRV(I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), |
| 1529 | DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), | 1529 | DRM_IOCTL_DEF_DRV(I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), |
| 1530 | DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), | 1530 | DRM_IOCTL_DEF_DRV(I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 1531 | DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), | 1531 | DRM_IOCTL_DEF_DRV(I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), |
| 1532 | DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), | 1532 | DRM_IOCTL_DEF_DRV(I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), |
| 1533 | DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), | 1533 | DRM_IOCTL_DEF_DRV(I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), |
| 1534 | DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), | 1534 | DRM_IOCTL_DEF_DRV(I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), |
| 1535 | DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), | 1535 | DRM_IOCTL_DEF_DRV(I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), |
| 1536 | DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), | 1536 | DRM_IOCTL_DEF_DRV(I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), |
| 1537 | DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), | 1537 | DRM_IOCTL_DEF_DRV(I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), |
| 1538 | DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), | 1538 | DRM_IOCTL_DEF_DRV(I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), |
| 1539 | DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), | 1539 | DRM_IOCTL_DEF_DRV(I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), |
| 1540 | DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), | 1540 | DRM_IOCTL_DEF_DRV(I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), |
| 1541 | }; | 1541 | }; |
| 1542 | 1542 | ||
| 1543 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); | 1543 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index da78f2c0d909..5c8e53458edb 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
| @@ -8,6 +8,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
| 8 | i915_suspend.o \ | 8 | i915_suspend.o \ |
| 9 | i915_gem.o \ | 9 | i915_gem.o \ |
| 10 | i915_gem_debug.o \ | 10 | i915_gem_debug.o \ |
| 11 | i915_gem_evict.o \ | ||
| 11 | i915_gem_tiling.o \ | 12 | i915_gem_tiling.o \ |
| 12 | i915_trace_points.o \ | 13 | i915_trace_points.o \ |
| 13 | intel_display.o \ | 14 | intel_display.o \ |
| @@ -18,6 +19,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
| 18 | intel_hdmi.o \ | 19 | intel_hdmi.o \ |
| 19 | intel_sdvo.o \ | 20 | intel_sdvo.o \ |
| 20 | intel_modes.o \ | 21 | intel_modes.o \ |
| 22 | intel_panel.o \ | ||
| 21 | intel_i2c.o \ | 23 | intel_i2c.o \ |
| 22 | intel_fb.o \ | 24 | intel_fb.o \ |
| 23 | intel_tv.o \ | 25 | intel_tv.o \ |
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index 0d6ff640e1c6..8c2ad014c47f 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h | |||
| @@ -30,20 +30,17 @@ | |||
| 30 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
| 31 | 31 | ||
| 32 | struct intel_dvo_device { | 32 | struct intel_dvo_device { |
| 33 | char *name; | 33 | const char *name; |
| 34 | int type; | 34 | int type; |
| 35 | /* DVOA/B/C output register */ | 35 | /* DVOA/B/C output register */ |
| 36 | u32 dvo_reg; | 36 | u32 dvo_reg; |
| 37 | /* GPIO register used for i2c bus to control this device */ | 37 | /* GPIO register used for i2c bus to control this device */ |
| 38 | u32 gpio; | 38 | u32 gpio; |
| 39 | int slave_addr; | 39 | int slave_addr; |
| 40 | struct i2c_adapter *i2c_bus; | ||
| 41 | 40 | ||
| 42 | const struct intel_dvo_dev_ops *dev_ops; | 41 | const struct intel_dvo_dev_ops *dev_ops; |
| 43 | void *dev_priv; | 42 | void *dev_priv; |
| 44 | 43 | struct i2c_adapter *i2c_bus; | |
| 45 | struct drm_display_mode *panel_fixed_mode; | ||
| 46 | bool panel_wants_dither; | ||
| 47 | }; | 44 | }; |
| 48 | 45 | ||
| 49 | struct intel_dvo_dev_ops { | 46 | struct intel_dvo_dev_ops { |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9214119c0154..5e43d7076789 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include "drmP.h" | 32 | #include "drmP.h" |
| 33 | #include "drm.h" | 33 | #include "drm.h" |
| 34 | #include "intel_drv.h" | ||
| 34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
| 35 | #include "i915_drv.h" | 36 | #include "i915_drv.h" |
| 36 | 37 | ||
| @@ -121,6 +122,54 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
| 121 | return 0; | 122 | return 0; |
| 122 | } | 123 | } |
| 123 | 124 | ||
| 125 | static int i915_gem_pageflip_info(struct seq_file *m, void *data) | ||
| 126 | { | ||
| 127 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
| 128 | struct drm_device *dev = node->minor->dev; | ||
| 129 | unsigned long flags; | ||
| 130 | struct intel_crtc *crtc; | ||
| 131 | |||
| 132 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { | ||
| 133 | const char *pipe = crtc->pipe ? "B" : "A"; | ||
| 134 | const char *plane = crtc->plane ? "B" : "A"; | ||
| 135 | struct intel_unpin_work *work; | ||
| 136 | |||
| 137 | spin_lock_irqsave(&dev->event_lock, flags); | ||
| 138 | work = crtc->unpin_work; | ||
| 139 | if (work == NULL) { | ||
| 140 | seq_printf(m, "No flip due on pipe %s (plane %s)\n", | ||
| 141 | pipe, plane); | ||
| 142 | } else { | ||
| 143 | if (!work->pending) { | ||
| 144 | seq_printf(m, "Flip queued on pipe %s (plane %s)\n", | ||
| 145 | pipe, plane); | ||
| 146 | } else { | ||
| 147 | seq_printf(m, "Flip pending (waiting for vsync) on pipe %s (plane %s)\n", | ||
| 148 | pipe, plane); | ||
| 149 | } | ||
| 150 | if (work->enable_stall_check) | ||
| 151 | seq_printf(m, "Stall check enabled, "); | ||
| 152 | else | ||
| 153 | seq_printf(m, "Stall check waiting for page flip ioctl, "); | ||
| 154 | seq_printf(m, "%d prepares\n", work->pending); | ||
| 155 | |||
| 156 | if (work->old_fb_obj) { | ||
| 157 | struct drm_i915_gem_object *obj_priv = to_intel_bo(work->old_fb_obj); | ||
| 158 | if(obj_priv) | ||
| 159 | seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); | ||
| 160 | } | ||
| 161 | if (work->pending_flip_obj) { | ||
| 162 | struct drm_i915_gem_object *obj_priv = to_intel_bo(work->pending_flip_obj); | ||
| 163 | if(obj_priv) | ||
| 164 | seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 168 | } | ||
| 169 | |||
| 170 | return 0; | ||
| 171 | } | ||
| 172 | |||
| 124 | static int i915_gem_request_info(struct seq_file *m, void *data) | 173 | static int i915_gem_request_info(struct seq_file *m, void *data) |
| 125 | { | 174 | { |
| 126 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 175 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
| @@ -467,6 +516,9 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
| 467 | } | 516 | } |
| 468 | } | 517 | } |
| 469 | 518 | ||
| 519 | if (error->overlay) | ||
| 520 | intel_overlay_print_error_state(m, error->overlay); | ||
| 521 | |||
| 470 | out: | 522 | out: |
| 471 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | 523 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); |
| 472 | 524 | ||
| @@ -774,6 +826,7 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
| 774 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 826 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
| 775 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, | 827 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, |
| 776 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, | 828 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, |
| 829 | {"i915_gem_pageflip", i915_gem_pageflip_info, 0}, | ||
| 777 | {"i915_gem_request", i915_gem_request_info, 0}, | 830 | {"i915_gem_request", i915_gem_request_info, 0}, |
| 778 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, | 831 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, |
| 779 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, | 832 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f19ffe87af3c..2dd2c93ebfa3 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -499,6 +499,13 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
| 499 | } | 499 | } |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | |||
| 503 | if (IS_G4X(dev) || IS_IRONLAKE(dev)) { | ||
| 504 | BEGIN_LP_RING(2); | ||
| 505 | OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); | ||
| 506 | OUT_RING(MI_NOOP); | ||
| 507 | ADVANCE_LP_RING(); | ||
| 508 | } | ||
| 502 | i915_emit_breadcrumb(dev); | 509 | i915_emit_breadcrumb(dev); |
| 503 | 510 | ||
| 504 | return 0; | 511 | return 0; |
| @@ -613,8 +620,10 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
| 613 | ret = copy_from_user(cliprects, batch->cliprects, | 620 | ret = copy_from_user(cliprects, batch->cliprects, |
| 614 | batch->num_cliprects * | 621 | batch->num_cliprects * |
| 615 | sizeof(struct drm_clip_rect)); | 622 | sizeof(struct drm_clip_rect)); |
| 616 | if (ret != 0) | 623 | if (ret != 0) { |
| 624 | ret = -EFAULT; | ||
| 617 | goto fail_free; | 625 | goto fail_free; |
| 626 | } | ||
| 618 | } | 627 | } |
| 619 | 628 | ||
| 620 | mutex_lock(&dev->struct_mutex); | 629 | mutex_lock(&dev->struct_mutex); |
| @@ -655,8 +664,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
| 655 | return -ENOMEM; | 664 | return -ENOMEM; |
| 656 | 665 | ||
| 657 | ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); | 666 | ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); |
| 658 | if (ret != 0) | 667 | if (ret != 0) { |
| 668 | ret = -EFAULT; | ||
| 659 | goto fail_batch_free; | 669 | goto fail_batch_free; |
| 670 | } | ||
| 660 | 671 | ||
| 661 | if (cmdbuf->num_cliprects) { | 672 | if (cmdbuf->num_cliprects) { |
| 662 | cliprects = kcalloc(cmdbuf->num_cliprects, | 673 | cliprects = kcalloc(cmdbuf->num_cliprects, |
| @@ -669,8 +680,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
| 669 | ret = copy_from_user(cliprects, cmdbuf->cliprects, | 680 | ret = copy_from_user(cliprects, cmdbuf->cliprects, |
| 670 | cmdbuf->num_cliprects * | 681 | cmdbuf->num_cliprects * |
| 671 | sizeof(struct drm_clip_rect)); | 682 | sizeof(struct drm_clip_rect)); |
| 672 | if (ret != 0) | 683 | if (ret != 0) { |
| 684 | ret = -EFAULT; | ||
| 673 | goto fail_clip_free; | 685 | goto fail_clip_free; |
| 686 | } | ||
| 674 | } | 687 | } |
| 675 | 688 | ||
| 676 | mutex_lock(&dev->struct_mutex); | 689 | mutex_lock(&dev->struct_mutex); |
| @@ -878,7 +891,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
| 878 | int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; | 891 | int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; |
| 879 | u32 temp_lo, temp_hi = 0; | 892 | u32 temp_lo, temp_hi = 0; |
| 880 | u64 mchbar_addr; | 893 | u64 mchbar_addr; |
| 881 | int ret = 0; | 894 | int ret; |
| 882 | 895 | ||
| 883 | if (IS_I965G(dev)) | 896 | if (IS_I965G(dev)) |
| 884 | pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); | 897 | pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); |
| @@ -888,22 +901,23 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
| 888 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ | 901 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ |
| 889 | #ifdef CONFIG_PNP | 902 | #ifdef CONFIG_PNP |
| 890 | if (mchbar_addr && | 903 | if (mchbar_addr && |
| 891 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { | 904 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) |
| 892 | ret = 0; | 905 | return 0; |
| 893 | goto out; | ||
| 894 | } | ||
| 895 | #endif | 906 | #endif |
| 896 | 907 | ||
| 897 | /* Get some space for it */ | 908 | /* Get some space for it */ |
| 898 | ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res, | 909 | dev_priv->mch_res.name = "i915 MCHBAR"; |
| 910 | dev_priv->mch_res.flags = IORESOURCE_MEM; | ||
| 911 | ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, | ||
| 912 | &dev_priv->mch_res, | ||
| 899 | MCHBAR_SIZE, MCHBAR_SIZE, | 913 | MCHBAR_SIZE, MCHBAR_SIZE, |
| 900 | PCIBIOS_MIN_MEM, | 914 | PCIBIOS_MIN_MEM, |
| 901 | 0, pcibios_align_resource, | 915 | 0, pcibios_align_resource, |
| 902 | dev_priv->bridge_dev); | 916 | dev_priv->bridge_dev); |
| 903 | if (ret) { | 917 | if (ret) { |
| 904 | DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); | 918 | DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); |
| 905 | dev_priv->mch_res.start = 0; | 919 | dev_priv->mch_res.start = 0; |
| 906 | goto out; | 920 | return ret; |
| 907 | } | 921 | } |
| 908 | 922 | ||
| 909 | if (IS_I965G(dev)) | 923 | if (IS_I965G(dev)) |
| @@ -912,8 +926,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
| 912 | 926 | ||
| 913 | pci_write_config_dword(dev_priv->bridge_dev, reg, | 927 | pci_write_config_dword(dev_priv->bridge_dev, reg, |
| 914 | lower_32_bits(dev_priv->mch_res.start)); | 928 | lower_32_bits(dev_priv->mch_res.start)); |
| 915 | out: | 929 | return 0; |
| 916 | return ret; | ||
| 917 | } | 930 | } |
| 918 | 931 | ||
| 919 | /* Setup MCHBAR if possible, return true if we should disable it again */ | 932 | /* Setup MCHBAR if possible, return true if we should disable it again */ |
| @@ -1774,9 +1787,9 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) | |||
| 1774 | } | 1787 | } |
| 1775 | } | 1788 | } |
| 1776 | 1789 | ||
| 1777 | div_u64(diff, diff1); | 1790 | diff = div_u64(diff, diff1); |
| 1778 | ret = ((m * diff) + c); | 1791 | ret = ((m * diff) + c); |
| 1779 | div_u64(ret, 10); | 1792 | ret = div_u64(ret, 10); |
| 1780 | 1793 | ||
| 1781 | dev_priv->last_count1 = total_count; | 1794 | dev_priv->last_count1 = total_count; |
| 1782 | dev_priv->last_time1 = now; | 1795 | dev_priv->last_time1 = now; |
| @@ -1845,7 +1858,7 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv) | |||
| 1845 | 1858 | ||
| 1846 | /* More magic constants... */ | 1859 | /* More magic constants... */ |
| 1847 | diff = diff * 1181; | 1860 | diff = diff * 1181; |
| 1848 | div_u64(diff, diffms * 10); | 1861 | diff = div_u64(diff, diffms * 10); |
| 1849 | dev_priv->gfx_power = diff; | 1862 | dev_priv->gfx_power = diff; |
| 1850 | } | 1863 | } |
| 1851 | 1864 | ||
| @@ -2075,6 +2088,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 2075 | goto free_priv; | 2088 | goto free_priv; |
| 2076 | } | 2089 | } |
| 2077 | 2090 | ||
| 2091 | /* overlay on gen2 is broken and can't address above 1G */ | ||
| 2092 | if (IS_GEN2(dev)) | ||
| 2093 | dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); | ||
| 2094 | |||
| 2078 | dev_priv->regs = ioremap(base, size); | 2095 | dev_priv->regs = ioremap(base, size); |
| 2079 | if (!dev_priv->regs) { | 2096 | if (!dev_priv->regs) { |
| 2080 | DRM_ERROR("failed to map registers\n"); | 2097 | DRM_ERROR("failed to map registers\n"); |
| @@ -2214,6 +2231,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 2214 | dev_priv->mchdev_lock = &mchdev_lock; | 2231 | dev_priv->mchdev_lock = &mchdev_lock; |
| 2215 | spin_unlock(&mchdev_lock); | 2232 | spin_unlock(&mchdev_lock); |
| 2216 | 2233 | ||
| 2234 | /* XXX Prevent module unload due to memory corruption bugs. */ | ||
| 2235 | __module_get(THIS_MODULE); | ||
| 2236 | |||
| 2217 | return 0; | 2237 | return 0; |
| 2218 | 2238 | ||
| 2219 | out_workqueue_free: | 2239 | out_workqueue_free: |
| @@ -2360,46 +2380,46 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | |||
| 2360 | } | 2380 | } |
| 2361 | 2381 | ||
| 2362 | struct drm_ioctl_desc i915_ioctls[] = { | 2382 | struct drm_ioctl_desc i915_ioctls[] = { |
| 2363 | DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2383 | DRM_IOCTL_DEF_DRV(I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 2364 | DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), | 2384 | DRM_IOCTL_DEF_DRV(I915_FLUSH, i915_flush_ioctl, DRM_AUTH), |
| 2365 | DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), | 2385 | DRM_IOCTL_DEF_DRV(I915_FLIP, i915_flip_bufs, DRM_AUTH), |
| 2366 | DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), | 2386 | DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), |
| 2367 | DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), | 2387 | DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), |
| 2368 | DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), | 2388 | DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), |
| 2369 | DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), | 2389 | DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), |
| 2370 | DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2390 | DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 2371 | DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), | 2391 | DRM_IOCTL_DEF_DRV(I915_ALLOC, i915_mem_alloc, DRM_AUTH), |
| 2372 | DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), | 2392 | DRM_IOCTL_DEF_DRV(I915_FREE, i915_mem_free, DRM_AUTH), |
| 2373 | DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2393 | DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 2374 | DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), | 2394 | DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), |
| 2375 | DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), | 2395 | DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 2376 | DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), | 2396 | DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 2377 | DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), | 2397 | DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), |
| 2378 | DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), | 2398 | DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), |
| 2379 | DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2399 | DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 2380 | DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2400 | DRM_IOCTL_DEF_DRV(I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
| 2381 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), | 2401 | DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), |
| 2382 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), | 2402 | DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), |
| 2383 | DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2403 | DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), |
| 2384 | DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2404 | DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), |
| 2385 | DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), | 2405 | DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 2386 | DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), | 2406 | DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 2387 | DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2407 | DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
| 2388 | DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2408 | DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
| 2389 | DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), | 2409 | DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), |
| 2390 | DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), | 2410 | DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), |
| 2391 | DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), | 2411 | DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), |
| 2392 | DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), | 2412 | DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), |
| 2393 | DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), | 2413 | DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), |
| 2394 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), | 2414 | DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), |
| 2395 | DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), | 2415 | DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), |
| 2396 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), | 2416 | DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), |
| 2397 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), | 2417 | DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), |
| 2398 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), | 2418 | DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), |
| 2399 | DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), | 2419 | DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), |
| 2400 | DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), | 2420 | DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), |
| 2401 | DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 2421 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 2402 | DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 2422 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
| 2403 | }; | 2423 | }; |
| 2404 | 2424 | ||
| 2405 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 2425 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5044f653e8ea..6dbe14cc4f74 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -61,91 +61,86 @@ extern int intel_agp_enabled; | |||
| 61 | .driver_data = (unsigned long) info } | 61 | .driver_data = (unsigned long) info } |
| 62 | 62 | ||
| 63 | static const struct intel_device_info intel_i830_info = { | 63 | static const struct intel_device_info intel_i830_info = { |
| 64 | .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, | 64 | .gen = 2, .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, |
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | static const struct intel_device_info intel_845g_info = { | 67 | static const struct intel_device_info intel_845g_info = { |
| 68 | .is_i8xx = 1, | 68 | .gen = 2, .is_i8xx = 1, |
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | static const struct intel_device_info intel_i85x_info = { | 71 | static const struct intel_device_info intel_i85x_info = { |
| 72 | .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, | 72 | .gen = 2, .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, |
| 73 | .cursor_needs_physical = 1, | 73 | .cursor_needs_physical = 1, |
| 74 | }; | 74 | }; |
| 75 | 75 | ||
| 76 | static const struct intel_device_info intel_i865g_info = { | 76 | static const struct intel_device_info intel_i865g_info = { |
| 77 | .is_i8xx = 1, | 77 | .gen = 2, .is_i8xx = 1, |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | static const struct intel_device_info intel_i915g_info = { | 80 | static const struct intel_device_info intel_i915g_info = { |
| 81 | .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, | 81 | .gen = 3, .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, |
| 82 | }; | 82 | }; |
| 83 | static const struct intel_device_info intel_i915gm_info = { | 83 | static const struct intel_device_info intel_i915gm_info = { |
| 84 | .is_i9xx = 1, .is_mobile = 1, | 84 | .gen = 3, .is_i9xx = 1, .is_mobile = 1, |
| 85 | .cursor_needs_physical = 1, | 85 | .cursor_needs_physical = 1, |
| 86 | }; | 86 | }; |
| 87 | static const struct intel_device_info intel_i945g_info = { | 87 | static const struct intel_device_info intel_i945g_info = { |
| 88 | .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, | 88 | .gen = 3, .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, |
| 89 | }; | 89 | }; |
| 90 | static const struct intel_device_info intel_i945gm_info = { | 90 | static const struct intel_device_info intel_i945gm_info = { |
| 91 | .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, | 91 | .gen = 3, .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, |
| 92 | .has_hotplug = 1, .cursor_needs_physical = 1, | 92 | .has_hotplug = 1, .cursor_needs_physical = 1, |
| 93 | }; | 93 | }; |
| 94 | 94 | ||
| 95 | static const struct intel_device_info intel_i965g_info = { | 95 | static const struct intel_device_info intel_i965g_info = { |
| 96 | .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, | 96 | .gen = 4, .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, |
| 97 | .has_hotplug = 1, | ||
| 97 | }; | 98 | }; |
| 98 | 99 | ||
| 99 | static const struct intel_device_info intel_i965gm_info = { | 100 | static const struct intel_device_info intel_i965gm_info = { |
| 100 | .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, | 101 | .gen = 4, .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, |
| 101 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, | 102 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, |
| 102 | .has_hotplug = 1, | ||
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | static const struct intel_device_info intel_g33_info = { | 105 | static const struct intel_device_info intel_g33_info = { |
| 106 | .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 106 | .gen = 3, .is_g33 = 1, .is_i9xx = 1, |
| 107 | .has_hotplug = 1, | 107 | .need_gfx_hws = 1, .has_hotplug = 1, |
| 108 | }; | 108 | }; |
| 109 | 109 | ||
| 110 | static const struct intel_device_info intel_g45_info = { | 110 | static const struct intel_device_info intel_g45_info = { |
| 111 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 111 | .gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
| 112 | .has_pipe_cxsr = 1, | 112 | .has_pipe_cxsr = 1, .has_hotplug = 1, |
| 113 | .has_hotplug = 1, | ||
| 114 | }; | 113 | }; |
| 115 | 114 | ||
| 116 | static const struct intel_device_info intel_gm45_info = { | 115 | static const struct intel_device_info intel_gm45_info = { |
| 117 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, | 116 | .gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, |
| 118 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, | 117 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, |
| 119 | .has_pipe_cxsr = 1, | 118 | .has_pipe_cxsr = 1, .has_hotplug = 1, |
| 120 | .has_hotplug = 1, | ||
| 121 | }; | 119 | }; |
| 122 | 120 | ||
| 123 | static const struct intel_device_info intel_pineview_info = { | 121 | static const struct intel_device_info intel_pineview_info = { |
| 124 | .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, | 122 | .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, |
| 125 | .need_gfx_hws = 1, | 123 | .need_gfx_hws = 1, .has_hotplug = 1, |
| 126 | .has_hotplug = 1, | ||
| 127 | }; | 124 | }; |
| 128 | 125 | ||
| 129 | static const struct intel_device_info intel_ironlake_d_info = { | 126 | static const struct intel_device_info intel_ironlake_d_info = { |
| 130 | .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 127 | .gen = 5, .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, |
| 131 | .has_pipe_cxsr = 1, | 128 | .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, |
| 132 | .has_hotplug = 1, | ||
| 133 | }; | 129 | }; |
| 134 | 130 | ||
| 135 | static const struct intel_device_info intel_ironlake_m_info = { | 131 | static const struct intel_device_info intel_ironlake_m_info = { |
| 136 | .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, | 132 | .gen = 5, .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, |
| 137 | .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, | 133 | .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, |
| 138 | .has_hotplug = 1, | ||
| 139 | }; | 134 | }; |
| 140 | 135 | ||
| 141 | static const struct intel_device_info intel_sandybridge_d_info = { | 136 | static const struct intel_device_info intel_sandybridge_d_info = { |
| 142 | .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 137 | .gen = 6, .is_i965g = 1, .is_i9xx = 1, |
| 143 | .has_hotplug = 1, .is_gen6 = 1, | 138 | .need_gfx_hws = 1, .has_hotplug = 1, |
| 144 | }; | 139 | }; |
| 145 | 140 | ||
| 146 | static const struct intel_device_info intel_sandybridge_m_info = { | 141 | static const struct intel_device_info intel_sandybridge_m_info = { |
| 147 | .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 142 | .gen = 6, .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, |
| 148 | .has_hotplug = 1, .is_gen6 = 1, | 143 | .need_gfx_hws = 1, .has_hotplug = 1, |
| 149 | }; | 144 | }; |
| 150 | 145 | ||
| 151 | static const struct pci_device_id pciidlist[] = { /* aka */ | 146 | static const struct pci_device_id pciidlist[] = { /* aka */ |
| @@ -175,12 +170,18 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
| 175 | INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ | 170 | INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ |
| 176 | INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ | 171 | INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ |
| 177 | INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ | 172 | INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ |
| 173 | INTEL_VGA_DEVICE(0x2e92, &intel_g45_info), /* B43_G.1 */ | ||
| 178 | INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), | 174 | INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), |
| 179 | INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), | 175 | INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), |
| 180 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), | 176 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), |
| 181 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), | 177 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), |
| 182 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), | 178 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), |
| 179 | INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info), | ||
| 180 | INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info), | ||
| 183 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), | 181 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), |
| 182 | INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), | ||
| 183 | INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), | ||
| 184 | INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), | ||
| 184 | {0, 0, 0} | 185 | {0, 0, 0} |
| 185 | }; | 186 | }; |
| 186 | 187 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 906663b9929e..af4a263cf257 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -113,6 +113,9 @@ struct intel_opregion { | |||
| 113 | int enabled; | 113 | int enabled; |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | struct intel_overlay; | ||
| 117 | struct intel_overlay_error_state; | ||
| 118 | |||
| 116 | struct drm_i915_master_private { | 119 | struct drm_i915_master_private { |
| 117 | drm_local_map_t *sarea; | 120 | drm_local_map_t *sarea; |
| 118 | struct _drm_i915_sarea *sarea_priv; | 121 | struct _drm_i915_sarea *sarea_priv; |
| @@ -166,6 +169,7 @@ struct drm_i915_error_state { | |||
| 166 | u32 purgeable:1; | 169 | u32 purgeable:1; |
| 167 | } *active_bo; | 170 | } *active_bo; |
| 168 | u32 active_bo_count; | 171 | u32 active_bo_count; |
| 172 | struct intel_overlay_error_state *overlay; | ||
| 169 | }; | 173 | }; |
| 170 | 174 | ||
| 171 | struct drm_i915_display_funcs { | 175 | struct drm_i915_display_funcs { |
| @@ -186,9 +190,8 @@ struct drm_i915_display_funcs { | |||
| 186 | /* clock gating init */ | 190 | /* clock gating init */ |
| 187 | }; | 191 | }; |
| 188 | 192 | ||
| 189 | struct intel_overlay; | ||
| 190 | |||
| 191 | struct intel_device_info { | 193 | struct intel_device_info { |
| 194 | u8 gen; | ||
| 192 | u8 is_mobile : 1; | 195 | u8 is_mobile : 1; |
| 193 | u8 is_i8xx : 1; | 196 | u8 is_i8xx : 1; |
| 194 | u8 is_i85x : 1; | 197 | u8 is_i85x : 1; |
| @@ -204,7 +207,6 @@ struct intel_device_info { | |||
| 204 | u8 is_broadwater : 1; | 207 | u8 is_broadwater : 1; |
| 205 | u8 is_crestline : 1; | 208 | u8 is_crestline : 1; |
| 206 | u8 is_ironlake : 1; | 209 | u8 is_ironlake : 1; |
| 207 | u8 is_gen6 : 1; | ||
| 208 | u8 has_fbc : 1; | 210 | u8 has_fbc : 1; |
| 209 | u8 has_rc6 : 1; | 211 | u8 has_rc6 : 1; |
| 210 | u8 has_pipe_cxsr : 1; | 212 | u8 has_pipe_cxsr : 1; |
| @@ -242,6 +244,7 @@ typedef struct drm_i915_private { | |||
| 242 | struct pci_dev *bridge_dev; | 244 | struct pci_dev *bridge_dev; |
| 243 | struct intel_ring_buffer render_ring; | 245 | struct intel_ring_buffer render_ring; |
| 244 | struct intel_ring_buffer bsd_ring; | 246 | struct intel_ring_buffer bsd_ring; |
| 247 | uint32_t next_seqno; | ||
| 245 | 248 | ||
| 246 | drm_dma_handle_t *status_page_dmah; | 249 | drm_dma_handle_t *status_page_dmah; |
| 247 | void *seqno_page; | 250 | void *seqno_page; |
| @@ -251,6 +254,7 @@ typedef struct drm_i915_private { | |||
| 251 | drm_local_map_t hws_map; | 254 | drm_local_map_t hws_map; |
| 252 | struct drm_gem_object *seqno_obj; | 255 | struct drm_gem_object *seqno_obj; |
| 253 | struct drm_gem_object *pwrctx; | 256 | struct drm_gem_object *pwrctx; |
| 257 | struct drm_gem_object *renderctx; | ||
| 254 | 258 | ||
| 255 | struct resource mch_res; | 259 | struct resource mch_res; |
| 256 | 260 | ||
| @@ -285,6 +289,9 @@ typedef struct drm_i915_private { | |||
| 285 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | 289 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
| 286 | int vblank_pipe; | 290 | int vblank_pipe; |
| 287 | int num_pipe; | 291 | int num_pipe; |
| 292 | u32 flush_rings; | ||
| 293 | #define FLUSH_RENDER_RING 0x1 | ||
| 294 | #define FLUSH_BSD_RING 0x2 | ||
| 288 | 295 | ||
| 289 | /* For hangcheck timer */ | 296 | /* For hangcheck timer */ |
| 290 | #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ | 297 | #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ |
| @@ -568,8 +575,6 @@ typedef struct drm_i915_private { | |||
| 568 | */ | 575 | */ |
| 569 | struct delayed_work retire_work; | 576 | struct delayed_work retire_work; |
| 570 | 577 | ||
| 571 | uint32_t next_gem_seqno; | ||
| 572 | |||
| 573 | /** | 578 | /** |
| 574 | * Waiting sequence number, if any | 579 | * Waiting sequence number, if any |
| 575 | */ | 580 | */ |
| @@ -610,6 +615,8 @@ typedef struct drm_i915_private { | |||
| 610 | struct sdvo_device_mapping sdvo_mappings[2]; | 615 | struct sdvo_device_mapping sdvo_mappings[2]; |
| 611 | /* indicate whether the LVDS_BORDER should be enabled or not */ | 616 | /* indicate whether the LVDS_BORDER should be enabled or not */ |
| 612 | unsigned int lvds_border_bits; | 617 | unsigned int lvds_border_bits; |
| 618 | /* Panel fitter placement and size for Ironlake+ */ | ||
| 619 | u32 pch_pf_pos, pch_pf_size; | ||
| 613 | 620 | ||
| 614 | struct drm_crtc *plane_to_crtc_mapping[2]; | 621 | struct drm_crtc *plane_to_crtc_mapping[2]; |
| 615 | struct drm_crtc *pipe_to_crtc_mapping[2]; | 622 | struct drm_crtc *pipe_to_crtc_mapping[2]; |
| @@ -669,6 +676,8 @@ struct drm_i915_gem_object { | |||
| 669 | struct list_head list; | 676 | struct list_head list; |
| 670 | /** This object's place on GPU write list */ | 677 | /** This object's place on GPU write list */ |
| 671 | struct list_head gpu_write_list; | 678 | struct list_head gpu_write_list; |
| 679 | /** This object's place on eviction list */ | ||
| 680 | struct list_head evict_list; | ||
| 672 | 681 | ||
| 673 | /** | 682 | /** |
| 674 | * This is set if the object is on the active or flushing lists | 683 | * This is set if the object is on the active or flushing lists |
| @@ -978,6 +987,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); | |||
| 978 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 987 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
| 979 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 988 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
| 980 | unsigned long end); | 989 | unsigned long end); |
| 990 | int i915_gpu_idle(struct drm_device *dev); | ||
| 981 | int i915_gem_idle(struct drm_device *dev); | 991 | int i915_gem_idle(struct drm_device *dev); |
| 982 | uint32_t i915_add_request(struct drm_device *dev, | 992 | uint32_t i915_add_request(struct drm_device *dev, |
| 983 | struct drm_file *file_priv, | 993 | struct drm_file *file_priv, |
| @@ -991,7 +1001,9 @@ int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | |||
| 991 | int write); | 1001 | int write); |
| 992 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); | 1002 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); |
| 993 | int i915_gem_attach_phys_object(struct drm_device *dev, | 1003 | int i915_gem_attach_phys_object(struct drm_device *dev, |
| 994 | struct drm_gem_object *obj, int id); | 1004 | struct drm_gem_object *obj, |
| 1005 | int id, | ||
| 1006 | int align); | ||
| 995 | void i915_gem_detach_phys_object(struct drm_device *dev, | 1007 | void i915_gem_detach_phys_object(struct drm_device *dev, |
| 996 | struct drm_gem_object *obj); | 1008 | struct drm_gem_object *obj); |
| 997 | void i915_gem_free_all_phys_object(struct drm_device *dev); | 1009 | void i915_gem_free_all_phys_object(struct drm_device *dev); |
| @@ -1003,6 +1015,11 @@ int i915_gem_object_flush_write_domain(struct drm_gem_object *obj); | |||
| 1003 | void i915_gem_shrinker_init(void); | 1015 | void i915_gem_shrinker_init(void); |
| 1004 | void i915_gem_shrinker_exit(void); | 1016 | void i915_gem_shrinker_exit(void); |
| 1005 | 1017 | ||
| 1018 | /* i915_gem_evict.c */ | ||
| 1019 | int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment); | ||
| 1020 | int i915_gem_evict_everything(struct drm_device *dev); | ||
| 1021 | int i915_gem_evict_inactive(struct drm_device *dev); | ||
| 1022 | |||
| 1006 | /* i915_gem_tiling.c */ | 1023 | /* i915_gem_tiling.c */ |
| 1007 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | 1024 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); |
| 1008 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); | 1025 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); |
| @@ -1066,6 +1083,10 @@ extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | |||
| 1066 | extern void intel_detect_pch (struct drm_device *dev); | 1083 | extern void intel_detect_pch (struct drm_device *dev); |
| 1067 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | 1084 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
| 1068 | 1085 | ||
| 1086 | /* overlay */ | ||
| 1087 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); | ||
| 1088 | extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); | ||
| 1089 | |||
| 1069 | /** | 1090 | /** |
| 1070 | * Lock test for when it's just for synchronization of ring access. | 1091 | * Lock test for when it's just for synchronization of ring access. |
| 1071 | * | 1092 | * |
| @@ -1092,26 +1113,26 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
| 1092 | #define I915_VERBOSE 0 | 1113 | #define I915_VERBOSE 0 |
| 1093 | 1114 | ||
| 1094 | #define BEGIN_LP_RING(n) do { \ | 1115 | #define BEGIN_LP_RING(n) do { \ |
| 1095 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1116 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
| 1096 | if (I915_VERBOSE) \ | 1117 | if (I915_VERBOSE) \ |
| 1097 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ | 1118 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ |
| 1098 | intel_ring_begin(dev, &dev_priv->render_ring, (n)); \ | 1119 | intel_ring_begin(dev, &dev_priv__->render_ring, (n)); \ |
| 1099 | } while (0) | 1120 | } while (0) |
| 1100 | 1121 | ||
| 1101 | 1122 | ||
| 1102 | #define OUT_RING(x) do { \ | 1123 | #define OUT_RING(x) do { \ |
| 1103 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1124 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
| 1104 | if (I915_VERBOSE) \ | 1125 | if (I915_VERBOSE) \ |
| 1105 | DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ | 1126 | DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ |
| 1106 | intel_ring_emit(dev, &dev_priv->render_ring, x); \ | 1127 | intel_ring_emit(dev, &dev_priv__->render_ring, x); \ |
| 1107 | } while (0) | 1128 | } while (0) |
| 1108 | 1129 | ||
| 1109 | #define ADVANCE_LP_RING() do { \ | 1130 | #define ADVANCE_LP_RING() do { \ |
| 1110 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1131 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
| 1111 | if (I915_VERBOSE) \ | 1132 | if (I915_VERBOSE) \ |
| 1112 | DRM_DEBUG("ADVANCE_LP_RING %x\n", \ | 1133 | DRM_DEBUG("ADVANCE_LP_RING %x\n", \ |
| 1113 | dev_priv->render_ring.tail); \ | 1134 | dev_priv__->render_ring.tail); \ |
| 1114 | intel_ring_advance(dev, &dev_priv->render_ring); \ | 1135 | intel_ring_advance(dev, &dev_priv__->render_ring); \ |
| 1115 | } while(0) | 1136 | } while(0) |
| 1116 | 1137 | ||
| 1117 | /** | 1138 | /** |
| @@ -1141,7 +1162,6 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
| 1141 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) | 1162 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) |
| 1142 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) | 1163 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) |
| 1143 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) | 1164 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) |
| 1144 | #define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx) | ||
| 1145 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) | 1165 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) |
| 1146 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) | 1166 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) |
| 1147 | #define IS_I945G(dev) ((dev)->pci_device == 0x2772) | 1167 | #define IS_I945G(dev) ((dev)->pci_device == 0x2772) |
| @@ -1160,27 +1180,13 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
| 1160 | #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) | 1180 | #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) |
| 1161 | #define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake) | 1181 | #define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake) |
| 1162 | #define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx) | 1182 | #define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx) |
| 1163 | #define IS_GEN6(dev) (INTEL_INFO(dev)->is_gen6) | ||
| 1164 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) | 1183 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) |
| 1165 | 1184 | ||
| 1166 | #define IS_GEN3(dev) (IS_I915G(dev) || \ | 1185 | #define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2) |
| 1167 | IS_I915GM(dev) || \ | 1186 | #define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3) |
| 1168 | IS_I945G(dev) || \ | 1187 | #define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4) |
| 1169 | IS_I945GM(dev) || \ | 1188 | #define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) |
| 1170 | IS_G33(dev) || \ | 1189 | #define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) |
| 1171 | IS_PINEVIEW(dev)) | ||
| 1172 | #define IS_GEN4(dev) ((dev)->pci_device == 0x2972 || \ | ||
| 1173 | (dev)->pci_device == 0x2982 || \ | ||
| 1174 | (dev)->pci_device == 0x2992 || \ | ||
| 1175 | (dev)->pci_device == 0x29A2 || \ | ||
| 1176 | (dev)->pci_device == 0x2A02 || \ | ||
| 1177 | (dev)->pci_device == 0x2A12 || \ | ||
| 1178 | (dev)->pci_device == 0x2E02 || \ | ||
| 1179 | (dev)->pci_device == 0x2E12 || \ | ||
| 1180 | (dev)->pci_device == 0x2E22 || \ | ||
| 1181 | (dev)->pci_device == 0x2E32 || \ | ||
| 1182 | (dev)->pci_device == 0x2A42 || \ | ||
| 1183 | (dev)->pci_device == 0x2E42) | ||
| 1184 | 1190 | ||
| 1185 | #define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) | 1191 | #define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) |
| 1186 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) | 1192 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0758c7802e6b..90b1d6753b9d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -34,7 +34,9 @@ | |||
| 34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
| 35 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
| 36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
| 37 | #include <linux/intel-gtt.h> | ||
| 37 | 38 | ||
| 39 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); | ||
| 38 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); | 40 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); |
| 39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); | 41 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); |
| 40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); | 42 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); |
| @@ -48,8 +50,6 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); | |||
| 48 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 50 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, |
| 49 | unsigned alignment); | 51 | unsigned alignment); |
| 50 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); | 52 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); |
| 51 | static int i915_gem_evict_something(struct drm_device *dev, int min_size); | ||
| 52 | static int i915_gem_evict_from_inactive_list(struct drm_device *dev); | ||
| 53 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 53 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, |
| 54 | struct drm_i915_gem_pwrite *args, | 54 | struct drm_i915_gem_pwrite *args, |
| 55 | struct drm_file *file_priv); | 55 | struct drm_file *file_priv); |
| @@ -58,6 +58,14 @@ static void i915_gem_free_object_tail(struct drm_gem_object *obj); | |||
| 58 | static LIST_HEAD(shrink_list); | 58 | static LIST_HEAD(shrink_list); |
| 59 | static DEFINE_SPINLOCK(shrink_list_lock); | 59 | static DEFINE_SPINLOCK(shrink_list_lock); |
| 60 | 60 | ||
| 61 | static inline bool | ||
| 62 | i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv) | ||
| 63 | { | ||
| 64 | return obj_priv->gtt_space && | ||
| 65 | !obj_priv->active && | ||
| 66 | obj_priv->pin_count == 0; | ||
| 67 | } | ||
| 68 | |||
| 61 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 69 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
| 62 | unsigned long end) | 70 | unsigned long end) |
| 63 | { | 71 | { |
| @@ -128,12 +136,13 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
| 128 | return -ENOMEM; | 136 | return -ENOMEM; |
| 129 | 137 | ||
| 130 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 138 | ret = drm_gem_handle_create(file_priv, obj, &handle); |
| 139 | /* drop reference from allocate - handle holds it now */ | ||
| 131 | drm_gem_object_unreference_unlocked(obj); | 140 | drm_gem_object_unreference_unlocked(obj); |
| 132 | if (ret) | 141 | if (ret) { |
| 133 | return ret; | 142 | return ret; |
| 143 | } | ||
| 134 | 144 | ||
| 135 | args->handle = handle; | 145 | args->handle = handle; |
| 136 | |||
| 137 | return 0; | 146 | return 0; |
| 138 | } | 147 | } |
| 139 | 148 | ||
| @@ -313,7 +322,8 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) | |||
| 313 | if (ret == -ENOMEM) { | 322 | if (ret == -ENOMEM) { |
| 314 | struct drm_device *dev = obj->dev; | 323 | struct drm_device *dev = obj->dev; |
| 315 | 324 | ||
| 316 | ret = i915_gem_evict_something(dev, obj->size); | 325 | ret = i915_gem_evict_something(dev, obj->size, |
| 326 | i915_gem_get_gtt_alignment(obj)); | ||
| 317 | if (ret) | 327 | if (ret) |
| 318 | return ret; | 328 | return ret; |
| 319 | 329 | ||
| @@ -459,14 +469,17 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
| 459 | return -ENOENT; | 469 | return -ENOENT; |
| 460 | obj_priv = to_intel_bo(obj); | 470 | obj_priv = to_intel_bo(obj); |
| 461 | 471 | ||
| 462 | /* Bounds check source. | 472 | /* Bounds check source. */ |
| 463 | * | 473 | if (args->offset > obj->size || args->size > obj->size - args->offset) { |
| 464 | * XXX: This could use review for overflow issues... | 474 | ret = -EINVAL; |
| 465 | */ | 475 | goto err; |
| 466 | if (args->offset > obj->size || args->size > obj->size || | 476 | } |
| 467 | args->offset + args->size > obj->size) { | 477 | |
| 468 | drm_gem_object_unreference_unlocked(obj); | 478 | if (!access_ok(VERIFY_WRITE, |
| 469 | return -EINVAL; | 479 | (char __user *)(uintptr_t)args->data_ptr, |
| 480 | args->size)) { | ||
| 481 | ret = -EFAULT; | ||
| 482 | goto err; | ||
| 470 | } | 483 | } |
| 471 | 484 | ||
| 472 | if (i915_gem_object_needs_bit17_swizzle(obj)) { | 485 | if (i915_gem_object_needs_bit17_swizzle(obj)) { |
| @@ -478,8 +491,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
| 478 | file_priv); | 491 | file_priv); |
| 479 | } | 492 | } |
| 480 | 493 | ||
| 494 | err: | ||
| 481 | drm_gem_object_unreference_unlocked(obj); | 495 | drm_gem_object_unreference_unlocked(obj); |
| 482 | |||
| 483 | return ret; | 496 | return ret; |
| 484 | } | 497 | } |
| 485 | 498 | ||
| @@ -568,8 +581,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
| 568 | 581 | ||
| 569 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 582 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
| 570 | remain = args->size; | 583 | remain = args->size; |
| 571 | if (!access_ok(VERIFY_READ, user_data, remain)) | ||
| 572 | return -EFAULT; | ||
| 573 | 584 | ||
| 574 | 585 | ||
| 575 | mutex_lock(&dev->struct_mutex); | 586 | mutex_lock(&dev->struct_mutex); |
| @@ -922,14 +933,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
| 922 | return -ENOENT; | 933 | return -ENOENT; |
| 923 | obj_priv = to_intel_bo(obj); | 934 | obj_priv = to_intel_bo(obj); |
| 924 | 935 | ||
| 925 | /* Bounds check destination. | 936 | /* Bounds check destination. */ |
| 926 | * | 937 | if (args->offset > obj->size || args->size > obj->size - args->offset) { |
| 927 | * XXX: This could use review for overflow issues... | 938 | ret = -EINVAL; |
| 928 | */ | 939 | goto err; |
| 929 | if (args->offset > obj->size || args->size > obj->size || | 940 | } |
| 930 | args->offset + args->size > obj->size) { | 941 | |
| 931 | drm_gem_object_unreference_unlocked(obj); | 942 | if (!access_ok(VERIFY_READ, |
| 932 | return -EINVAL; | 943 | (char __user *)(uintptr_t)args->data_ptr, |
| 944 | args->size)) { | ||
| 945 | ret = -EFAULT; | ||
| 946 | goto err; | ||
| 933 | } | 947 | } |
| 934 | 948 | ||
| 935 | /* We can only do the GTT pwrite on untiled buffers, as otherwise | 949 | /* We can only do the GTT pwrite on untiled buffers, as otherwise |
| @@ -963,8 +977,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
| 963 | DRM_INFO("pwrite failed %d\n", ret); | 977 | DRM_INFO("pwrite failed %d\n", ret); |
| 964 | #endif | 978 | #endif |
| 965 | 979 | ||
| 980 | err: | ||
| 966 | drm_gem_object_unreference_unlocked(obj); | 981 | drm_gem_object_unreference_unlocked(obj); |
| 967 | |||
| 968 | return ret; | 982 | return ret; |
| 969 | } | 983 | } |
| 970 | 984 | ||
| @@ -1036,6 +1050,11 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
| 1036 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); | 1050 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); |
| 1037 | } | 1051 | } |
| 1038 | 1052 | ||
| 1053 | |||
| 1054 | /* Maintain LRU order of "inactive" objects */ | ||
| 1055 | if (ret == 0 && i915_gem_object_is_inactive(obj_priv)) | ||
| 1056 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
| 1057 | |||
| 1039 | drm_gem_object_unreference(obj); | 1058 | drm_gem_object_unreference(obj); |
| 1040 | mutex_unlock(&dev->struct_mutex); | 1059 | mutex_unlock(&dev->struct_mutex); |
| 1041 | return ret; | 1060 | return ret; |
| @@ -1137,7 +1156,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 1137 | { | 1156 | { |
| 1138 | struct drm_gem_object *obj = vma->vm_private_data; | 1157 | struct drm_gem_object *obj = vma->vm_private_data; |
| 1139 | struct drm_device *dev = obj->dev; | 1158 | struct drm_device *dev = obj->dev; |
| 1140 | struct drm_i915_private *dev_priv = dev->dev_private; | 1159 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1141 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1160 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
| 1142 | pgoff_t page_offset; | 1161 | pgoff_t page_offset; |
| 1143 | unsigned long pfn; | 1162 | unsigned long pfn; |
| @@ -1155,8 +1174,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 1155 | if (ret) | 1174 | if (ret) |
| 1156 | goto unlock; | 1175 | goto unlock; |
| 1157 | 1176 | ||
| 1158 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
| 1159 | |||
| 1160 | ret = i915_gem_object_set_to_gtt_domain(obj, write); | 1177 | ret = i915_gem_object_set_to_gtt_domain(obj, write); |
| 1161 | if (ret) | 1178 | if (ret) |
| 1162 | goto unlock; | 1179 | goto unlock; |
| @@ -1169,6 +1186,9 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 1169 | goto unlock; | 1186 | goto unlock; |
| 1170 | } | 1187 | } |
| 1171 | 1188 | ||
| 1189 | if (i915_gem_object_is_inactive(obj_priv)) | ||
| 1190 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
| 1191 | |||
| 1172 | pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + | 1192 | pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + |
| 1173 | page_offset; | 1193 | page_offset; |
| 1174 | 1194 | ||
| @@ -1363,7 +1383,6 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
| 1363 | struct drm_file *file_priv) | 1383 | struct drm_file *file_priv) |
| 1364 | { | 1384 | { |
| 1365 | struct drm_i915_gem_mmap_gtt *args = data; | 1385 | struct drm_i915_gem_mmap_gtt *args = data; |
| 1366 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1367 | struct drm_gem_object *obj; | 1386 | struct drm_gem_object *obj; |
| 1368 | struct drm_i915_gem_object *obj_priv; | 1387 | struct drm_i915_gem_object *obj_priv; |
| 1369 | int ret; | 1388 | int ret; |
| @@ -1409,7 +1428,6 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
| 1409 | mutex_unlock(&dev->struct_mutex); | 1428 | mutex_unlock(&dev->struct_mutex); |
| 1410 | return ret; | 1429 | return ret; |
| 1411 | } | 1430 | } |
| 1412 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
| 1413 | } | 1431 | } |
| 1414 | 1432 | ||
| 1415 | drm_gem_object_unreference(obj); | 1433 | drm_gem_object_unreference(obj); |
| @@ -1493,9 +1511,16 @@ i915_gem_object_truncate(struct drm_gem_object *obj) | |||
| 1493 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1511 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
| 1494 | struct inode *inode; | 1512 | struct inode *inode; |
| 1495 | 1513 | ||
| 1514 | /* Our goal here is to return as much of the memory as | ||
| 1515 | * is possible back to the system as we are called from OOM. | ||
| 1516 | * To do this we must instruct the shmfs to drop all of its | ||
| 1517 | * backing pages, *now*. Here we mirror the actions taken | ||
| 1518 | * when by shmem_delete_inode() to release the backing store. | ||
| 1519 | */ | ||
| 1496 | inode = obj->filp->f_path.dentry->d_inode; | 1520 | inode = obj->filp->f_path.dentry->d_inode; |
| 1497 | if (inode->i_op->truncate) | 1521 | truncate_inode_pages(inode->i_mapping, 0); |
| 1498 | inode->i_op->truncate (inode); | 1522 | if (inode->i_op->truncate_range) |
| 1523 | inode->i_op->truncate_range(inode, 0, (loff_t)-1); | ||
| 1499 | 1524 | ||
| 1500 | obj_priv->madv = __I915_MADV_PURGED; | 1525 | obj_priv->madv = __I915_MADV_PURGED; |
| 1501 | } | 1526 | } |
| @@ -1887,19 +1912,6 @@ i915_gem_flush(struct drm_device *dev, | |||
| 1887 | flush_domains); | 1912 | flush_domains); |
| 1888 | } | 1913 | } |
| 1889 | 1914 | ||
| 1890 | static void | ||
| 1891 | i915_gem_flush_ring(struct drm_device *dev, | ||
| 1892 | uint32_t invalidate_domains, | ||
| 1893 | uint32_t flush_domains, | ||
| 1894 | struct intel_ring_buffer *ring) | ||
| 1895 | { | ||
| 1896 | if (flush_domains & I915_GEM_DOMAIN_CPU) | ||
| 1897 | drm_agp_chipset_flush(dev); | ||
| 1898 | ring->flush(dev, ring, | ||
| 1899 | invalidate_domains, | ||
| 1900 | flush_domains); | ||
| 1901 | } | ||
| 1902 | |||
| 1903 | /** | 1915 | /** |
| 1904 | * Ensures that all rendering to the object has completed and the object is | 1916 | * Ensures that all rendering to the object has completed and the object is |
| 1905 | * safe to unbind from the GTT or access from the CPU. | 1917 | * safe to unbind from the GTT or access from the CPU. |
| @@ -1973,8 +1985,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
| 1973 | * cause memory corruption through use-after-free. | 1985 | * cause memory corruption through use-after-free. |
| 1974 | */ | 1986 | */ |
| 1975 | 1987 | ||
| 1976 | BUG_ON(obj_priv->active); | ||
| 1977 | |||
| 1978 | /* release the fence reg _after_ flushing */ | 1988 | /* release the fence reg _after_ flushing */ |
| 1979 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 1989 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
| 1980 | i915_gem_clear_fence_reg(obj); | 1990 | i915_gem_clear_fence_reg(obj); |
| @@ -2010,34 +2020,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
| 2010 | return ret; | 2020 | return ret; |
| 2011 | } | 2021 | } |
| 2012 | 2022 | ||
| 2013 | static struct drm_gem_object * | 2023 | int |
| 2014 | i915_gem_find_inactive_object(struct drm_device *dev, int min_size) | ||
| 2015 | { | ||
| 2016 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 2017 | struct drm_i915_gem_object *obj_priv; | ||
| 2018 | struct drm_gem_object *best = NULL; | ||
| 2019 | struct drm_gem_object *first = NULL; | ||
| 2020 | |||
| 2021 | /* Try to find the smallest clean object */ | ||
| 2022 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
| 2023 | struct drm_gem_object *obj = &obj_priv->base; | ||
| 2024 | if (obj->size >= min_size) { | ||
| 2025 | if ((!obj_priv->dirty || | ||
| 2026 | i915_gem_object_is_purgeable(obj_priv)) && | ||
| 2027 | (!best || obj->size < best->size)) { | ||
| 2028 | best = obj; | ||
| 2029 | if (best->size == min_size) | ||
| 2030 | return best; | ||
| 2031 | } | ||
| 2032 | if (!first) | ||
| 2033 | first = obj; | ||
| 2034 | } | ||
| 2035 | } | ||
| 2036 | |||
| 2037 | return best ? best : first; | ||
| 2038 | } | ||
| 2039 | |||
| 2040 | static int | ||
| 2041 | i915_gpu_idle(struct drm_device *dev) | 2024 | i915_gpu_idle(struct drm_device *dev) |
| 2042 | { | 2025 | { |
| 2043 | drm_i915_private_t *dev_priv = dev->dev_private; | 2026 | drm_i915_private_t *dev_priv = dev->dev_private; |
| @@ -2078,155 +2061,6 @@ i915_gpu_idle(struct drm_device *dev) | |||
| 2078 | return ret; | 2061 | return ret; |
| 2079 | } | 2062 | } |
| 2080 | 2063 | ||
| 2081 | static int | ||
| 2082 | i915_gem_evict_everything(struct drm_device *dev) | ||
| 2083 | { | ||
| 2084 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 2085 | int ret; | ||
| 2086 | bool lists_empty; | ||
| 2087 | |||
| 2088 | spin_lock(&dev_priv->mm.active_list_lock); | ||
| 2089 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
| 2090 | list_empty(&dev_priv->mm.flushing_list) && | ||
| 2091 | list_empty(&dev_priv->render_ring.active_list) && | ||
| 2092 | (!HAS_BSD(dev) | ||
| 2093 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
| 2094 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
| 2095 | |||
| 2096 | if (lists_empty) | ||
| 2097 | return -ENOSPC; | ||
| 2098 | |||
| 2099 | /* Flush everything (on to the inactive lists) and evict */ | ||
| 2100 | ret = i915_gpu_idle(dev); | ||
| 2101 | if (ret) | ||
| 2102 | return ret; | ||
| 2103 | |||
| 2104 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
| 2105 | |||
| 2106 | ret = i915_gem_evict_from_inactive_list(dev); | ||
| 2107 | if (ret) | ||
| 2108 | return ret; | ||
| 2109 | |||
| 2110 | spin_lock(&dev_priv->mm.active_list_lock); | ||
| 2111 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
| 2112 | list_empty(&dev_priv->mm.flushing_list) && | ||
| 2113 | list_empty(&dev_priv->render_ring.active_list) && | ||
| 2114 | (!HAS_BSD(dev) | ||
| 2115 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
| 2116 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
| 2117 | BUG_ON(!lists_empty); | ||
| 2118 | |||
| 2119 | return 0; | ||
| 2120 | } | ||
| 2121 | |||
| 2122 | static int | ||
| 2123 | i915_gem_evict_something(struct drm_device *dev, int min_size) | ||
| 2124 | { | ||
| 2125 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 2126 | struct drm_gem_object *obj; | ||
| 2127 | int ret; | ||
| 2128 | |||
| 2129 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | ||
| 2130 | struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; | ||
| 2131 | for (;;) { | ||
| 2132 | i915_gem_retire_requests(dev); | ||
| 2133 | |||
| 2134 | /* If there's an inactive buffer available now, grab it | ||
| 2135 | * and be done. | ||
| 2136 | */ | ||
| 2137 | obj = i915_gem_find_inactive_object(dev, min_size); | ||
| 2138 | if (obj) { | ||
| 2139 | struct drm_i915_gem_object *obj_priv; | ||
| 2140 | |||
| 2141 | #if WATCH_LRU | ||
| 2142 | DRM_INFO("%s: evicting %p\n", __func__, obj); | ||
| 2143 | #endif | ||
| 2144 | obj_priv = to_intel_bo(obj); | ||
| 2145 | BUG_ON(obj_priv->pin_count != 0); | ||
| 2146 | BUG_ON(obj_priv->active); | ||
| 2147 | |||
| 2148 | /* Wait on the rendering and unbind the buffer. */ | ||
| 2149 | return i915_gem_object_unbind(obj); | ||
| 2150 | } | ||
| 2151 | |||
| 2152 | /* If we didn't get anything, but the ring is still processing | ||
| 2153 | * things, wait for the next to finish and hopefully leave us | ||
| 2154 | * a buffer to evict. | ||
| 2155 | */ | ||
| 2156 | if (!list_empty(&render_ring->request_list)) { | ||
| 2157 | struct drm_i915_gem_request *request; | ||
| 2158 | |||
| 2159 | request = list_first_entry(&render_ring->request_list, | ||
| 2160 | struct drm_i915_gem_request, | ||
| 2161 | list); | ||
| 2162 | |||
| 2163 | ret = i915_wait_request(dev, | ||
| 2164 | request->seqno, request->ring); | ||
| 2165 | if (ret) | ||
| 2166 | return ret; | ||
| 2167 | |||
| 2168 | continue; | ||
| 2169 | } | ||
| 2170 | |||
| 2171 | if (HAS_BSD(dev) && !list_empty(&bsd_ring->request_list)) { | ||
| 2172 | struct drm_i915_gem_request *request; | ||
| 2173 | |||
| 2174 | request = list_first_entry(&bsd_ring->request_list, | ||
| 2175 | struct drm_i915_gem_request, | ||
| 2176 | list); | ||
| 2177 | |||
| 2178 | ret = i915_wait_request(dev, | ||
| 2179 | request->seqno, request->ring); | ||
| 2180 | if (ret) | ||
| 2181 | return ret; | ||
| 2182 | |||
| 2183 | continue; | ||
| 2184 | } | ||
| 2185 | |||
| 2186 | /* If we didn't have anything on the request list but there | ||
| 2187 | * are buffers awaiting a flush, emit one and try again. | ||
| 2188 | * When we wait on it, those buffers waiting for that flush | ||
| 2189 | * will get moved to inactive. | ||
| 2190 | */ | ||
| 2191 | if (!list_empty(&dev_priv->mm.flushing_list)) { | ||
| 2192 | struct drm_i915_gem_object *obj_priv; | ||
| 2193 | |||
| 2194 | /* Find an object that we can immediately reuse */ | ||
| 2195 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
| 2196 | obj = &obj_priv->base; | ||
| 2197 | if (obj->size >= min_size) | ||
| 2198 | break; | ||
| 2199 | |||
| 2200 | obj = NULL; | ||
| 2201 | } | ||
| 2202 | |||
| 2203 | if (obj != NULL) { | ||
| 2204 | uint32_t seqno; | ||
| 2205 | |||
| 2206 | i915_gem_flush_ring(dev, | ||
| 2207 | obj->write_domain, | ||
| 2208 | obj->write_domain, | ||
| 2209 | obj_priv->ring); | ||
| 2210 | seqno = i915_add_request(dev, NULL, | ||
| 2211 | obj->write_domain, | ||
| 2212 | obj_priv->ring); | ||
| 2213 | if (seqno == 0) | ||
| 2214 | return -ENOMEM; | ||
| 2215 | continue; | ||
| 2216 | } | ||
| 2217 | } | ||
| 2218 | |||
| 2219 | /* If we didn't do any of the above, there's no single buffer | ||
| 2220 | * large enough to swap out for the new one, so just evict | ||
| 2221 | * everything and start again. (This should be rare.) | ||
| 2222 | */ | ||
| 2223 | if (!list_empty (&dev_priv->mm.inactive_list)) | ||
| 2224 | return i915_gem_evict_from_inactive_list(dev); | ||
| 2225 | else | ||
| 2226 | return i915_gem_evict_everything(dev); | ||
| 2227 | } | ||
| 2228 | } | ||
| 2229 | |||
| 2230 | int | 2064 | int |
| 2231 | i915_gem_object_get_pages(struct drm_gem_object *obj, | 2065 | i915_gem_object_get_pages(struct drm_gem_object *obj, |
| 2232 | gfp_t gfpmask) | 2066 | gfp_t gfpmask) |
| @@ -2519,14 +2353,21 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
| 2519 | 2353 | ||
| 2520 | reg->obj = obj; | 2354 | reg->obj = obj; |
| 2521 | 2355 | ||
| 2522 | if (IS_GEN6(dev)) | 2356 | switch (INTEL_INFO(dev)->gen) { |
| 2357 | case 6: | ||
| 2523 | sandybridge_write_fence_reg(reg); | 2358 | sandybridge_write_fence_reg(reg); |
| 2524 | else if (IS_I965G(dev)) | 2359 | break; |
| 2360 | case 5: | ||
| 2361 | case 4: | ||
| 2525 | i965_write_fence_reg(reg); | 2362 | i965_write_fence_reg(reg); |
| 2526 | else if (IS_I9XX(dev)) | 2363 | break; |
| 2364 | case 3: | ||
| 2527 | i915_write_fence_reg(reg); | 2365 | i915_write_fence_reg(reg); |
| 2528 | else | 2366 | break; |
| 2367 | case 2: | ||
| 2529 | i830_write_fence_reg(reg); | 2368 | i830_write_fence_reg(reg); |
| 2369 | break; | ||
| 2370 | } | ||
| 2530 | 2371 | ||
| 2531 | trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, | 2372 | trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, |
| 2532 | obj_priv->tiling_mode); | 2373 | obj_priv->tiling_mode); |
| @@ -2549,22 +2390,26 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
| 2549 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2390 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
| 2550 | struct drm_i915_fence_reg *reg = | 2391 | struct drm_i915_fence_reg *reg = |
| 2551 | &dev_priv->fence_regs[obj_priv->fence_reg]; | 2392 | &dev_priv->fence_regs[obj_priv->fence_reg]; |
| 2393 | uint32_t fence_reg; | ||
| 2552 | 2394 | ||
| 2553 | if (IS_GEN6(dev)) { | 2395 | switch (INTEL_INFO(dev)->gen) { |
| 2396 | case 6: | ||
| 2554 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + | 2397 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + |
| 2555 | (obj_priv->fence_reg * 8), 0); | 2398 | (obj_priv->fence_reg * 8), 0); |
| 2556 | } else if (IS_I965G(dev)) { | 2399 | break; |
| 2400 | case 5: | ||
| 2401 | case 4: | ||
| 2557 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); | 2402 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); |
| 2558 | } else { | 2403 | break; |
| 2559 | uint32_t fence_reg; | 2404 | case 3: |
| 2560 | 2405 | if (obj_priv->fence_reg >= 8) | |
| 2561 | if (obj_priv->fence_reg < 8) | 2406 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4; |
| 2562 | fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; | ||
| 2563 | else | 2407 | else |
| 2564 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - | 2408 | case 2: |
| 2565 | 8) * 4; | 2409 | fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; |
| 2566 | 2410 | ||
| 2567 | I915_WRITE(fence_reg, 0); | 2411 | I915_WRITE(fence_reg, 0); |
| 2412 | break; | ||
| 2568 | } | 2413 | } |
| 2569 | 2414 | ||
| 2570 | reg->obj = NULL; | 2415 | reg->obj = NULL; |
| @@ -2666,7 +2511,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
| 2666 | #if WATCH_LRU | 2511 | #if WATCH_LRU |
| 2667 | DRM_INFO("%s: GTT full, evicting something\n", __func__); | 2512 | DRM_INFO("%s: GTT full, evicting something\n", __func__); |
| 2668 | #endif | 2513 | #endif |
| 2669 | ret = i915_gem_evict_something(dev, obj->size); | 2514 | ret = i915_gem_evict_something(dev, obj->size, alignment); |
| 2670 | if (ret) | 2515 | if (ret) |
| 2671 | return ret; | 2516 | return ret; |
| 2672 | 2517 | ||
| @@ -2684,7 +2529,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
| 2684 | 2529 | ||
| 2685 | if (ret == -ENOMEM) { | 2530 | if (ret == -ENOMEM) { |
| 2686 | /* first try to clear up some space from the GTT */ | 2531 | /* first try to clear up some space from the GTT */ |
| 2687 | ret = i915_gem_evict_something(dev, obj->size); | 2532 | ret = i915_gem_evict_something(dev, obj->size, |
| 2533 | alignment); | ||
| 2688 | if (ret) { | 2534 | if (ret) { |
| 2689 | /* now try to shrink everyone else */ | 2535 | /* now try to shrink everyone else */ |
| 2690 | if (gfpmask) { | 2536 | if (gfpmask) { |
| @@ -2714,7 +2560,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
| 2714 | drm_mm_put_block(obj_priv->gtt_space); | 2560 | drm_mm_put_block(obj_priv->gtt_space); |
| 2715 | obj_priv->gtt_space = NULL; | 2561 | obj_priv->gtt_space = NULL; |
| 2716 | 2562 | ||
| 2717 | ret = i915_gem_evict_something(dev, obj->size); | 2563 | ret = i915_gem_evict_something(dev, obj->size, alignment); |
| 2718 | if (ret) | 2564 | if (ret) |
| 2719 | return ret; | 2565 | return ret; |
| 2720 | 2566 | ||
| @@ -2723,6 +2569,9 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
| 2723 | atomic_inc(&dev->gtt_count); | 2569 | atomic_inc(&dev->gtt_count); |
| 2724 | atomic_add(obj->size, &dev->gtt_memory); | 2570 | atomic_add(obj->size, &dev->gtt_memory); |
| 2725 | 2571 | ||
| 2572 | /* keep track of bounds object by adding it to the inactive list */ | ||
| 2573 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
| 2574 | |||
| 2726 | /* Assert that the object is not currently in any GPU domain. As it | 2575 | /* Assert that the object is not currently in any GPU domain. As it |
| 2727 | * wasn't in the GTT, there shouldn't be any way it could have been in | 2576 | * wasn't in the GTT, there shouldn't be any way it could have been in |
| 2728 | * a GPU cache | 2577 | * a GPU cache |
| @@ -3117,6 +2966,7 @@ static void | |||
| 3117 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | 2966 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) |
| 3118 | { | 2967 | { |
| 3119 | struct drm_device *dev = obj->dev; | 2968 | struct drm_device *dev = obj->dev; |
| 2969 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 3120 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2970 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
| 3121 | uint32_t invalidate_domains = 0; | 2971 | uint32_t invalidate_domains = 0; |
| 3122 | uint32_t flush_domains = 0; | 2972 | uint32_t flush_domains = 0; |
| @@ -3179,6 +3029,13 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | |||
| 3179 | obj->pending_write_domain = obj->write_domain; | 3029 | obj->pending_write_domain = obj->write_domain; |
| 3180 | obj->read_domains = obj->pending_read_domains; | 3030 | obj->read_domains = obj->pending_read_domains; |
| 3181 | 3031 | ||
| 3032 | if (flush_domains & I915_GEM_GPU_DOMAINS) { | ||
| 3033 | if (obj_priv->ring == &dev_priv->render_ring) | ||
| 3034 | dev_priv->flush_rings |= FLUSH_RENDER_RING; | ||
| 3035 | else if (obj_priv->ring == &dev_priv->bsd_ring) | ||
| 3036 | dev_priv->flush_rings |= FLUSH_BSD_RING; | ||
| 3037 | } | ||
| 3038 | |||
| 3182 | dev->invalidate_domains |= invalidate_domains; | 3039 | dev->invalidate_domains |= invalidate_domains; |
| 3183 | dev->flush_domains |= flush_domains; | 3040 | dev->flush_domains |= flush_domains; |
| 3184 | #if WATCH_BUF | 3041 | #if WATCH_BUF |
| @@ -3403,6 +3260,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
| 3403 | (int) reloc->offset, | 3260 | (int) reloc->offset, |
| 3404 | reloc->read_domains, | 3261 | reloc->read_domains, |
| 3405 | reloc->write_domain); | 3262 | reloc->write_domain); |
| 3263 | drm_gem_object_unreference(target_obj); | ||
| 3264 | i915_gem_object_unpin(obj); | ||
| 3406 | return -EINVAL; | 3265 | return -EINVAL; |
| 3407 | } | 3266 | } |
| 3408 | if (reloc->write_domain & I915_GEM_DOMAIN_CPU || | 3267 | if (reloc->write_domain & I915_GEM_DOMAIN_CPU || |
| @@ -3718,7 +3577,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 3718 | ring = &dev_priv->render_ring; | 3577 | ring = &dev_priv->render_ring; |
| 3719 | } | 3578 | } |
| 3720 | 3579 | ||
| 3721 | |||
| 3722 | if (args->buffer_count < 1) { | 3580 | if (args->buffer_count < 1) { |
| 3723 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | 3581 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); |
| 3724 | return -EINVAL; | 3582 | return -EINVAL; |
| @@ -3746,6 +3604,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 3746 | if (ret != 0) { | 3604 | if (ret != 0) { |
| 3747 | DRM_ERROR("copy %d cliprects failed: %d\n", | 3605 | DRM_ERROR("copy %d cliprects failed: %d\n", |
| 3748 | args->num_cliprects, ret); | 3606 | args->num_cliprects, ret); |
| 3607 | ret = -EFAULT; | ||
| 3749 | goto pre_mutex_err; | 3608 | goto pre_mutex_err; |
| 3750 | } | 3609 | } |
| 3751 | } | 3610 | } |
| @@ -3892,6 +3751,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 3892 | */ | 3751 | */ |
| 3893 | dev->invalidate_domains = 0; | 3752 | dev->invalidate_domains = 0; |
| 3894 | dev->flush_domains = 0; | 3753 | dev->flush_domains = 0; |
| 3754 | dev_priv->flush_rings = 0; | ||
| 3895 | 3755 | ||
| 3896 | for (i = 0; i < args->buffer_count; i++) { | 3756 | for (i = 0; i < args->buffer_count; i++) { |
| 3897 | struct drm_gem_object *obj = object_list[i]; | 3757 | struct drm_gem_object *obj = object_list[i]; |
| @@ -3912,16 +3772,14 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 3912 | i915_gem_flush(dev, | 3772 | i915_gem_flush(dev, |
| 3913 | dev->invalidate_domains, | 3773 | dev->invalidate_domains, |
| 3914 | dev->flush_domains); | 3774 | dev->flush_domains); |
| 3915 | if (dev->flush_domains & I915_GEM_GPU_DOMAINS) { | 3775 | if (dev_priv->flush_rings & FLUSH_RENDER_RING) |
| 3916 | (void)i915_add_request(dev, file_priv, | 3776 | (void)i915_add_request(dev, file_priv, |
| 3917 | dev->flush_domains, | 3777 | dev->flush_domains, |
| 3918 | &dev_priv->render_ring); | 3778 | &dev_priv->render_ring); |
| 3919 | 3779 | if (dev_priv->flush_rings & FLUSH_BSD_RING) | |
| 3920 | if (HAS_BSD(dev)) | 3780 | (void)i915_add_request(dev, file_priv, |
| 3921 | (void)i915_add_request(dev, file_priv, | 3781 | dev->flush_domains, |
| 3922 | dev->flush_domains, | 3782 | &dev_priv->bsd_ring); |
| 3923 | &dev_priv->bsd_ring); | ||
| 3924 | } | ||
| 3925 | } | 3783 | } |
| 3926 | 3784 | ||
| 3927 | for (i = 0; i < args->buffer_count; i++) { | 3785 | for (i = 0; i < args->buffer_count; i++) { |
| @@ -4192,6 +4050,10 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
| 4192 | if (alignment == 0) | 4050 | if (alignment == 0) |
| 4193 | alignment = i915_gem_get_gtt_alignment(obj); | 4051 | alignment = i915_gem_get_gtt_alignment(obj); |
| 4194 | if (obj_priv->gtt_offset & (alignment - 1)) { | 4052 | if (obj_priv->gtt_offset & (alignment - 1)) { |
| 4053 | WARN(obj_priv->pin_count, | ||
| 4054 | "bo is already pinned with incorrect alignment:" | ||
| 4055 | " offset=%x, req.alignment=%x\n", | ||
| 4056 | obj_priv->gtt_offset, alignment); | ||
| 4195 | ret = i915_gem_object_unbind(obj); | 4057 | ret = i915_gem_object_unbind(obj); |
| 4196 | if (ret) | 4058 | if (ret) |
| 4197 | return ret; | 4059 | return ret; |
| @@ -4213,8 +4075,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
| 4213 | atomic_inc(&dev->pin_count); | 4075 | atomic_inc(&dev->pin_count); |
| 4214 | atomic_add(obj->size, &dev->pin_memory); | 4076 | atomic_add(obj->size, &dev->pin_memory); |
| 4215 | if (!obj_priv->active && | 4077 | if (!obj_priv->active && |
| 4216 | (obj->write_domain & I915_GEM_GPU_DOMAINS) == 0 && | 4078 | (obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) |
| 4217 | !list_empty(&obj_priv->list)) | ||
| 4218 | list_del_init(&obj_priv->list); | 4079 | list_del_init(&obj_priv->list); |
| 4219 | } | 4080 | } |
| 4220 | i915_verify_inactive(dev, __FILE__, __LINE__); | 4081 | i915_verify_inactive(dev, __FILE__, __LINE__); |
| @@ -4359,22 +4220,34 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
| 4359 | } | 4220 | } |
| 4360 | 4221 | ||
| 4361 | mutex_lock(&dev->struct_mutex); | 4222 | mutex_lock(&dev->struct_mutex); |
| 4362 | /* Update the active list for the hardware's current position. | ||
| 4363 | * Otherwise this only updates on a delayed timer or when irqs are | ||
| 4364 | * actually unmasked, and our working set ends up being larger than | ||
| 4365 | * required. | ||
| 4366 | */ | ||
| 4367 | i915_gem_retire_requests(dev); | ||
| 4368 | 4223 | ||
| 4369 | obj_priv = to_intel_bo(obj); | 4224 | /* Count all active objects as busy, even if they are currently not used |
| 4370 | /* Don't count being on the flushing list against the object being | 4225 | * by the gpu. Users of this interface expect objects to eventually |
| 4371 | * done. Otherwise, a buffer left on the flushing list but not getting | 4226 | * become non-busy without any further actions, therefore emit any |
| 4372 | * flushed (because nobody's flushing that domain) won't ever return | 4227 | * necessary flushes here. |
| 4373 | * unbusy and get reused by libdrm's bo cache. The other expected | ||
| 4374 | * consumer of this interface, OpenGL's occlusion queries, also specs | ||
| 4375 | * that the objects get unbusy "eventually" without any interference. | ||
| 4376 | */ | 4228 | */ |
| 4377 | args->busy = obj_priv->active && obj_priv->last_rendering_seqno != 0; | 4229 | obj_priv = to_intel_bo(obj); |
| 4230 | args->busy = obj_priv->active; | ||
| 4231 | if (args->busy) { | ||
| 4232 | /* Unconditionally flush objects, even when the gpu still uses this | ||
| 4233 | * object. Userspace calling this function indicates that it wants to | ||
| 4234 | * use this buffer rather sooner than later, so issuing the required | ||
| 4235 | * flush earlier is beneficial. | ||
| 4236 | */ | ||
| 4237 | if (obj->write_domain) { | ||
| 4238 | i915_gem_flush(dev, 0, obj->write_domain); | ||
| 4239 | (void)i915_add_request(dev, file_priv, obj->write_domain, obj_priv->ring); | ||
| 4240 | } | ||
| 4241 | |||
| 4242 | /* Update the active list for the hardware's current position. | ||
| 4243 | * Otherwise this only updates on a delayed timer or when irqs | ||
| 4244 | * are actually unmasked, and our working set ends up being | ||
| 4245 | * larger than required. | ||
| 4246 | */ | ||
| 4247 | i915_gem_retire_requests_ring(dev, obj_priv->ring); | ||
| 4248 | |||
| 4249 | args->busy = obj_priv->active; | ||
| 4250 | } | ||
| 4378 | 4251 | ||
| 4379 | drm_gem_object_unreference(obj); | 4252 | drm_gem_object_unreference(obj); |
| 4380 | mutex_unlock(&dev->struct_mutex); | 4253 | mutex_unlock(&dev->struct_mutex); |
| @@ -4514,30 +4387,6 @@ void i915_gem_free_object(struct drm_gem_object *obj) | |||
| 4514 | i915_gem_free_object_tail(obj); | 4387 | i915_gem_free_object_tail(obj); |
| 4515 | } | 4388 | } |
| 4516 | 4389 | ||
| 4517 | /** Unbinds all inactive objects. */ | ||
| 4518 | static int | ||
| 4519 | i915_gem_evict_from_inactive_list(struct drm_device *dev) | ||
| 4520 | { | ||
| 4521 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 4522 | |||
| 4523 | while (!list_empty(&dev_priv->mm.inactive_list)) { | ||
| 4524 | struct drm_gem_object *obj; | ||
| 4525 | int ret; | ||
| 4526 | |||
| 4527 | obj = &list_first_entry(&dev_priv->mm.inactive_list, | ||
| 4528 | struct drm_i915_gem_object, | ||
| 4529 | list)->base; | ||
| 4530 | |||
| 4531 | ret = i915_gem_object_unbind(obj); | ||
| 4532 | if (ret != 0) { | ||
| 4533 | DRM_ERROR("Error unbinding object: %d\n", ret); | ||
| 4534 | return ret; | ||
| 4535 | } | ||
| 4536 | } | ||
| 4537 | |||
| 4538 | return 0; | ||
| 4539 | } | ||
| 4540 | |||
| 4541 | int | 4390 | int |
| 4542 | i915_gem_idle(struct drm_device *dev) | 4391 | i915_gem_idle(struct drm_device *dev) |
| 4543 | { | 4392 | { |
| @@ -4562,7 +4411,7 @@ i915_gem_idle(struct drm_device *dev) | |||
| 4562 | 4411 | ||
| 4563 | /* Under UMS, be paranoid and evict. */ | 4412 | /* Under UMS, be paranoid and evict. */ |
| 4564 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { | 4413 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { |
| 4565 | ret = i915_gem_evict_from_inactive_list(dev); | 4414 | ret = i915_gem_evict_inactive(dev); |
| 4566 | if (ret) { | 4415 | if (ret) { |
| 4567 | mutex_unlock(&dev->struct_mutex); | 4416 | mutex_unlock(&dev->struct_mutex); |
| 4568 | return ret; | 4417 | return ret; |
| @@ -4680,6 +4529,8 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
| 4680 | goto cleanup_render_ring; | 4529 | goto cleanup_render_ring; |
| 4681 | } | 4530 | } |
| 4682 | 4531 | ||
| 4532 | dev_priv->next_seqno = 1; | ||
| 4533 | |||
| 4683 | return 0; | 4534 | return 0; |
| 4684 | 4535 | ||
| 4685 | cleanup_render_ring: | 4536 | cleanup_render_ring: |
| @@ -4841,7 +4692,7 @@ i915_gem_load(struct drm_device *dev) | |||
| 4841 | * e.g. for cursor + overlay regs | 4692 | * e.g. for cursor + overlay regs |
| 4842 | */ | 4693 | */ |
| 4843 | int i915_gem_init_phys_object(struct drm_device *dev, | 4694 | int i915_gem_init_phys_object(struct drm_device *dev, |
| 4844 | int id, int size) | 4695 | int id, int size, int align) |
| 4845 | { | 4696 | { |
| 4846 | drm_i915_private_t *dev_priv = dev->dev_private; | 4697 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 4847 | struct drm_i915_gem_phys_object *phys_obj; | 4698 | struct drm_i915_gem_phys_object *phys_obj; |
| @@ -4856,7 +4707,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, | |||
| 4856 | 4707 | ||
| 4857 | phys_obj->id = id; | 4708 | phys_obj->id = id; |
| 4858 | 4709 | ||
| 4859 | phys_obj->handle = drm_pci_alloc(dev, size, 0); | 4710 | phys_obj->handle = drm_pci_alloc(dev, size, align); |
| 4860 | if (!phys_obj->handle) { | 4711 | if (!phys_obj->handle) { |
| 4861 | ret = -ENOMEM; | 4712 | ret = -ENOMEM; |
| 4862 | goto kfree_obj; | 4713 | goto kfree_obj; |
| @@ -4938,7 +4789,9 @@ out: | |||
| 4938 | 4789 | ||
| 4939 | int | 4790 | int |
| 4940 | i915_gem_attach_phys_object(struct drm_device *dev, | 4791 | i915_gem_attach_phys_object(struct drm_device *dev, |
| 4941 | struct drm_gem_object *obj, int id) | 4792 | struct drm_gem_object *obj, |
| 4793 | int id, | ||
| 4794 | int align) | ||
| 4942 | { | 4795 | { |
| 4943 | drm_i915_private_t *dev_priv = dev->dev_private; | 4796 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 4944 | struct drm_i915_gem_object *obj_priv; | 4797 | struct drm_i915_gem_object *obj_priv; |
| @@ -4957,11 +4810,10 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
| 4957 | i915_gem_detach_phys_object(dev, obj); | 4810 | i915_gem_detach_phys_object(dev, obj); |
| 4958 | } | 4811 | } |
| 4959 | 4812 | ||
| 4960 | |||
| 4961 | /* create a new object */ | 4813 | /* create a new object */ |
| 4962 | if (!dev_priv->mm.phys_objs[id - 1]) { | 4814 | if (!dev_priv->mm.phys_objs[id - 1]) { |
| 4963 | ret = i915_gem_init_phys_object(dev, id, | 4815 | ret = i915_gem_init_phys_object(dev, id, |
| 4964 | obj->size); | 4816 | obj->size, align); |
| 4965 | if (ret) { | 4817 | if (ret) { |
| 4966 | DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); | 4818 | DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); |
| 4967 | goto out; | 4819 | goto out; |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c new file mode 100644 index 000000000000..5c428fa3e0b3 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
| @@ -0,0 +1,271 @@ | |||
| 1 | /* | ||
| 2 | * Copyright © 2008-2010 Intel Corporation | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice (including the next | ||
| 12 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 13 | * Software. | ||
| 14 | * | ||
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| 21 | * IN THE SOFTWARE. | ||
| 22 | * | ||
| 23 | * Authors: | ||
| 24 | * Eric Anholt <eric@anholt.net> | ||
| 25 | * Chris Wilson <chris@chris-wilson.co.uuk> | ||
| 26 | * | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include "drmP.h" | ||
| 30 | #include "drm.h" | ||
| 31 | #include "i915_drv.h" | ||
| 32 | #include "i915_drm.h" | ||
| 33 | |||
| 34 | static struct drm_i915_gem_object * | ||
| 35 | i915_gem_next_active_object(struct drm_device *dev, | ||
| 36 | struct list_head **render_iter, | ||
| 37 | struct list_head **bsd_iter) | ||
| 38 | { | ||
| 39 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 40 | struct drm_i915_gem_object *render_obj = NULL, *bsd_obj = NULL; | ||
| 41 | |||
| 42 | if (*render_iter != &dev_priv->render_ring.active_list) | ||
| 43 | render_obj = list_entry(*render_iter, | ||
| 44 | struct drm_i915_gem_object, | ||
| 45 | list); | ||
| 46 | |||
| 47 | if (HAS_BSD(dev)) { | ||
| 48 | if (*bsd_iter != &dev_priv->bsd_ring.active_list) | ||
| 49 | bsd_obj = list_entry(*bsd_iter, | ||
| 50 | struct drm_i915_gem_object, | ||
| 51 | list); | ||
| 52 | |||
| 53 | if (render_obj == NULL) { | ||
| 54 | *bsd_iter = (*bsd_iter)->next; | ||
| 55 | return bsd_obj; | ||
| 56 | } | ||
| 57 | |||
| 58 | if (bsd_obj == NULL) { | ||
| 59 | *render_iter = (*render_iter)->next; | ||
| 60 | return render_obj; | ||
| 61 | } | ||
| 62 | |||
| 63 | /* XXX can we handle seqno wrapping? */ | ||
| 64 | if (render_obj->last_rendering_seqno < bsd_obj->last_rendering_seqno) { | ||
| 65 | *render_iter = (*render_iter)->next; | ||
| 66 | return render_obj; | ||
| 67 | } else { | ||
| 68 | *bsd_iter = (*bsd_iter)->next; | ||
| 69 | return bsd_obj; | ||
| 70 | } | ||
| 71 | } else { | ||
| 72 | *render_iter = (*render_iter)->next; | ||
| 73 | return render_obj; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | static bool | ||
| 78 | mark_free(struct drm_i915_gem_object *obj_priv, | ||
| 79 | struct list_head *unwind) | ||
| 80 | { | ||
| 81 | list_add(&obj_priv->evict_list, unwind); | ||
| 82 | drm_gem_object_reference(&obj_priv->base); | ||
| 83 | return drm_mm_scan_add_block(obj_priv->gtt_space); | ||
| 84 | } | ||
| 85 | |||
| 86 | #define i915_for_each_active_object(OBJ, R, B) \ | ||
| 87 | *(R) = dev_priv->render_ring.active_list.next; \ | ||
| 88 | *(B) = dev_priv->bsd_ring.active_list.next; \ | ||
| 89 | while (((OBJ) = i915_gem_next_active_object(dev, (R), (B))) != NULL) | ||
| 90 | |||
| 91 | int | ||
| 92 | i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment) | ||
| 93 | { | ||
| 94 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 95 | struct list_head eviction_list, unwind_list; | ||
| 96 | struct drm_i915_gem_object *obj_priv; | ||
| 97 | struct list_head *render_iter, *bsd_iter; | ||
| 98 | int ret = 0; | ||
| 99 | |||
| 100 | i915_gem_retire_requests(dev); | ||
| 101 | |||
| 102 | /* Re-check for free space after retiring requests */ | ||
| 103 | if (drm_mm_search_free(&dev_priv->mm.gtt_space, | ||
| 104 | min_size, alignment, 0)) | ||
| 105 | return 0; | ||
| 106 | |||
| 107 | /* | ||
| 108 | * The goal is to evict objects and amalgamate space in LRU order. | ||
| 109 | * The oldest idle objects reside on the inactive list, which is in | ||
| 110 | * retirement order. The next objects to retire are those on the (per | ||
| 111 | * ring) active list that do not have an outstanding flush. Once the | ||
| 112 | * hardware reports completion (the seqno is updated after the | ||
| 113 | * batchbuffer has been finished) the clean buffer objects would | ||
| 114 | * be retired to the inactive list. Any dirty objects would be added | ||
| 115 | * to the tail of the flushing list. So after processing the clean | ||
| 116 | * active objects we need to emit a MI_FLUSH to retire the flushing | ||
| 117 | * list, hence the retirement order of the flushing list is in | ||
| 118 | * advance of the dirty objects on the active lists. | ||
| 119 | * | ||
| 120 | * The retirement sequence is thus: | ||
| 121 | * 1. Inactive objects (already retired) | ||
| 122 | * 2. Clean active objects | ||
| 123 | * 3. Flushing list | ||
| 124 | * 4. Dirty active objects. | ||
| 125 | * | ||
| 126 | * On each list, the oldest objects lie at the HEAD with the freshest | ||
| 127 | * object on the TAIL. | ||
| 128 | */ | ||
| 129 | |||
| 130 | INIT_LIST_HEAD(&unwind_list); | ||
| 131 | drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); | ||
| 132 | |||
| 133 | /* First see if there is a large enough contiguous idle region... */ | ||
| 134 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
| 135 | if (mark_free(obj_priv, &unwind_list)) | ||
| 136 | goto found; | ||
| 137 | } | ||
| 138 | |||
| 139 | /* Now merge in the soon-to-be-expired objects... */ | ||
| 140 | i915_for_each_active_object(obj_priv, &render_iter, &bsd_iter) { | ||
| 141 | /* Does the object require an outstanding flush? */ | ||
| 142 | if (obj_priv->base.write_domain || obj_priv->pin_count) | ||
| 143 | continue; | ||
| 144 | |||
| 145 | if (mark_free(obj_priv, &unwind_list)) | ||
| 146 | goto found; | ||
| 147 | } | ||
| 148 | |||
| 149 | /* Finally add anything with a pending flush (in order of retirement) */ | ||
| 150 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
| 151 | if (obj_priv->pin_count) | ||
| 152 | continue; | ||
| 153 | |||
| 154 | if (mark_free(obj_priv, &unwind_list)) | ||
| 155 | goto found; | ||
| 156 | } | ||
| 157 | i915_for_each_active_object(obj_priv, &render_iter, &bsd_iter) { | ||
| 158 | if (! obj_priv->base.write_domain || obj_priv->pin_count) | ||
| 159 | continue; | ||
| 160 | |||
| 161 | if (mark_free(obj_priv, &unwind_list)) | ||
| 162 | goto found; | ||
| 163 | } | ||
| 164 | |||
| 165 | /* Nothing found, clean up and bail out! */ | ||
| 166 | list_for_each_entry(obj_priv, &unwind_list, evict_list) { | ||
| 167 | ret = drm_mm_scan_remove_block(obj_priv->gtt_space); | ||
| 168 | BUG_ON(ret); | ||
| 169 | drm_gem_object_unreference(&obj_priv->base); | ||
| 170 | } | ||
| 171 | |||
| 172 | /* We expect the caller to unpin, evict all and try again, or give up. | ||
| 173 | * So calling i915_gem_evict_everything() is unnecessary. | ||
| 174 | */ | ||
| 175 | return -ENOSPC; | ||
| 176 | |||
| 177 | found: | ||
| 178 | /* drm_mm doesn't allow any other other operations while | ||
| 179 | * scanning, therefore store to be evicted objects on a | ||
| 180 | * temporary list. */ | ||
| 181 | INIT_LIST_HEAD(&eviction_list); | ||
| 182 | while (!list_empty(&unwind_list)) { | ||
| 183 | obj_priv = list_first_entry(&unwind_list, | ||
| 184 | struct drm_i915_gem_object, | ||
| 185 | evict_list); | ||
| 186 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { | ||
| 187 | list_move(&obj_priv->evict_list, &eviction_list); | ||
| 188 | continue; | ||
| 189 | } | ||
| 190 | list_del(&obj_priv->evict_list); | ||
| 191 | drm_gem_object_unreference(&obj_priv->base); | ||
| 192 | } | ||
| 193 | |||
| 194 | /* Unbinding will emit any required flushes */ | ||
| 195 | while (!list_empty(&eviction_list)) { | ||
| 196 | obj_priv = list_first_entry(&eviction_list, | ||
| 197 | struct drm_i915_gem_object, | ||
| 198 | evict_list); | ||
| 199 | if (ret == 0) | ||
| 200 | ret = i915_gem_object_unbind(&obj_priv->base); | ||
| 201 | list_del(&obj_priv->evict_list); | ||
| 202 | drm_gem_object_unreference(&obj_priv->base); | ||
| 203 | } | ||
| 204 | |||
| 205 | return ret; | ||
| 206 | } | ||
| 207 | |||
| 208 | int | ||
| 209 | i915_gem_evict_everything(struct drm_device *dev) | ||
| 210 | { | ||
| 211 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 212 | int ret; | ||
| 213 | bool lists_empty; | ||
| 214 | |||
| 215 | spin_lock(&dev_priv->mm.active_list_lock); | ||
| 216 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
| 217 | list_empty(&dev_priv->mm.flushing_list) && | ||
| 218 | list_empty(&dev_priv->render_ring.active_list) && | ||
| 219 | (!HAS_BSD(dev) | ||
| 220 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
| 221 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
| 222 | |||
| 223 | if (lists_empty) | ||
| 224 | return -ENOSPC; | ||
| 225 | |||
| 226 | /* Flush everything (on to the inactive lists) and evict */ | ||
| 227 | ret = i915_gpu_idle(dev); | ||
| 228 | if (ret) | ||
| 229 | return ret; | ||
| 230 | |||
| 231 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
| 232 | |||
| 233 | ret = i915_gem_evict_inactive(dev); | ||
| 234 | if (ret) | ||
| 235 | return ret; | ||
| 236 | |||
| 237 | spin_lock(&dev_priv->mm.active_list_lock); | ||
| 238 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
| 239 | list_empty(&dev_priv->mm.flushing_list) && | ||
| 240 | list_empty(&dev_priv->render_ring.active_list) && | ||
| 241 | (!HAS_BSD(dev) | ||
| 242 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
| 243 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
| 244 | BUG_ON(!lists_empty); | ||
| 245 | |||
| 246 | return 0; | ||
| 247 | } | ||
| 248 | |||
| 249 | /** Unbinds all inactive objects. */ | ||
| 250 | int | ||
| 251 | i915_gem_evict_inactive(struct drm_device *dev) | ||
| 252 | { | ||
| 253 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 254 | |||
| 255 | while (!list_empty(&dev_priv->mm.inactive_list)) { | ||
| 256 | struct drm_gem_object *obj; | ||
| 257 | int ret; | ||
| 258 | |||
| 259 | obj = &list_first_entry(&dev_priv->mm.inactive_list, | ||
| 260 | struct drm_i915_gem_object, | ||
| 261 | list)->base; | ||
| 262 | |||
| 263 | ret = i915_gem_object_unbind(obj); | ||
| 264 | if (ret != 0) { | ||
| 265 | DRM_ERROR("Error unbinding object: %d\n", ret); | ||
| 266 | return ret; | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | return 0; | ||
| 271 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 85785a8844ed..744225ebb4b2 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -425,9 +425,11 @@ static struct drm_i915_error_object * | |||
| 425 | i915_error_object_create(struct drm_device *dev, | 425 | i915_error_object_create(struct drm_device *dev, |
| 426 | struct drm_gem_object *src) | 426 | struct drm_gem_object *src) |
| 427 | { | 427 | { |
| 428 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 428 | struct drm_i915_error_object *dst; | 429 | struct drm_i915_error_object *dst; |
| 429 | struct drm_i915_gem_object *src_priv; | 430 | struct drm_i915_gem_object *src_priv; |
| 430 | int page, page_count; | 431 | int page, page_count; |
| 432 | u32 reloc_offset; | ||
| 431 | 433 | ||
| 432 | if (src == NULL) | 434 | if (src == NULL) |
| 433 | return NULL; | 435 | return NULL; |
| @@ -442,18 +444,27 @@ i915_error_object_create(struct drm_device *dev, | |||
| 442 | if (dst == NULL) | 444 | if (dst == NULL) |
| 443 | return NULL; | 445 | return NULL; |
| 444 | 446 | ||
| 447 | reloc_offset = src_priv->gtt_offset; | ||
| 445 | for (page = 0; page < page_count; page++) { | 448 | for (page = 0; page < page_count; page++) { |
| 446 | void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | ||
| 447 | unsigned long flags; | 449 | unsigned long flags; |
| 450 | void __iomem *s; | ||
| 451 | void *d; | ||
| 448 | 452 | ||
| 453 | d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | ||
| 449 | if (d == NULL) | 454 | if (d == NULL) |
| 450 | goto unwind; | 455 | goto unwind; |
| 456 | |||
| 451 | local_irq_save(flags); | 457 | local_irq_save(flags); |
| 452 | s = kmap_atomic(src_priv->pages[page], KM_IRQ0); | 458 | s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, |
| 453 | memcpy(d, s, PAGE_SIZE); | 459 | reloc_offset, |
| 454 | kunmap_atomic(s, KM_IRQ0); | 460 | KM_IRQ0); |
| 461 | memcpy_fromio(d, s, PAGE_SIZE); | ||
| 462 | io_mapping_unmap_atomic(s, KM_IRQ0); | ||
| 455 | local_irq_restore(flags); | 463 | local_irq_restore(flags); |
| 464 | |||
| 456 | dst->pages[page] = d; | 465 | dst->pages[page] = d; |
| 466 | |||
| 467 | reloc_offset += PAGE_SIZE; | ||
| 457 | } | 468 | } |
| 458 | dst->page_count = page_count; | 469 | dst->page_count = page_count; |
| 459 | dst->gtt_offset = src_priv->gtt_offset; | 470 | dst->gtt_offset = src_priv->gtt_offset; |
| @@ -489,6 +500,7 @@ i915_error_state_free(struct drm_device *dev, | |||
| 489 | i915_error_object_free(error->batchbuffer[1]); | 500 | i915_error_object_free(error->batchbuffer[1]); |
| 490 | i915_error_object_free(error->ringbuffer); | 501 | i915_error_object_free(error->ringbuffer); |
| 491 | kfree(error->active_bo); | 502 | kfree(error->active_bo); |
| 503 | kfree(error->overlay); | ||
| 492 | kfree(error); | 504 | kfree(error); |
| 493 | } | 505 | } |
| 494 | 506 | ||
| @@ -612,18 +624,57 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
| 612 | 624 | ||
| 613 | if (batchbuffer[1] == NULL && | 625 | if (batchbuffer[1] == NULL && |
| 614 | error->acthd >= obj_priv->gtt_offset && | 626 | error->acthd >= obj_priv->gtt_offset && |
| 615 | error->acthd < obj_priv->gtt_offset + obj->size && | 627 | error->acthd < obj_priv->gtt_offset + obj->size) |
| 616 | batchbuffer[0] != obj) | ||
| 617 | batchbuffer[1] = obj; | 628 | batchbuffer[1] = obj; |
| 618 | 629 | ||
| 619 | count++; | 630 | count++; |
| 620 | } | 631 | } |
| 632 | /* Scan the other lists for completeness for those bizarre errors. */ | ||
| 633 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | ||
| 634 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
| 635 | struct drm_gem_object *obj = &obj_priv->base; | ||
| 636 | |||
| 637 | if (batchbuffer[0] == NULL && | ||
| 638 | bbaddr >= obj_priv->gtt_offset && | ||
| 639 | bbaddr < obj_priv->gtt_offset + obj->size) | ||
| 640 | batchbuffer[0] = obj; | ||
| 641 | |||
| 642 | if (batchbuffer[1] == NULL && | ||
| 643 | error->acthd >= obj_priv->gtt_offset && | ||
| 644 | error->acthd < obj_priv->gtt_offset + obj->size) | ||
| 645 | batchbuffer[1] = obj; | ||
| 646 | |||
| 647 | if (batchbuffer[0] && batchbuffer[1]) | ||
| 648 | break; | ||
| 649 | } | ||
| 650 | } | ||
| 651 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | ||
| 652 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
| 653 | struct drm_gem_object *obj = &obj_priv->base; | ||
| 654 | |||
| 655 | if (batchbuffer[0] == NULL && | ||
| 656 | bbaddr >= obj_priv->gtt_offset && | ||
| 657 | bbaddr < obj_priv->gtt_offset + obj->size) | ||
| 658 | batchbuffer[0] = obj; | ||
| 659 | |||
| 660 | if (batchbuffer[1] == NULL && | ||
| 661 | error->acthd >= obj_priv->gtt_offset && | ||
| 662 | error->acthd < obj_priv->gtt_offset + obj->size) | ||
| 663 | batchbuffer[1] = obj; | ||
| 664 | |||
| 665 | if (batchbuffer[0] && batchbuffer[1]) | ||
| 666 | break; | ||
| 667 | } | ||
| 668 | } | ||
| 621 | 669 | ||
| 622 | /* We need to copy these to an anonymous buffer as the simplest | 670 | /* We need to copy these to an anonymous buffer as the simplest |
| 623 | * method to avoid being overwritten by userpace. | 671 | * method to avoid being overwritten by userpace. |
| 624 | */ | 672 | */ |
| 625 | error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); | 673 | error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); |
| 626 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); | 674 | if (batchbuffer[1] != batchbuffer[0]) |
| 675 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); | ||
| 676 | else | ||
| 677 | error->batchbuffer[1] = NULL; | ||
| 627 | 678 | ||
| 628 | /* Record the ringbuffer */ | 679 | /* Record the ringbuffer */ |
| 629 | error->ringbuffer = i915_error_object_create(dev, | 680 | error->ringbuffer = i915_error_object_create(dev, |
| @@ -667,6 +718,8 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
| 667 | 718 | ||
| 668 | do_gettimeofday(&error->time); | 719 | do_gettimeofday(&error->time); |
| 669 | 720 | ||
| 721 | error->overlay = intel_overlay_capture_error_state(dev); | ||
| 722 | |||
| 670 | spin_lock_irqsave(&dev_priv->error_lock, flags); | 723 | spin_lock_irqsave(&dev_priv->error_lock, flags); |
| 671 | if (dev_priv->first_error == NULL) { | 724 | if (dev_priv->first_error == NULL) { |
| 672 | dev_priv->first_error = error; | 725 | dev_priv->first_error = error; |
| @@ -834,6 +887,49 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) | |||
| 834 | queue_work(dev_priv->wq, &dev_priv->error_work); | 887 | queue_work(dev_priv->wq, &dev_priv->error_work); |
| 835 | } | 888 | } |
| 836 | 889 | ||
| 890 | static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) | ||
| 891 | { | ||
| 892 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 893 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | ||
| 894 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 895 | struct drm_i915_gem_object *obj_priv; | ||
| 896 | struct intel_unpin_work *work; | ||
| 897 | unsigned long flags; | ||
| 898 | bool stall_detected; | ||
| 899 | |||
| 900 | /* Ignore early vblank irqs */ | ||
| 901 | if (intel_crtc == NULL) | ||
| 902 | return; | ||
| 903 | |||
| 904 | spin_lock_irqsave(&dev->event_lock, flags); | ||
| 905 | work = intel_crtc->unpin_work; | ||
| 906 | |||
| 907 | if (work == NULL || work->pending || !work->enable_stall_check) { | ||
| 908 | /* Either the pending flip IRQ arrived, or we're too early. Don't check */ | ||
| 909 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 910 | return; | ||
| 911 | } | ||
| 912 | |||
| 913 | /* Potential stall - if we see that the flip has happened, assume a missed interrupt */ | ||
| 914 | obj_priv = to_intel_bo(work->pending_flip_obj); | ||
| 915 | if(IS_I965G(dev)) { | ||
| 916 | int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF; | ||
| 917 | stall_detected = I915_READ(dspsurf) == obj_priv->gtt_offset; | ||
| 918 | } else { | ||
| 919 | int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR; | ||
| 920 | stall_detected = I915_READ(dspaddr) == (obj_priv->gtt_offset + | ||
| 921 | crtc->y * crtc->fb->pitch + | ||
| 922 | crtc->x * crtc->fb->bits_per_pixel/8); | ||
| 923 | } | ||
| 924 | |||
| 925 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 926 | |||
| 927 | if (stall_detected) { | ||
| 928 | DRM_DEBUG_DRIVER("Pageflip stall detected\n"); | ||
| 929 | intel_prepare_page_flip(dev, intel_crtc->plane); | ||
| 930 | } | ||
| 931 | } | ||
| 932 | |||
| 837 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 933 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
| 838 | { | 934 | { |
| 839 | struct drm_device *dev = (struct drm_device *) arg; | 935 | struct drm_device *dev = (struct drm_device *) arg; |
| @@ -951,15 +1047,19 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
| 951 | if (pipea_stats & vblank_status) { | 1047 | if (pipea_stats & vblank_status) { |
| 952 | vblank++; | 1048 | vblank++; |
| 953 | drm_handle_vblank(dev, 0); | 1049 | drm_handle_vblank(dev, 0); |
| 954 | if (!dev_priv->flip_pending_is_done) | 1050 | if (!dev_priv->flip_pending_is_done) { |
| 1051 | i915_pageflip_stall_check(dev, 0); | ||
| 955 | intel_finish_page_flip(dev, 0); | 1052 | intel_finish_page_flip(dev, 0); |
| 1053 | } | ||
| 956 | } | 1054 | } |
| 957 | 1055 | ||
| 958 | if (pipeb_stats & vblank_status) { | 1056 | if (pipeb_stats & vblank_status) { |
| 959 | vblank++; | 1057 | vblank++; |
| 960 | drm_handle_vblank(dev, 1); | 1058 | drm_handle_vblank(dev, 1); |
| 961 | if (!dev_priv->flip_pending_is_done) | 1059 | if (!dev_priv->flip_pending_is_done) { |
| 1060 | i915_pageflip_stall_check(dev, 1); | ||
| 962 | intel_finish_page_flip(dev, 1); | 1061 | intel_finish_page_flip(dev, 1); |
| 1062 | } | ||
| 963 | } | 1063 | } |
| 964 | 1064 | ||
| 965 | if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || | 1065 | if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || |
| @@ -1250,7 +1350,25 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
| 1250 | i915_seqno_passed(i915_get_gem_seqno(dev, | 1350 | i915_seqno_passed(i915_get_gem_seqno(dev, |
| 1251 | &dev_priv->render_ring), | 1351 | &dev_priv->render_ring), |
| 1252 | i915_get_tail_request(dev)->seqno)) { | 1352 | i915_get_tail_request(dev)->seqno)) { |
| 1353 | bool missed_wakeup = false; | ||
| 1354 | |||
| 1253 | dev_priv->hangcheck_count = 0; | 1355 | dev_priv->hangcheck_count = 0; |
| 1356 | |||
| 1357 | /* Issue a wake-up to catch stuck h/w. */ | ||
| 1358 | if (dev_priv->render_ring.waiting_gem_seqno && | ||
| 1359 | waitqueue_active(&dev_priv->render_ring.irq_queue)) { | ||
| 1360 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); | ||
| 1361 | missed_wakeup = true; | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | if (dev_priv->bsd_ring.waiting_gem_seqno && | ||
| 1365 | waitqueue_active(&dev_priv->bsd_ring.irq_queue)) { | ||
| 1366 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | ||
| 1367 | missed_wakeup = true; | ||
| 1368 | } | ||
| 1369 | |||
| 1370 | if (missed_wakeup) | ||
| 1371 | DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n"); | ||
| 1254 | return; | 1372 | return; |
| 1255 | } | 1373 | } |
| 1256 | 1374 | ||
| @@ -1318,12 +1436,17 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
| 1318 | I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); | 1436 | I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); |
| 1319 | (void) I915_READ(DEIER); | 1437 | (void) I915_READ(DEIER); |
| 1320 | 1438 | ||
| 1321 | /* user interrupt should be enabled, but masked initial */ | 1439 | /* Gen6 only needs render pipe_control now */ |
| 1440 | if (IS_GEN6(dev)) | ||
| 1441 | render_mask = GT_PIPE_NOTIFY; | ||
| 1442 | |||
| 1322 | dev_priv->gt_irq_mask_reg = ~render_mask; | 1443 | dev_priv->gt_irq_mask_reg = ~render_mask; |
| 1323 | dev_priv->gt_irq_enable_reg = render_mask; | 1444 | dev_priv->gt_irq_enable_reg = render_mask; |
| 1324 | 1445 | ||
| 1325 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1446 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
| 1326 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); | 1447 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); |
| 1448 | if (IS_GEN6(dev)) | ||
| 1449 | I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT); | ||
| 1327 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); | 1450 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); |
| 1328 | (void) I915_READ(GTIER); | 1451 | (void) I915_READ(GTIER); |
| 1329 | 1452 | ||
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index d1bf92b99788..ea5d3fea4b61 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c | |||
| @@ -114,10 +114,6 @@ struct opregion_asle { | |||
| 114 | #define ASLE_REQ_MSK 0xf | 114 | #define ASLE_REQ_MSK 0xf |
| 115 | 115 | ||
| 116 | /* response bits of ASLE irq request */ | 116 | /* response bits of ASLE irq request */ |
| 117 | #define ASLE_ALS_ILLUM_FAIL (2<<10) | ||
| 118 | #define ASLE_BACKLIGHT_FAIL (2<<12) | ||
| 119 | #define ASLE_PFIT_FAIL (2<<14) | ||
| 120 | #define ASLE_PWM_FREQ_FAIL (2<<16) | ||
| 121 | #define ASLE_ALS_ILLUM_FAILED (1<<10) | 117 | #define ASLE_ALS_ILLUM_FAILED (1<<10) |
| 122 | #define ASLE_BACKLIGHT_FAILED (1<<12) | 118 | #define ASLE_BACKLIGHT_FAILED (1<<12) |
| 123 | #define ASLE_PFIT_FAILED (1<<14) | 119 | #define ASLE_PFIT_FAILED (1<<14) |
| @@ -155,11 +151,11 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | |||
| 155 | u32 max_backlight, level, shift; | 151 | u32 max_backlight, level, shift; |
| 156 | 152 | ||
| 157 | if (!(bclp & ASLE_BCLP_VALID)) | 153 | if (!(bclp & ASLE_BCLP_VALID)) |
| 158 | return ASLE_BACKLIGHT_FAIL; | 154 | return ASLE_BACKLIGHT_FAILED; |
| 159 | 155 | ||
| 160 | bclp &= ASLE_BCLP_MSK; | 156 | bclp &= ASLE_BCLP_MSK; |
| 161 | if (bclp < 0 || bclp > 255) | 157 | if (bclp < 0 || bclp > 255) |
| 162 | return ASLE_BACKLIGHT_FAIL; | 158 | return ASLE_BACKLIGHT_FAILED; |
| 163 | 159 | ||
| 164 | blc_pwm_ctl = I915_READ(BLC_PWM_CTL); | 160 | blc_pwm_ctl = I915_READ(BLC_PWM_CTL); |
| 165 | blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); | 161 | blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); |
| @@ -211,7 +207,7 @@ static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) | |||
| 211 | /* Panel fitting is currently controlled by the X code, so this is a | 207 | /* Panel fitting is currently controlled by the X code, so this is a |
| 212 | noop until modesetting support works fully */ | 208 | noop until modesetting support works fully */ |
| 213 | if (!(pfit & ASLE_PFIT_VALID)) | 209 | if (!(pfit & ASLE_PFIT_VALID)) |
| 214 | return ASLE_PFIT_FAIL; | 210 | return ASLE_PFIT_FAILED; |
| 215 | return 0; | 211 | return 0; |
| 216 | } | 212 | } |
| 217 | 213 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 281db6e5403a..4f5e15577e89 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -170,6 +170,7 @@ | |||
| 170 | #define MI_NO_WRITE_FLUSH (1 << 2) | 170 | #define MI_NO_WRITE_FLUSH (1 << 2) |
| 171 | #define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ | 171 | #define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ |
| 172 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ | 172 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ |
| 173 | #define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */ | ||
| 173 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) | 174 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) |
| 174 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) | 175 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) |
| 175 | #define MI_OVERLAY_FLIP MI_INSTR(0x11,0) | 176 | #define MI_OVERLAY_FLIP MI_INSTR(0x11,0) |
| @@ -180,6 +181,12 @@ | |||
| 180 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) | 181 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) |
| 181 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) | 182 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) |
| 182 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) | 183 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) |
| 184 | #define MI_SET_CONTEXT MI_INSTR(0x18, 0) | ||
| 185 | #define MI_MM_SPACE_GTT (1<<8) | ||
| 186 | #define MI_MM_SPACE_PHYSICAL (0<<8) | ||
| 187 | #define MI_SAVE_EXT_STATE_EN (1<<3) | ||
| 188 | #define MI_RESTORE_EXT_STATE_EN (1<<2) | ||
| 189 | #define MI_RESTORE_INHIBIT (1<<0) | ||
| 183 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) | 190 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) |
| 184 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ | 191 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ |
| 185 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) | 192 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) |
| @@ -312,6 +319,7 @@ | |||
| 312 | 319 | ||
| 313 | #define MI_MODE 0x0209c | 320 | #define MI_MODE 0x0209c |
| 314 | # define VS_TIMER_DISPATCH (1 << 6) | 321 | # define VS_TIMER_DISPATCH (1 << 6) |
| 322 | # define MI_FLUSH_ENABLE (1 << 11) | ||
| 315 | 323 | ||
| 316 | #define SCPD0 0x0209c /* 915+ only */ | 324 | #define SCPD0 0x0209c /* 915+ only */ |
| 317 | #define IER 0x020a0 | 325 | #define IER 0x020a0 |
| @@ -1100,6 +1108,11 @@ | |||
| 1100 | #define PEG_BAND_GAP_DATA 0x14d68 | 1108 | #define PEG_BAND_GAP_DATA 0x14d68 |
| 1101 | 1109 | ||
| 1102 | /* | 1110 | /* |
| 1111 | * Logical Context regs | ||
| 1112 | */ | ||
| 1113 | #define CCID 0x2180 | ||
| 1114 | #define CCID_EN (1<<0) | ||
| 1115 | /* | ||
| 1103 | * Overlay regs | 1116 | * Overlay regs |
| 1104 | */ | 1117 | */ |
| 1105 | 1118 | ||
| @@ -2069,6 +2082,7 @@ | |||
| 2069 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) | 2082 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) |
| 2070 | /* Pipe A */ | 2083 | /* Pipe A */ |
| 2071 | #define PIPEADSL 0x70000 | 2084 | #define PIPEADSL 0x70000 |
| 2085 | #define DSL_LINEMASK 0x00000fff | ||
| 2072 | #define PIPEACONF 0x70008 | 2086 | #define PIPEACONF 0x70008 |
| 2073 | #define PIPEACONF_ENABLE (1<<31) | 2087 | #define PIPEACONF_ENABLE (1<<31) |
| 2074 | #define PIPEACONF_DISABLE 0 | 2088 | #define PIPEACONF_DISABLE 0 |
| @@ -2192,9 +2206,17 @@ | |||
| 2192 | #define WM1_LP_SR_EN (1<<31) | 2206 | #define WM1_LP_SR_EN (1<<31) |
| 2193 | #define WM1_LP_LATENCY_SHIFT 24 | 2207 | #define WM1_LP_LATENCY_SHIFT 24 |
| 2194 | #define WM1_LP_LATENCY_MASK (0x7f<<24) | 2208 | #define WM1_LP_LATENCY_MASK (0x7f<<24) |
| 2209 | #define WM1_LP_FBC_LP1_MASK (0xf<<20) | ||
| 2210 | #define WM1_LP_FBC_LP1_SHIFT 20 | ||
| 2195 | #define WM1_LP_SR_MASK (0x1ff<<8) | 2211 | #define WM1_LP_SR_MASK (0x1ff<<8) |
| 2196 | #define WM1_LP_SR_SHIFT 8 | 2212 | #define WM1_LP_SR_SHIFT 8 |
| 2197 | #define WM1_LP_CURSOR_MASK (0x3f) | 2213 | #define WM1_LP_CURSOR_MASK (0x3f) |
| 2214 | #define WM2_LP_ILK 0x4510c | ||
| 2215 | #define WM2_LP_EN (1<<31) | ||
| 2216 | #define WM3_LP_ILK 0x45110 | ||
| 2217 | #define WM3_LP_EN (1<<31) | ||
| 2218 | #define WM1S_LP_ILK 0x45120 | ||
| 2219 | #define WM1S_LP_EN (1<<31) | ||
| 2198 | 2220 | ||
| 2199 | /* Memory latency timer register */ | 2221 | /* Memory latency timer register */ |
| 2200 | #define MLTR_ILK 0x11222 | 2222 | #define MLTR_ILK 0x11222 |
| @@ -2928,6 +2950,7 @@ | |||
| 2928 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 | 2950 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 |
| 2929 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) | 2951 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) |
| 2930 | #define TRANS_DP_HSYNC_ACTIVE_LOW 0 | 2952 | #define TRANS_DP_HSYNC_ACTIVE_LOW 0 |
| 2953 | #define TRANS_DP_SYNC_MASK (3<<3) | ||
| 2931 | 2954 | ||
| 2932 | /* SNB eDP training params */ | 2955 | /* SNB eDP training params */ |
| 2933 | /* SNB A-stepping */ | 2956 | /* SNB A-stepping */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 6e2025274db5..31f08581e93a 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
| @@ -34,7 +34,7 @@ static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) | |||
| 34 | struct drm_i915_private *dev_priv = dev->dev_private; | 34 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 35 | u32 dpll_reg; | 35 | u32 dpll_reg; |
| 36 | 36 | ||
| 37 | if (IS_IRONLAKE(dev)) { | 37 | if (HAS_PCH_SPLIT(dev)) { |
| 38 | dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; | 38 | dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; |
| 39 | } else { | 39 | } else { |
| 40 | dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; | 40 | dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; |
| @@ -53,7 +53,7 @@ static void i915_save_palette(struct drm_device *dev, enum pipe pipe) | |||
| 53 | if (!i915_pipe_enabled(dev, pipe)) | 53 | if (!i915_pipe_enabled(dev, pipe)) |
| 54 | return; | 54 | return; |
| 55 | 55 | ||
| 56 | if (IS_IRONLAKE(dev)) | 56 | if (HAS_PCH_SPLIT(dev)) |
| 57 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; | 57 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; |
| 58 | 58 | ||
| 59 | if (pipe == PIPE_A) | 59 | if (pipe == PIPE_A) |
| @@ -75,7 +75,7 @@ static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) | |||
| 75 | if (!i915_pipe_enabled(dev, pipe)) | 75 | if (!i915_pipe_enabled(dev, pipe)) |
| 76 | return; | 76 | return; |
| 77 | 77 | ||
| 78 | if (IS_IRONLAKE(dev)) | 78 | if (HAS_PCH_SPLIT(dev)) |
| 79 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; | 79 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; |
| 80 | 80 | ||
| 81 | if (pipe == PIPE_A) | 81 | if (pipe == PIPE_A) |
| @@ -239,7 +239,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
| 240 | return; | 240 | return; |
| 241 | 241 | ||
| 242 | if (IS_IRONLAKE(dev)) { | 242 | if (HAS_PCH_SPLIT(dev)) { |
| 243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); | 243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); |
| 244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); | 244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); |
| 245 | } | 245 | } |
| @@ -247,7 +247,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 247 | /* Pipe & plane A info */ | 247 | /* Pipe & plane A info */ |
| 248 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 248 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
| 249 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 249 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
| 250 | if (IS_IRONLAKE(dev)) { | 250 | if (HAS_PCH_SPLIT(dev)) { |
| 251 | dev_priv->saveFPA0 = I915_READ(PCH_FPA0); | 251 | dev_priv->saveFPA0 = I915_READ(PCH_FPA0); |
| 252 | dev_priv->saveFPA1 = I915_READ(PCH_FPA1); | 252 | dev_priv->saveFPA1 = I915_READ(PCH_FPA1); |
| 253 | dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); | 253 | dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); |
| @@ -256,7 +256,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 256 | dev_priv->saveFPA1 = I915_READ(FPA1); | 256 | dev_priv->saveFPA1 = I915_READ(FPA1); |
| 257 | dev_priv->saveDPLL_A = I915_READ(DPLL_A); | 257 | dev_priv->saveDPLL_A = I915_READ(DPLL_A); |
| 258 | } | 258 | } |
| 259 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 259 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
| 260 | dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); | 260 | dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); |
| 261 | dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); | 261 | dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); |
| 262 | dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); | 262 | dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); |
| @@ -264,10 +264,10 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 264 | dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); | 264 | dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); |
| 265 | dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); | 265 | dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); |
| 266 | dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); | 266 | dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); |
| 267 | if (!IS_IRONLAKE(dev)) | 267 | if (!HAS_PCH_SPLIT(dev)) |
| 268 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | 268 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); |
| 269 | 269 | ||
| 270 | if (IS_IRONLAKE(dev)) { | 270 | if (HAS_PCH_SPLIT(dev)) { |
| 271 | dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); | 271 | dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); |
| 272 | dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); | 272 | dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); |
| 273 | dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); | 273 | dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); |
| @@ -304,7 +304,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 304 | /* Pipe & plane B info */ | 304 | /* Pipe & plane B info */ |
| 305 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); | 305 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); |
| 306 | dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); | 306 | dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); |
| 307 | if (IS_IRONLAKE(dev)) { | 307 | if (HAS_PCH_SPLIT(dev)) { |
| 308 | dev_priv->saveFPB0 = I915_READ(PCH_FPB0); | 308 | dev_priv->saveFPB0 = I915_READ(PCH_FPB0); |
| 309 | dev_priv->saveFPB1 = I915_READ(PCH_FPB1); | 309 | dev_priv->saveFPB1 = I915_READ(PCH_FPB1); |
| 310 | dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); | 310 | dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); |
| @@ -313,7 +313,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 313 | dev_priv->saveFPB1 = I915_READ(FPB1); | 313 | dev_priv->saveFPB1 = I915_READ(FPB1); |
| 314 | dev_priv->saveDPLL_B = I915_READ(DPLL_B); | 314 | dev_priv->saveDPLL_B = I915_READ(DPLL_B); |
| 315 | } | 315 | } |
| 316 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 316 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
| 317 | dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); | 317 | dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); |
| 318 | dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); | 318 | dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); |
| 319 | dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); | 319 | dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); |
| @@ -321,10 +321,10 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 321 | dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); | 321 | dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); |
| 322 | dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); | 322 | dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); |
| 323 | dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); | 323 | dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); |
| 324 | if (!IS_IRONLAKE(dev)) | 324 | if (!HAS_PCH_SPLIT(dev)) |
| 325 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); | 325 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); |
| 326 | 326 | ||
| 327 | if (IS_IRONLAKE(dev)) { | 327 | if (HAS_PCH_SPLIT(dev)) { |
| 328 | dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); | 328 | dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); |
| 329 | dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); | 329 | dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); |
| 330 | dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); | 330 | dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); |
| @@ -369,7 +369,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 369 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 369 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
| 370 | return; | 370 | return; |
| 371 | 371 | ||
| 372 | if (IS_IRONLAKE(dev)) { | 372 | if (HAS_PCH_SPLIT(dev)) { |
| 373 | dpll_a_reg = PCH_DPLL_A; | 373 | dpll_a_reg = PCH_DPLL_A; |
| 374 | dpll_b_reg = PCH_DPLL_B; | 374 | dpll_b_reg = PCH_DPLL_B; |
| 375 | fpa0_reg = PCH_FPA0; | 375 | fpa0_reg = PCH_FPA0; |
| @@ -385,7 +385,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 385 | fpb1_reg = FPB1; | 385 | fpb1_reg = FPB1; |
| 386 | } | 386 | } |
| 387 | 387 | ||
| 388 | if (IS_IRONLAKE(dev)) { | 388 | if (HAS_PCH_SPLIT(dev)) { |
| 389 | I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); | 389 | I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); |
| 390 | I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); | 390 | I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); |
| 391 | } | 391 | } |
| @@ -395,16 +395,20 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 395 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | 395 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { |
| 396 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & | 396 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & |
| 397 | ~DPLL_VCO_ENABLE); | 397 | ~DPLL_VCO_ENABLE); |
| 398 | DRM_UDELAY(150); | 398 | POSTING_READ(dpll_a_reg); |
| 399 | udelay(150); | ||
| 399 | } | 400 | } |
| 400 | I915_WRITE(fpa0_reg, dev_priv->saveFPA0); | 401 | I915_WRITE(fpa0_reg, dev_priv->saveFPA0); |
| 401 | I915_WRITE(fpa1_reg, dev_priv->saveFPA1); | 402 | I915_WRITE(fpa1_reg, dev_priv->saveFPA1); |
| 402 | /* Actually enable it */ | 403 | /* Actually enable it */ |
| 403 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); | 404 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); |
| 404 | DRM_UDELAY(150); | 405 | POSTING_READ(dpll_a_reg); |
| 405 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 406 | udelay(150); |
| 407 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { | ||
| 406 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | 408 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); |
| 407 | DRM_UDELAY(150); | 409 | POSTING_READ(DPLL_A_MD); |
| 410 | } | ||
| 411 | udelay(150); | ||
| 408 | 412 | ||
| 409 | /* Restore mode */ | 413 | /* Restore mode */ |
| 410 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | 414 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); |
| @@ -413,10 +417,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 413 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | 417 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); |
| 414 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | 418 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); |
| 415 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | 419 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); |
| 416 | if (!IS_IRONLAKE(dev)) | 420 | if (!HAS_PCH_SPLIT(dev)) |
| 417 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | 421 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); |
| 418 | 422 | ||
| 419 | if (IS_IRONLAKE(dev)) { | 423 | if (HAS_PCH_SPLIT(dev)) { |
| 420 | I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); | 424 | I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); |
| 421 | I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); | 425 | I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); |
| 422 | I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); | 426 | I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); |
| @@ -460,16 +464,20 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 460 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | 464 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { |
| 461 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & | 465 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & |
| 462 | ~DPLL_VCO_ENABLE); | 466 | ~DPLL_VCO_ENABLE); |
| 463 | DRM_UDELAY(150); | 467 | POSTING_READ(dpll_b_reg); |
| 468 | udelay(150); | ||
| 464 | } | 469 | } |
| 465 | I915_WRITE(fpb0_reg, dev_priv->saveFPB0); | 470 | I915_WRITE(fpb0_reg, dev_priv->saveFPB0); |
| 466 | I915_WRITE(fpb1_reg, dev_priv->saveFPB1); | 471 | I915_WRITE(fpb1_reg, dev_priv->saveFPB1); |
| 467 | /* Actually enable it */ | 472 | /* Actually enable it */ |
| 468 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); | 473 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); |
| 469 | DRM_UDELAY(150); | 474 | POSTING_READ(dpll_b_reg); |
| 470 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 475 | udelay(150); |
| 476 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { | ||
| 471 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | 477 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); |
| 472 | DRM_UDELAY(150); | 478 | POSTING_READ(DPLL_B_MD); |
| 479 | } | ||
| 480 | udelay(150); | ||
| 473 | 481 | ||
| 474 | /* Restore mode */ | 482 | /* Restore mode */ |
| 475 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | 483 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); |
| @@ -478,10 +486,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 478 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | 486 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); |
| 479 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | 487 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); |
| 480 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | 488 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); |
| 481 | if (!IS_IRONLAKE(dev)) | 489 | if (!HAS_PCH_SPLIT(dev)) |
| 482 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | 490 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); |
| 483 | 491 | ||
| 484 | if (IS_IRONLAKE(dev)) { | 492 | if (HAS_PCH_SPLIT(dev)) { |
| 485 | I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); | 493 | I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); |
| 486 | I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); | 494 | I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); |
| 487 | I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); | 495 | I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); |
| @@ -546,14 +554,14 @@ void i915_save_display(struct drm_device *dev) | |||
| 546 | dev_priv->saveCURSIZE = I915_READ(CURSIZE); | 554 | dev_priv->saveCURSIZE = I915_READ(CURSIZE); |
| 547 | 555 | ||
| 548 | /* CRT state */ | 556 | /* CRT state */ |
| 549 | if (IS_IRONLAKE(dev)) { | 557 | if (HAS_PCH_SPLIT(dev)) { |
| 550 | dev_priv->saveADPA = I915_READ(PCH_ADPA); | 558 | dev_priv->saveADPA = I915_READ(PCH_ADPA); |
| 551 | } else { | 559 | } else { |
| 552 | dev_priv->saveADPA = I915_READ(ADPA); | 560 | dev_priv->saveADPA = I915_READ(ADPA); |
| 553 | } | 561 | } |
| 554 | 562 | ||
| 555 | /* LVDS state */ | 563 | /* LVDS state */ |
| 556 | if (IS_IRONLAKE(dev)) { | 564 | if (HAS_PCH_SPLIT(dev)) { |
| 557 | dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); | 565 | dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); |
| 558 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); | 566 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); |
| 559 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); | 567 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); |
| @@ -571,10 +579,10 @@ void i915_save_display(struct drm_device *dev) | |||
| 571 | dev_priv->saveLVDS = I915_READ(LVDS); | 579 | dev_priv->saveLVDS = I915_READ(LVDS); |
| 572 | } | 580 | } |
| 573 | 581 | ||
| 574 | if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev)) | 582 | if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) |
| 575 | dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); | 583 | dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); |
| 576 | 584 | ||
| 577 | if (IS_IRONLAKE(dev)) { | 585 | if (HAS_PCH_SPLIT(dev)) { |
| 578 | dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); | 586 | dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); |
| 579 | dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); | 587 | dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); |
| 580 | dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); | 588 | dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); |
| @@ -602,7 +610,7 @@ void i915_save_display(struct drm_device *dev) | |||
| 602 | 610 | ||
| 603 | /* Only save FBC state on the platform that supports FBC */ | 611 | /* Only save FBC state on the platform that supports FBC */ |
| 604 | if (I915_HAS_FBC(dev)) { | 612 | if (I915_HAS_FBC(dev)) { |
| 605 | if (IS_IRONLAKE_M(dev)) { | 613 | if (HAS_PCH_SPLIT(dev)) { |
| 606 | dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); | 614 | dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); |
| 607 | } else if (IS_GM45(dev)) { | 615 | } else if (IS_GM45(dev)) { |
| 608 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); | 616 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); |
| @@ -618,7 +626,7 @@ void i915_save_display(struct drm_device *dev) | |||
| 618 | dev_priv->saveVGA0 = I915_READ(VGA0); | 626 | dev_priv->saveVGA0 = I915_READ(VGA0); |
| 619 | dev_priv->saveVGA1 = I915_READ(VGA1); | 627 | dev_priv->saveVGA1 = I915_READ(VGA1); |
| 620 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); | 628 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); |
| 621 | if (IS_IRONLAKE(dev)) | 629 | if (HAS_PCH_SPLIT(dev)) |
| 622 | dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); | 630 | dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); |
| 623 | else | 631 | else |
| 624 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | 632 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); |
| @@ -660,24 +668,24 @@ void i915_restore_display(struct drm_device *dev) | |||
| 660 | I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); | 668 | I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); |
| 661 | 669 | ||
| 662 | /* CRT state */ | 670 | /* CRT state */ |
| 663 | if (IS_IRONLAKE(dev)) | 671 | if (HAS_PCH_SPLIT(dev)) |
| 664 | I915_WRITE(PCH_ADPA, dev_priv->saveADPA); | 672 | I915_WRITE(PCH_ADPA, dev_priv->saveADPA); |
| 665 | else | 673 | else |
| 666 | I915_WRITE(ADPA, dev_priv->saveADPA); | 674 | I915_WRITE(ADPA, dev_priv->saveADPA); |
| 667 | 675 | ||
| 668 | /* LVDS state */ | 676 | /* LVDS state */ |
| 669 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 677 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
| 670 | I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); | 678 | I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); |
| 671 | 679 | ||
| 672 | if (IS_IRONLAKE(dev)) { | 680 | if (HAS_PCH_SPLIT(dev)) { |
| 673 | I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); | 681 | I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); |
| 674 | } else if (IS_MOBILE(dev) && !IS_I830(dev)) | 682 | } else if (IS_MOBILE(dev) && !IS_I830(dev)) |
| 675 | I915_WRITE(LVDS, dev_priv->saveLVDS); | 683 | I915_WRITE(LVDS, dev_priv->saveLVDS); |
| 676 | 684 | ||
| 677 | if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev)) | 685 | if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) |
| 678 | I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); | 686 | I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); |
| 679 | 687 | ||
| 680 | if (IS_IRONLAKE(dev)) { | 688 | if (HAS_PCH_SPLIT(dev)) { |
| 681 | I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); | 689 | I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); |
| 682 | I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); | 690 | I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); |
| 683 | I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); | 691 | I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); |
| @@ -708,7 +716,7 @@ void i915_restore_display(struct drm_device *dev) | |||
| 708 | 716 | ||
| 709 | /* only restore FBC info on the platform that supports FBC*/ | 717 | /* only restore FBC info on the platform that supports FBC*/ |
| 710 | if (I915_HAS_FBC(dev)) { | 718 | if (I915_HAS_FBC(dev)) { |
| 711 | if (IS_IRONLAKE_M(dev)) { | 719 | if (HAS_PCH_SPLIT(dev)) { |
| 712 | ironlake_disable_fbc(dev); | 720 | ironlake_disable_fbc(dev); |
| 713 | I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); | 721 | I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); |
| 714 | } else if (IS_GM45(dev)) { | 722 | } else if (IS_GM45(dev)) { |
| @@ -723,14 +731,15 @@ void i915_restore_display(struct drm_device *dev) | |||
| 723 | } | 731 | } |
| 724 | } | 732 | } |
| 725 | /* VGA state */ | 733 | /* VGA state */ |
| 726 | if (IS_IRONLAKE(dev)) | 734 | if (HAS_PCH_SPLIT(dev)) |
| 727 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); | 735 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); |
| 728 | else | 736 | else |
| 729 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); | 737 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); |
| 730 | I915_WRITE(VGA0, dev_priv->saveVGA0); | 738 | I915_WRITE(VGA0, dev_priv->saveVGA0); |
| 731 | I915_WRITE(VGA1, dev_priv->saveVGA1); | 739 | I915_WRITE(VGA1, dev_priv->saveVGA1); |
| 732 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); | 740 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); |
| 733 | DRM_UDELAY(150); | 741 | POSTING_READ(VGA_PD); |
| 742 | udelay(150); | ||
| 734 | 743 | ||
| 735 | i915_restore_vga(dev); | 744 | i915_restore_vga(dev); |
| 736 | } | 745 | } |
| @@ -748,7 +757,7 @@ int i915_save_state(struct drm_device *dev) | |||
| 748 | i915_save_display(dev); | 757 | i915_save_display(dev); |
| 749 | 758 | ||
| 750 | /* Interrupt state */ | 759 | /* Interrupt state */ |
| 751 | if (IS_IRONLAKE(dev)) { | 760 | if (HAS_PCH_SPLIT(dev)) { |
| 752 | dev_priv->saveDEIER = I915_READ(DEIER); | 761 | dev_priv->saveDEIER = I915_READ(DEIER); |
| 753 | dev_priv->saveDEIMR = I915_READ(DEIMR); | 762 | dev_priv->saveDEIMR = I915_READ(DEIMR); |
| 754 | dev_priv->saveGTIER = I915_READ(GTIER); | 763 | dev_priv->saveGTIER = I915_READ(GTIER); |
| @@ -762,7 +771,7 @@ int i915_save_state(struct drm_device *dev) | |||
| 762 | dev_priv->saveIMR = I915_READ(IMR); | 771 | dev_priv->saveIMR = I915_READ(IMR); |
| 763 | } | 772 | } |
| 764 | 773 | ||
| 765 | if (IS_IRONLAKE_M(dev)) | 774 | if (HAS_PCH_SPLIT(dev)) |
| 766 | ironlake_disable_drps(dev); | 775 | ironlake_disable_drps(dev); |
| 767 | 776 | ||
| 768 | /* Cache mode state */ | 777 | /* Cache mode state */ |
| @@ -780,16 +789,25 @@ int i915_save_state(struct drm_device *dev) | |||
| 780 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); | 789 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); |
| 781 | 790 | ||
| 782 | /* Fences */ | 791 | /* Fences */ |
| 783 | if (IS_I965G(dev)) { | 792 | switch (INTEL_INFO(dev)->gen) { |
| 793 | case 6: | ||
| 794 | for (i = 0; i < 16; i++) | ||
| 795 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); | ||
| 796 | break; | ||
| 797 | case 5: | ||
| 798 | case 4: | ||
| 784 | for (i = 0; i < 16; i++) | 799 | for (i = 0; i < 16; i++) |
| 785 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); | 800 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); |
| 786 | } else { | 801 | break; |
| 787 | for (i = 0; i < 8; i++) | 802 | case 3: |
| 788 | dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); | ||
| 789 | |||
| 790 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | 803 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
| 791 | for (i = 0; i < 8; i++) | 804 | for (i = 0; i < 8; i++) |
| 792 | dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); | 805 | dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); |
| 806 | case 2: | ||
| 807 | for (i = 0; i < 8; i++) | ||
| 808 | dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); | ||
| 809 | break; | ||
| 810 | |||
| 793 | } | 811 | } |
| 794 | 812 | ||
| 795 | return 0; | 813 | return 0; |
| @@ -806,21 +824,30 @@ int i915_restore_state(struct drm_device *dev) | |||
| 806 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); | 824 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); |
| 807 | 825 | ||
| 808 | /* Fences */ | 826 | /* Fences */ |
| 809 | if (IS_I965G(dev)) { | 827 | switch (INTEL_INFO(dev)->gen) { |
| 828 | case 6: | ||
| 829 | for (i = 0; i < 16; i++) | ||
| 830 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); | ||
| 831 | break; | ||
| 832 | case 5: | ||
| 833 | case 4: | ||
| 810 | for (i = 0; i < 16; i++) | 834 | for (i = 0; i < 16; i++) |
| 811 | I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); | 835 | I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); |
| 812 | } else { | 836 | break; |
| 813 | for (i = 0; i < 8; i++) | 837 | case 3: |
| 814 | I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); | 838 | case 2: |
| 815 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | 839 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
| 816 | for (i = 0; i < 8; i++) | 840 | for (i = 0; i < 8; i++) |
| 817 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); | 841 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); |
| 842 | for (i = 0; i < 8; i++) | ||
| 843 | I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); | ||
| 844 | break; | ||
| 818 | } | 845 | } |
| 819 | 846 | ||
| 820 | i915_restore_display(dev); | 847 | i915_restore_display(dev); |
| 821 | 848 | ||
| 822 | /* Interrupt state */ | 849 | /* Interrupt state */ |
| 823 | if (IS_IRONLAKE(dev)) { | 850 | if (HAS_PCH_SPLIT(dev)) { |
| 824 | I915_WRITE(DEIER, dev_priv->saveDEIER); | 851 | I915_WRITE(DEIER, dev_priv->saveDEIER); |
| 825 | I915_WRITE(DEIMR, dev_priv->saveDEIMR); | 852 | I915_WRITE(DEIMR, dev_priv->saveDEIMR); |
| 826 | I915_WRITE(GTIER, dev_priv->saveGTIER); | 853 | I915_WRITE(GTIER, dev_priv->saveGTIER); |
| @@ -835,7 +862,7 @@ int i915_restore_state(struct drm_device *dev) | |||
| 835 | /* Clock gating state */ | 862 | /* Clock gating state */ |
| 836 | intel_init_clock_gating(dev); | 863 | intel_init_clock_gating(dev); |
| 837 | 864 | ||
| 838 | if (IS_IRONLAKE_M(dev)) | 865 | if (HAS_PCH_SPLIT(dev)) |
| 839 | ironlake_enable_drps(dev); | 866 | ironlake_enable_drps(dev); |
| 840 | 867 | ||
| 841 | /* Cache mode state */ | 868 | /* Cache mode state */ |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index ee0732b222a1..197d4f32585a 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -160,19 +160,20 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
| 160 | struct drm_i915_private *dev_priv = dev->dev_private; | 160 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 161 | u32 adpa, temp; | 161 | u32 adpa, temp; |
| 162 | bool ret; | 162 | bool ret; |
| 163 | bool turn_off_dac = false; | ||
| 163 | 164 | ||
| 164 | temp = adpa = I915_READ(PCH_ADPA); | 165 | temp = adpa = I915_READ(PCH_ADPA); |
| 165 | 166 | ||
| 166 | if (HAS_PCH_CPT(dev)) { | 167 | if (HAS_PCH_SPLIT(dev)) |
| 167 | /* Disable DAC before force detect */ | 168 | turn_off_dac = true; |
| 168 | I915_WRITE(PCH_ADPA, adpa & ~ADPA_DAC_ENABLE); | 169 | |
| 169 | (void)I915_READ(PCH_ADPA); | 170 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; |
| 170 | } else { | 171 | if (turn_off_dac) |
| 171 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | 172 | adpa &= ~ADPA_DAC_ENABLE; |
| 172 | /* disable HPD first */ | 173 | |
| 173 | I915_WRITE(PCH_ADPA, adpa); | 174 | /* disable HPD first */ |
| 174 | (void)I915_READ(PCH_ADPA); | 175 | I915_WRITE(PCH_ADPA, adpa); |
| 175 | } | 176 | (void)I915_READ(PCH_ADPA); |
| 176 | 177 | ||
| 177 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | | 178 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | |
| 178 | ADPA_CRT_HOTPLUG_WARMUP_10MS | | 179 | ADPA_CRT_HOTPLUG_WARMUP_10MS | |
| @@ -185,10 +186,11 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
| 185 | DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); | 186 | DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); |
| 186 | I915_WRITE(PCH_ADPA, adpa); | 187 | I915_WRITE(PCH_ADPA, adpa); |
| 187 | 188 | ||
| 188 | while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) | 189 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
| 189 | ; | 190 | 1000, 1)) |
| 191 | DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); | ||
| 190 | 192 | ||
| 191 | if (HAS_PCH_CPT(dev)) { | 193 | if (turn_off_dac) { |
| 192 | I915_WRITE(PCH_ADPA, temp); | 194 | I915_WRITE(PCH_ADPA, temp); |
| 193 | (void)I915_READ(PCH_ADPA); | 195 | (void)I915_READ(PCH_ADPA); |
| 194 | } | 196 | } |
| @@ -237,17 +239,13 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
| 237 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; | 239 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; |
| 238 | 240 | ||
| 239 | for (i = 0; i < tries ; i++) { | 241 | for (i = 0; i < tries ; i++) { |
| 240 | unsigned long timeout; | ||
| 241 | /* turn on the FORCE_DETECT */ | 242 | /* turn on the FORCE_DETECT */ |
| 242 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 243 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
| 243 | timeout = jiffies + msecs_to_jiffies(1000); | ||
| 244 | /* wait for FORCE_DETECT to go off */ | 244 | /* wait for FORCE_DETECT to go off */ |
| 245 | do { | 245 | if (wait_for((I915_READ(PORT_HOTPLUG_EN) & |
| 246 | if (!(I915_READ(PORT_HOTPLUG_EN) & | 246 | CRT_HOTPLUG_FORCE_DETECT) == 0, |
| 247 | CRT_HOTPLUG_FORCE_DETECT)) | 247 | 1000, 1)) |
| 248 | break; | 248 | DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off"); |
| 249 | msleep(1); | ||
| 250 | } while (time_after(timeout, jiffies)); | ||
| 251 | } | 249 | } |
| 252 | 250 | ||
| 253 | stat = I915_READ(PORT_HOTPLUG_STAT); | 251 | stat = I915_READ(PORT_HOTPLUG_STAT); |
| @@ -331,7 +329,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
| 331 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); | 329 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); |
| 332 | /* Wait for next Vblank to substitue | 330 | /* Wait for next Vblank to substitue |
| 333 | * border color for Color info */ | 331 | * border color for Color info */ |
| 334 | intel_wait_for_vblank(dev); | 332 | intel_wait_for_vblank(dev, pipe); |
| 335 | st00 = I915_READ8(VGA_MSR_WRITE); | 333 | st00 = I915_READ8(VGA_MSR_WRITE); |
| 336 | status = ((st00 & (1 << 4)) != 0) ? | 334 | status = ((st00 & (1 << 4)) != 0) ? |
| 337 | connector_status_connected : | 335 | connector_status_connected : |
| @@ -402,7 +400,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
| 402 | return status; | 400 | return status; |
| 403 | } | 401 | } |
| 404 | 402 | ||
| 405 | static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) | 403 | static enum drm_connector_status |
| 404 | intel_crt_detect(struct drm_connector *connector, bool force) | ||
| 406 | { | 405 | { |
| 407 | struct drm_device *dev = connector->dev; | 406 | struct drm_device *dev = connector->dev; |
| 408 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 407 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| @@ -421,6 +420,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto | |||
| 421 | if (intel_crt_detect_ddc(encoder)) | 420 | if (intel_crt_detect_ddc(encoder)) |
| 422 | return connector_status_connected; | 421 | return connector_status_connected; |
| 423 | 422 | ||
| 423 | if (!force) | ||
| 424 | return connector->status; | ||
| 425 | |||
| 424 | /* for pre-945g platforms use load detect */ | 426 | /* for pre-945g platforms use load detect */ |
| 425 | if (encoder->crtc && encoder->crtc->enabled) { | 427 | if (encoder->crtc && encoder->crtc->enabled) { |
| 426 | status = intel_crt_load_detect(encoder->crtc, intel_encoder); | 428 | status = intel_crt_load_detect(encoder->crtc, intel_encoder); |
| @@ -508,17 +510,8 @@ static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs | |||
| 508 | .best_encoder = intel_attached_encoder, | 510 | .best_encoder = intel_attached_encoder, |
| 509 | }; | 511 | }; |
| 510 | 512 | ||
| 511 | static void intel_crt_enc_destroy(struct drm_encoder *encoder) | ||
| 512 | { | ||
| 513 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 514 | |||
| 515 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
| 516 | drm_encoder_cleanup(encoder); | ||
| 517 | kfree(intel_encoder); | ||
| 518 | } | ||
| 519 | |||
| 520 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { | 513 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { |
| 521 | .destroy = intel_crt_enc_destroy, | 514 | .destroy = intel_encoder_destroy, |
| 522 | }; | 515 | }; |
| 523 | 516 | ||
| 524 | void intel_crt_init(struct drm_device *dev) | 517 | void intel_crt_init(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5ec10e02341b..979228594599 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
| 30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/vgaarb.h> | ||
| 32 | #include "drmP.h" | 33 | #include "drmP.h" |
| 33 | #include "intel_drv.h" | 34 | #include "intel_drv.h" |
| 34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
| @@ -976,14 +977,84 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
| 976 | return true; | 977 | return true; |
| 977 | } | 978 | } |
| 978 | 979 | ||
| 979 | void | 980 | /** |
| 980 | intel_wait_for_vblank(struct drm_device *dev) | 981 | * intel_wait_for_vblank - wait for vblank on a given pipe |
| 982 | * @dev: drm device | ||
| 983 | * @pipe: pipe to wait for | ||
| 984 | * | ||
| 985 | * Wait for vblank to occur on a given pipe. Needed for various bits of | ||
| 986 | * mode setting code. | ||
| 987 | */ | ||
| 988 | void intel_wait_for_vblank(struct drm_device *dev, int pipe) | ||
| 981 | { | 989 | { |
| 982 | /* Wait for 20ms, i.e. one cycle at 50hz. */ | 990 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 983 | if (in_dbg_master()) | 991 | int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT); |
| 984 | mdelay(20); /* The kernel debugger cannot call msleep() */ | 992 | |
| 985 | else | 993 | /* Clear existing vblank status. Note this will clear any other |
| 986 | msleep(20); | 994 | * sticky status fields as well. |
| 995 | * | ||
| 996 | * This races with i915_driver_irq_handler() with the result | ||
| 997 | * that either function could miss a vblank event. Here it is not | ||
| 998 | * fatal, as we will either wait upon the next vblank interrupt or | ||
| 999 | * timeout. Generally speaking intel_wait_for_vblank() is only | ||
| 1000 | * called during modeset at which time the GPU should be idle and | ||
| 1001 | * should *not* be performing page flips and thus not waiting on | ||
| 1002 | * vblanks... | ||
| 1003 | * Currently, the result of us stealing a vblank from the irq | ||
| 1004 | * handler is that a single frame will be skipped during swapbuffers. | ||
| 1005 | */ | ||
| 1006 | I915_WRITE(pipestat_reg, | ||
| 1007 | I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS); | ||
| 1008 | |||
| 1009 | /* Wait for vblank interrupt bit to set */ | ||
| 1010 | if (wait_for((I915_READ(pipestat_reg) & | ||
| 1011 | PIPE_VBLANK_INTERRUPT_STATUS), | ||
| 1012 | 50, 0)) | ||
| 1013 | DRM_DEBUG_KMS("vblank wait timed out\n"); | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | /* | ||
| 1017 | * intel_wait_for_pipe_off - wait for pipe to turn off | ||
| 1018 | * @dev: drm device | ||
| 1019 | * @pipe: pipe to wait for | ||
| 1020 | * | ||
| 1021 | * After disabling a pipe, we can't wait for vblank in the usual way, | ||
| 1022 | * spinning on the vblank interrupt status bit, since we won't actually | ||
| 1023 | * see an interrupt when the pipe is disabled. | ||
| 1024 | * | ||
| 1025 | * On Gen4 and above: | ||
| 1026 | * wait for the pipe register state bit to turn off | ||
| 1027 | * | ||
| 1028 | * Otherwise: | ||
| 1029 | * wait for the display line value to settle (it usually | ||
| 1030 | * ends up stopping at the start of the next frame). | ||
| 1031 | * | ||
| 1032 | */ | ||
| 1033 | static void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) | ||
| 1034 | { | ||
| 1035 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1036 | |||
| 1037 | if (INTEL_INFO(dev)->gen >= 4) { | ||
| 1038 | int pipeconf_reg = (pipe == 0 ? PIPEACONF : PIPEBCONF); | ||
| 1039 | |||
| 1040 | /* Wait for the Pipe State to go off */ | ||
| 1041 | if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, | ||
| 1042 | 100, 0)) | ||
| 1043 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); | ||
| 1044 | } else { | ||
| 1045 | u32 last_line; | ||
| 1046 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | ||
| 1047 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | ||
| 1048 | |||
| 1049 | /* Wait for the display line to settle */ | ||
| 1050 | do { | ||
| 1051 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | ||
| 1052 | mdelay(5); | ||
| 1053 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | ||
| 1054 | time_after(timeout, jiffies)); | ||
| 1055 | if (time_after(jiffies, timeout)) | ||
| 1056 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); | ||
| 1057 | } | ||
| 987 | } | 1058 | } |
| 988 | 1059 | ||
| 989 | /* Parameters have changed, update FBC info */ | 1060 | /* Parameters have changed, update FBC info */ |
| @@ -1037,7 +1108,6 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
| 1037 | void i8xx_disable_fbc(struct drm_device *dev) | 1108 | void i8xx_disable_fbc(struct drm_device *dev) |
| 1038 | { | 1109 | { |
| 1039 | struct drm_i915_private *dev_priv = dev->dev_private; | 1110 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1040 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
| 1041 | u32 fbc_ctl; | 1111 | u32 fbc_ctl; |
| 1042 | 1112 | ||
| 1043 | if (!I915_HAS_FBC(dev)) | 1113 | if (!I915_HAS_FBC(dev)) |
| @@ -1052,16 +1122,11 @@ void i8xx_disable_fbc(struct drm_device *dev) | |||
| 1052 | I915_WRITE(FBC_CONTROL, fbc_ctl); | 1122 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
| 1053 | 1123 | ||
| 1054 | /* Wait for compressing bit to clear */ | 1124 | /* Wait for compressing bit to clear */ |
| 1055 | while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) { | 1125 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10, 0)) { |
| 1056 | if (time_after(jiffies, timeout)) { | 1126 | DRM_DEBUG_KMS("FBC idle timed out\n"); |
| 1057 | DRM_DEBUG_DRIVER("FBC idle timed out\n"); | 1127 | return; |
| 1058 | break; | ||
| 1059 | } | ||
| 1060 | ; /* do nothing */ | ||
| 1061 | } | 1128 | } |
| 1062 | 1129 | ||
| 1063 | intel_wait_for_vblank(dev); | ||
| 1064 | |||
| 1065 | DRM_DEBUG_KMS("disabled FBC\n"); | 1130 | DRM_DEBUG_KMS("disabled FBC\n"); |
| 1066 | } | 1131 | } |
| 1067 | 1132 | ||
| @@ -1118,7 +1183,6 @@ void g4x_disable_fbc(struct drm_device *dev) | |||
| 1118 | dpfc_ctl = I915_READ(DPFC_CONTROL); | 1183 | dpfc_ctl = I915_READ(DPFC_CONTROL); |
| 1119 | dpfc_ctl &= ~DPFC_CTL_EN; | 1184 | dpfc_ctl &= ~DPFC_CTL_EN; |
| 1120 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); | 1185 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); |
| 1121 | intel_wait_for_vblank(dev); | ||
| 1122 | 1186 | ||
| 1123 | DRM_DEBUG_KMS("disabled FBC\n"); | 1187 | DRM_DEBUG_KMS("disabled FBC\n"); |
| 1124 | } | 1188 | } |
| @@ -1179,7 +1243,6 @@ void ironlake_disable_fbc(struct drm_device *dev) | |||
| 1179 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | 1243 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
| 1180 | dpfc_ctl &= ~DPFC_CTL_EN; | 1244 | dpfc_ctl &= ~DPFC_CTL_EN; |
| 1181 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | 1245 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); |
| 1182 | intel_wait_for_vblank(dev); | ||
| 1183 | 1246 | ||
| 1184 | DRM_DEBUG_KMS("disabled FBC\n"); | 1247 | DRM_DEBUG_KMS("disabled FBC\n"); |
| 1185 | } | 1248 | } |
| @@ -1453,7 +1516,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
| 1453 | dspcntr &= ~DISPPLANE_TILED; | 1516 | dspcntr &= ~DISPPLANE_TILED; |
| 1454 | } | 1517 | } |
| 1455 | 1518 | ||
| 1456 | if (IS_IRONLAKE(dev)) | 1519 | if (HAS_PCH_SPLIT(dev)) |
| 1457 | /* must disable */ | 1520 | /* must disable */ |
| 1458 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; | 1521 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; |
| 1459 | 1522 | ||
| @@ -1462,23 +1525,22 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
| 1462 | Start = obj_priv->gtt_offset; | 1525 | Start = obj_priv->gtt_offset; |
| 1463 | Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); | 1526 | Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); |
| 1464 | 1527 | ||
| 1465 | DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); | 1528 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", |
| 1529 | Start, Offset, x, y, fb->pitch); | ||
| 1466 | I915_WRITE(dspstride, fb->pitch); | 1530 | I915_WRITE(dspstride, fb->pitch); |
| 1467 | if (IS_I965G(dev)) { | 1531 | if (IS_I965G(dev)) { |
| 1468 | I915_WRITE(dspbase, Offset); | ||
| 1469 | I915_READ(dspbase); | ||
| 1470 | I915_WRITE(dspsurf, Start); | 1532 | I915_WRITE(dspsurf, Start); |
| 1471 | I915_READ(dspsurf); | ||
| 1472 | I915_WRITE(dsptileoff, (y << 16) | x); | 1533 | I915_WRITE(dsptileoff, (y << 16) | x); |
| 1534 | I915_WRITE(dspbase, Offset); | ||
| 1473 | } else { | 1535 | } else { |
| 1474 | I915_WRITE(dspbase, Start + Offset); | 1536 | I915_WRITE(dspbase, Start + Offset); |
| 1475 | I915_READ(dspbase); | ||
| 1476 | } | 1537 | } |
| 1538 | POSTING_READ(dspbase); | ||
| 1477 | 1539 | ||
| 1478 | if ((IS_I965G(dev) || plane == 0)) | 1540 | if (IS_I965G(dev) || plane == 0) |
| 1479 | intel_update_fbc(crtc, &crtc->mode); | 1541 | intel_update_fbc(crtc, &crtc->mode); |
| 1480 | 1542 | ||
| 1481 | intel_wait_for_vblank(dev); | 1543 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1482 | intel_increase_pllclock(crtc, true); | 1544 | intel_increase_pllclock(crtc, true); |
| 1483 | 1545 | ||
| 1484 | return 0; | 1546 | return 0; |
| @@ -1489,7 +1551,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 1489 | struct drm_framebuffer *old_fb) | 1551 | struct drm_framebuffer *old_fb) |
| 1490 | { | 1552 | { |
| 1491 | struct drm_device *dev = crtc->dev; | 1553 | struct drm_device *dev = crtc->dev; |
| 1492 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1493 | struct drm_i915_master_private *master_priv; | 1554 | struct drm_i915_master_private *master_priv; |
| 1494 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1555 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 1495 | struct intel_framebuffer *intel_fb; | 1556 | struct intel_framebuffer *intel_fb; |
| @@ -1497,13 +1558,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 1497 | struct drm_gem_object *obj; | 1558 | struct drm_gem_object *obj; |
| 1498 | int pipe = intel_crtc->pipe; | 1559 | int pipe = intel_crtc->pipe; |
| 1499 | int plane = intel_crtc->plane; | 1560 | int plane = intel_crtc->plane; |
| 1500 | unsigned long Start, Offset; | ||
| 1501 | int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR); | ||
| 1502 | int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF); | ||
| 1503 | int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; | ||
| 1504 | int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF); | ||
| 1505 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | ||
| 1506 | u32 dspcntr; | ||
| 1507 | int ret; | 1561 | int ret; |
| 1508 | 1562 | ||
| 1509 | /* no fb bound */ | 1563 | /* no fb bound */ |
| @@ -1539,73 +1593,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 1539 | return ret; | 1593 | return ret; |
| 1540 | } | 1594 | } |
| 1541 | 1595 | ||
| 1542 | dspcntr = I915_READ(dspcntr_reg); | 1596 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y); |
| 1543 | /* Mask out pixel format bits in case we change it */ | 1597 | if (ret) { |
| 1544 | dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; | ||
| 1545 | switch (crtc->fb->bits_per_pixel) { | ||
| 1546 | case 8: | ||
| 1547 | dspcntr |= DISPPLANE_8BPP; | ||
| 1548 | break; | ||
| 1549 | case 16: | ||
| 1550 | if (crtc->fb->depth == 15) | ||
| 1551 | dspcntr |= DISPPLANE_15_16BPP; | ||
| 1552 | else | ||
| 1553 | dspcntr |= DISPPLANE_16BPP; | ||
| 1554 | break; | ||
| 1555 | case 24: | ||
| 1556 | case 32: | ||
| 1557 | if (crtc->fb->depth == 30) | ||
| 1558 | dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA; | ||
| 1559 | else | ||
| 1560 | dspcntr |= DISPPLANE_32BPP_NO_ALPHA; | ||
| 1561 | break; | ||
| 1562 | default: | ||
| 1563 | DRM_ERROR("Unknown color depth\n"); | ||
| 1564 | i915_gem_object_unpin(obj); | 1598 | i915_gem_object_unpin(obj); |
| 1565 | mutex_unlock(&dev->struct_mutex); | 1599 | mutex_unlock(&dev->struct_mutex); |
| 1566 | return -EINVAL; | 1600 | return ret; |
| 1567 | } | ||
| 1568 | if (IS_I965G(dev)) { | ||
| 1569 | if (obj_priv->tiling_mode != I915_TILING_NONE) | ||
| 1570 | dspcntr |= DISPPLANE_TILED; | ||
| 1571 | else | ||
| 1572 | dspcntr &= ~DISPPLANE_TILED; | ||
| 1573 | } | ||
| 1574 | |||
| 1575 | if (HAS_PCH_SPLIT(dev)) | ||
| 1576 | /* must disable */ | ||
| 1577 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; | ||
| 1578 | |||
| 1579 | I915_WRITE(dspcntr_reg, dspcntr); | ||
| 1580 | |||
| 1581 | Start = obj_priv->gtt_offset; | ||
| 1582 | Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); | ||
| 1583 | |||
| 1584 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", | ||
| 1585 | Start, Offset, x, y, crtc->fb->pitch); | ||
| 1586 | I915_WRITE(dspstride, crtc->fb->pitch); | ||
| 1587 | if (IS_I965G(dev)) { | ||
| 1588 | I915_WRITE(dspbase, Offset); | ||
| 1589 | I915_READ(dspbase); | ||
| 1590 | I915_WRITE(dspsurf, Start); | ||
| 1591 | I915_READ(dspsurf); | ||
| 1592 | I915_WRITE(dsptileoff, (y << 16) | x); | ||
| 1593 | } else { | ||
| 1594 | I915_WRITE(dspbase, Start + Offset); | ||
| 1595 | I915_READ(dspbase); | ||
| 1596 | } | 1601 | } |
| 1597 | 1602 | ||
| 1598 | if ((IS_I965G(dev) || plane == 0)) | ||
| 1599 | intel_update_fbc(crtc, &crtc->mode); | ||
| 1600 | |||
| 1601 | intel_wait_for_vblank(dev); | ||
| 1602 | |||
| 1603 | if (old_fb) { | 1603 | if (old_fb) { |
| 1604 | intel_fb = to_intel_framebuffer(old_fb); | 1604 | intel_fb = to_intel_framebuffer(old_fb); |
| 1605 | obj_priv = to_intel_bo(intel_fb->obj); | 1605 | obj_priv = to_intel_bo(intel_fb->obj); |
| 1606 | i915_gem_object_unpin(intel_fb->obj); | 1606 | i915_gem_object_unpin(intel_fb->obj); |
| 1607 | } | 1607 | } |
| 1608 | intel_increase_pllclock(crtc, true); | ||
| 1609 | 1608 | ||
| 1610 | mutex_unlock(&dev->struct_mutex); | 1609 | mutex_unlock(&dev->struct_mutex); |
| 1611 | 1610 | ||
| @@ -1627,54 +1626,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 1627 | return 0; | 1626 | return 0; |
| 1628 | } | 1627 | } |
| 1629 | 1628 | ||
| 1630 | /* Disable the VGA plane that we never use */ | ||
| 1631 | static void i915_disable_vga (struct drm_device *dev) | ||
| 1632 | { | ||
| 1633 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1634 | u8 sr1; | ||
| 1635 | u32 vga_reg; | ||
| 1636 | |||
| 1637 | if (HAS_PCH_SPLIT(dev)) | ||
| 1638 | vga_reg = CPU_VGACNTRL; | ||
| 1639 | else | ||
| 1640 | vga_reg = VGACNTRL; | ||
| 1641 | |||
| 1642 | if (I915_READ(vga_reg) & VGA_DISP_DISABLE) | ||
| 1643 | return; | ||
| 1644 | |||
| 1645 | I915_WRITE8(VGA_SR_INDEX, 1); | ||
| 1646 | sr1 = I915_READ8(VGA_SR_DATA); | ||
| 1647 | I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5)); | ||
| 1648 | udelay(100); | ||
| 1649 | |||
| 1650 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
| 1651 | } | ||
| 1652 | |||
| 1653 | static void ironlake_disable_pll_edp (struct drm_crtc *crtc) | ||
| 1654 | { | ||
| 1655 | struct drm_device *dev = crtc->dev; | ||
| 1656 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1657 | u32 dpa_ctl; | ||
| 1658 | |||
| 1659 | DRM_DEBUG_KMS("\n"); | ||
| 1660 | dpa_ctl = I915_READ(DP_A); | ||
| 1661 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
| 1662 | I915_WRITE(DP_A, dpa_ctl); | ||
| 1663 | } | ||
| 1664 | |||
| 1665 | static void ironlake_enable_pll_edp (struct drm_crtc *crtc) | ||
| 1666 | { | ||
| 1667 | struct drm_device *dev = crtc->dev; | ||
| 1668 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1669 | u32 dpa_ctl; | ||
| 1670 | |||
| 1671 | dpa_ctl = I915_READ(DP_A); | ||
| 1672 | dpa_ctl |= DP_PLL_ENABLE; | ||
| 1673 | I915_WRITE(DP_A, dpa_ctl); | ||
| 1674 | udelay(200); | ||
| 1675 | } | ||
| 1676 | |||
| 1677 | |||
| 1678 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) | 1629 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) |
| 1679 | { | 1630 | { |
| 1680 | struct drm_device *dev = crtc->dev; | 1631 | struct drm_device *dev = crtc->dev; |
| @@ -1928,9 +1879,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 1928 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | 1879 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; |
| 1929 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | 1880 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; |
| 1930 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; | 1881 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; |
| 1931 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; | ||
| 1932 | int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ; | ||
| 1933 | int pf_win_pos = (pipe == 0) ? PFA_WIN_POS : PFB_WIN_POS; | ||
| 1934 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; | 1882 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; |
| 1935 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; | 1883 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; |
| 1936 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; | 1884 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; |
| @@ -1945,7 +1893,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 1945 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | 1893 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; |
| 1946 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; | 1894 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; |
| 1947 | u32 temp; | 1895 | u32 temp; |
| 1948 | int n; | ||
| 1949 | u32 pipe_bpc; | 1896 | u32 pipe_bpc; |
| 1950 | 1897 | ||
| 1951 | temp = I915_READ(pipeconf_reg); | 1898 | temp = I915_READ(pipeconf_reg); |
| @@ -1958,7 +1905,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 1958 | case DRM_MODE_DPMS_ON: | 1905 | case DRM_MODE_DPMS_ON: |
| 1959 | case DRM_MODE_DPMS_STANDBY: | 1906 | case DRM_MODE_DPMS_STANDBY: |
| 1960 | case DRM_MODE_DPMS_SUSPEND: | 1907 | case DRM_MODE_DPMS_SUSPEND: |
| 1961 | DRM_DEBUG_KMS("crtc %d dpms on\n", pipe); | 1908 | DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane); |
| 1962 | 1909 | ||
| 1963 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 1910 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
| 1964 | temp = I915_READ(PCH_LVDS); | 1911 | temp = I915_READ(PCH_LVDS); |
| @@ -1968,10 +1915,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 1968 | } | 1915 | } |
| 1969 | } | 1916 | } |
| 1970 | 1917 | ||
| 1971 | if (HAS_eDP) { | 1918 | if (!HAS_eDP) { |
| 1972 | /* enable eDP PLL */ | ||
| 1973 | ironlake_enable_pll_edp(crtc); | ||
| 1974 | } else { | ||
| 1975 | 1919 | ||
| 1976 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1920 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
| 1977 | temp = I915_READ(fdi_rx_reg); | 1921 | temp = I915_READ(fdi_rx_reg); |
| @@ -2003,17 +1947,19 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2003 | } | 1947 | } |
| 2004 | 1948 | ||
| 2005 | /* Enable panel fitting for LVDS */ | 1949 | /* Enable panel fitting for LVDS */ |
| 2006 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) | 1950 | if (dev_priv->pch_pf_size && |
| 2007 | || HAS_eDP || intel_pch_has_edp(crtc)) { | 1951 | (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) |
| 2008 | temp = I915_READ(pf_ctl_reg); | 1952 | || HAS_eDP || intel_pch_has_edp(crtc))) { |
| 2009 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); | 1953 | /* Force use of hard-coded filter coefficients |
| 2010 | 1954 | * as some pre-programmed values are broken, | |
| 2011 | /* currently full aspect */ | 1955 | * e.g. x201. |
| 2012 | I915_WRITE(pf_win_pos, 0); | 1956 | */ |
| 2013 | 1957 | I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, | |
| 2014 | I915_WRITE(pf_win_size, | 1958 | PF_ENABLE | PF_FILTER_MED_3x3); |
| 2015 | (dev_priv->panel_fixed_mode->hdisplay << 16) | | 1959 | I915_WRITE(pipe ? PFB_WIN_POS : PFA_WIN_POS, |
| 2016 | (dev_priv->panel_fixed_mode->vdisplay)); | 1960 | dev_priv->pch_pf_pos); |
| 1961 | I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, | ||
| 1962 | dev_priv->pch_pf_size); | ||
| 2017 | } | 1963 | } |
| 2018 | 1964 | ||
| 2019 | /* Enable CPU pipe */ | 1965 | /* Enable CPU pipe */ |
| @@ -2097,9 +2043,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2097 | int reg; | 2043 | int reg; |
| 2098 | 2044 | ||
| 2099 | reg = I915_READ(trans_dp_ctl); | 2045 | reg = I915_READ(trans_dp_ctl); |
| 2100 | reg &= ~TRANS_DP_PORT_SEL_MASK; | 2046 | reg &= ~(TRANS_DP_PORT_SEL_MASK | |
| 2101 | reg = TRANS_DP_OUTPUT_ENABLE | | 2047 | TRANS_DP_SYNC_MASK); |
| 2102 | TRANS_DP_ENH_FRAMING; | 2048 | reg |= (TRANS_DP_OUTPUT_ENABLE | |
| 2049 | TRANS_DP_ENH_FRAMING); | ||
| 2103 | 2050 | ||
| 2104 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | 2051 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
| 2105 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; | 2052 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; |
| @@ -2137,18 +2084,17 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2137 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 2084 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
| 2138 | I915_READ(transconf_reg); | 2085 | I915_READ(transconf_reg); |
| 2139 | 2086 | ||
| 2140 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) | 2087 | if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 100, 1)) |
| 2141 | ; | 2088 | DRM_ERROR("failed to enable transcoder\n"); |
| 2142 | |||
| 2143 | } | 2089 | } |
| 2144 | 2090 | ||
| 2145 | intel_crtc_load_lut(crtc); | 2091 | intel_crtc_load_lut(crtc); |
| 2146 | 2092 | ||
| 2147 | intel_update_fbc(crtc, &crtc->mode); | 2093 | intel_update_fbc(crtc, &crtc->mode); |
| 2094 | break; | ||
| 2148 | 2095 | ||
| 2149 | break; | ||
| 2150 | case DRM_MODE_DPMS_OFF: | 2096 | case DRM_MODE_DPMS_OFF: |
| 2151 | DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); | 2097 | DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane); |
| 2152 | 2098 | ||
| 2153 | drm_vblank_off(dev, pipe); | 2099 | drm_vblank_off(dev, pipe); |
| 2154 | /* Disable display plane */ | 2100 | /* Disable display plane */ |
| @@ -2164,40 +2110,22 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2164 | dev_priv->display.disable_fbc) | 2110 | dev_priv->display.disable_fbc) |
| 2165 | dev_priv->display.disable_fbc(dev); | 2111 | dev_priv->display.disable_fbc(dev); |
| 2166 | 2112 | ||
| 2167 | i915_disable_vga(dev); | ||
| 2168 | |||
| 2169 | /* disable cpu pipe, disable after all planes disabled */ | 2113 | /* disable cpu pipe, disable after all planes disabled */ |
| 2170 | temp = I915_READ(pipeconf_reg); | 2114 | temp = I915_READ(pipeconf_reg); |
| 2171 | if ((temp & PIPEACONF_ENABLE) != 0) { | 2115 | if ((temp & PIPEACONF_ENABLE) != 0) { |
| 2172 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); | 2116 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); |
| 2173 | I915_READ(pipeconf_reg); | 2117 | |
| 2174 | n = 0; | ||
| 2175 | /* wait for cpu pipe off, pipe state */ | 2118 | /* wait for cpu pipe off, pipe state */ |
| 2176 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) { | 2119 | if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, 50, 1)) |
| 2177 | n++; | 2120 | DRM_ERROR("failed to turn off cpu pipe\n"); |
| 2178 | if (n < 60) { | ||
| 2179 | udelay(500); | ||
| 2180 | continue; | ||
| 2181 | } else { | ||
| 2182 | DRM_DEBUG_KMS("pipe %d off delay\n", | ||
| 2183 | pipe); | ||
| 2184 | break; | ||
| 2185 | } | ||
| 2186 | } | ||
| 2187 | } else | 2121 | } else |
| 2188 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); | 2122 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); |
| 2189 | 2123 | ||
| 2190 | udelay(100); | 2124 | udelay(100); |
| 2191 | 2125 | ||
| 2192 | /* Disable PF */ | 2126 | /* Disable PF */ |
| 2193 | temp = I915_READ(pf_ctl_reg); | 2127 | I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, 0); |
| 2194 | if ((temp & PF_ENABLE) != 0) { | 2128 | I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, 0); |
| 2195 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
| 2196 | I915_READ(pf_ctl_reg); | ||
| 2197 | } | ||
| 2198 | I915_WRITE(pf_win_size, 0); | ||
| 2199 | POSTING_READ(pf_win_size); | ||
| 2200 | |||
| 2201 | 2129 | ||
| 2202 | /* disable CPU FDI tx and PCH FDI rx */ | 2130 | /* disable CPU FDI tx and PCH FDI rx */ |
| 2203 | temp = I915_READ(fdi_tx_reg); | 2131 | temp = I915_READ(fdi_tx_reg); |
| @@ -2244,20 +2172,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2244 | temp = I915_READ(transconf_reg); | 2172 | temp = I915_READ(transconf_reg); |
| 2245 | if ((temp & TRANS_ENABLE) != 0) { | 2173 | if ((temp & TRANS_ENABLE) != 0) { |
| 2246 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); | 2174 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); |
| 2247 | I915_READ(transconf_reg); | 2175 | |
| 2248 | n = 0; | ||
| 2249 | /* wait for PCH transcoder off, transcoder state */ | 2176 | /* wait for PCH transcoder off, transcoder state */ |
| 2250 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) { | 2177 | if (wait_for((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0, 50, 1)) |
| 2251 | n++; | 2178 | DRM_ERROR("failed to disable transcoder\n"); |
| 2252 | if (n < 60) { | ||
| 2253 | udelay(500); | ||
| 2254 | continue; | ||
| 2255 | } else { | ||
| 2256 | DRM_DEBUG_KMS("transcoder %d off " | ||
| 2257 | "delay\n", pipe); | ||
| 2258 | break; | ||
| 2259 | } | ||
| 2260 | } | ||
| 2261 | } | 2179 | } |
| 2262 | 2180 | ||
| 2263 | temp = I915_READ(transconf_reg); | 2181 | temp = I915_READ(transconf_reg); |
| @@ -2294,10 +2212,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2294 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); | 2212 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); |
| 2295 | I915_READ(pch_dpll_reg); | 2213 | I915_READ(pch_dpll_reg); |
| 2296 | 2214 | ||
| 2297 | if (HAS_eDP) { | ||
| 2298 | ironlake_disable_pll_edp(crtc); | ||
| 2299 | } | ||
| 2300 | |||
| 2301 | /* Switch from PCDclk to Rawclk */ | 2215 | /* Switch from PCDclk to Rawclk */ |
| 2302 | temp = I915_READ(fdi_rx_reg); | 2216 | temp = I915_READ(fdi_rx_reg); |
| 2303 | temp &= ~FDI_SEL_PCDCLK; | 2217 | temp &= ~FDI_SEL_PCDCLK; |
| @@ -2372,8 +2286,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2372 | case DRM_MODE_DPMS_ON: | 2286 | case DRM_MODE_DPMS_ON: |
| 2373 | case DRM_MODE_DPMS_STANDBY: | 2287 | case DRM_MODE_DPMS_STANDBY: |
| 2374 | case DRM_MODE_DPMS_SUSPEND: | 2288 | case DRM_MODE_DPMS_SUSPEND: |
| 2375 | intel_update_watermarks(dev); | ||
| 2376 | |||
| 2377 | /* Enable the DPLL */ | 2289 | /* Enable the DPLL */ |
| 2378 | temp = I915_READ(dpll_reg); | 2290 | temp = I915_READ(dpll_reg); |
| 2379 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 2291 | if ((temp & DPLL_VCO_ENABLE) == 0) { |
| @@ -2413,8 +2325,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2413 | intel_crtc_dpms_overlay(intel_crtc, true); | 2325 | intel_crtc_dpms_overlay(intel_crtc, true); |
| 2414 | break; | 2326 | break; |
| 2415 | case DRM_MODE_DPMS_OFF: | 2327 | case DRM_MODE_DPMS_OFF: |
| 2416 | intel_update_watermarks(dev); | ||
| 2417 | |||
| 2418 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 2328 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
| 2419 | intel_crtc_dpms_overlay(intel_crtc, false); | 2329 | intel_crtc_dpms_overlay(intel_crtc, false); |
| 2420 | drm_vblank_off(dev, pipe); | 2330 | drm_vblank_off(dev, pipe); |
| @@ -2423,9 +2333,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2423 | dev_priv->display.disable_fbc) | 2333 | dev_priv->display.disable_fbc) |
| 2424 | dev_priv->display.disable_fbc(dev); | 2334 | dev_priv->display.disable_fbc(dev); |
| 2425 | 2335 | ||
| 2426 | /* Disable the VGA plane that we never use */ | ||
| 2427 | i915_disable_vga(dev); | ||
| 2428 | |||
| 2429 | /* Disable display plane */ | 2336 | /* Disable display plane */ |
| 2430 | temp = I915_READ(dspcntr_reg); | 2337 | temp = I915_READ(dspcntr_reg); |
| 2431 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { | 2338 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { |
| @@ -2435,15 +2342,13 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2435 | I915_READ(dspbase_reg); | 2342 | I915_READ(dspbase_reg); |
| 2436 | } | 2343 | } |
| 2437 | 2344 | ||
| 2438 | if (!IS_I9XX(dev)) { | ||
| 2439 | /* Wait for vblank for the disable to take effect */ | ||
| 2440 | intel_wait_for_vblank(dev); | ||
| 2441 | } | ||
| 2442 | |||
| 2443 | /* Don't disable pipe A or pipe A PLLs if needed */ | 2345 | /* Don't disable pipe A or pipe A PLLs if needed */ |
| 2444 | if (pipeconf_reg == PIPEACONF && | 2346 | if (pipeconf_reg == PIPEACONF && |
| 2445 | (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | 2347 | (dev_priv->quirks & QUIRK_PIPEA_FORCE)) { |
| 2348 | /* Wait for vblank for the disable to take effect */ | ||
| 2349 | intel_wait_for_vblank(dev, pipe); | ||
| 2446 | goto skip_pipe_off; | 2350 | goto skip_pipe_off; |
| 2351 | } | ||
| 2447 | 2352 | ||
| 2448 | /* Next, disable display pipes */ | 2353 | /* Next, disable display pipes */ |
| 2449 | temp = I915_READ(pipeconf_reg); | 2354 | temp = I915_READ(pipeconf_reg); |
| @@ -2452,8 +2357,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2452 | I915_READ(pipeconf_reg); | 2357 | I915_READ(pipeconf_reg); |
| 2453 | } | 2358 | } |
| 2454 | 2359 | ||
| 2455 | /* Wait for vblank for the disable to take effect. */ | 2360 | /* Wait for the pipe to turn off */ |
| 2456 | intel_wait_for_vblank(dev); | 2361 | intel_wait_for_pipe_off(dev, pipe); |
| 2457 | 2362 | ||
| 2458 | temp = I915_READ(dpll_reg); | 2363 | temp = I915_READ(dpll_reg); |
| 2459 | if ((temp & DPLL_VCO_ENABLE) != 0) { | 2364 | if ((temp & DPLL_VCO_ENABLE) != 0) { |
| @@ -2469,9 +2374,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2469 | 2374 | ||
| 2470 | /** | 2375 | /** |
| 2471 | * Sets the power management mode of the pipe and plane. | 2376 | * Sets the power management mode of the pipe and plane. |
| 2472 | * | ||
| 2473 | * This code should probably grow support for turning the cursor off and back | ||
| 2474 | * on appropriately at the same time as we're turning the pipe off/on. | ||
| 2475 | */ | 2377 | */ |
| 2476 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | 2378 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) |
| 2477 | { | 2379 | { |
| @@ -2482,9 +2384,29 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2482 | int pipe = intel_crtc->pipe; | 2384 | int pipe = intel_crtc->pipe; |
| 2483 | bool enabled; | 2385 | bool enabled; |
| 2484 | 2386 | ||
| 2485 | dev_priv->display.dpms(crtc, mode); | 2387 | if (intel_crtc->dpms_mode == mode) |
| 2388 | return; | ||
| 2486 | 2389 | ||
| 2487 | intel_crtc->dpms_mode = mode; | 2390 | intel_crtc->dpms_mode = mode; |
| 2391 | intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON; | ||
| 2392 | |||
| 2393 | /* When switching on the display, ensure that SR is disabled | ||
| 2394 | * with multiple pipes prior to enabling to new pipe. | ||
| 2395 | * | ||
| 2396 | * When switching off the display, make sure the cursor is | ||
| 2397 | * properly hidden prior to disabling the pipe. | ||
| 2398 | */ | ||
| 2399 | if (mode == DRM_MODE_DPMS_ON) | ||
| 2400 | intel_update_watermarks(dev); | ||
| 2401 | else | ||
| 2402 | intel_crtc_update_cursor(crtc); | ||
| 2403 | |||
| 2404 | dev_priv->display.dpms(crtc, mode); | ||
| 2405 | |||
| 2406 | if (mode == DRM_MODE_DPMS_ON) | ||
| 2407 | intel_crtc_update_cursor(crtc); | ||
| 2408 | else | ||
| 2409 | intel_update_watermarks(dev); | ||
| 2488 | 2410 | ||
| 2489 | if (!dev->primary->master) | 2411 | if (!dev->primary->master) |
| 2490 | return; | 2412 | return; |
| @@ -2536,16 +2458,38 @@ void intel_encoder_commit (struct drm_encoder *encoder) | |||
| 2536 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); | 2458 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); |
| 2537 | } | 2459 | } |
| 2538 | 2460 | ||
| 2461 | void intel_encoder_destroy(struct drm_encoder *encoder) | ||
| 2462 | { | ||
| 2463 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 2464 | |||
| 2465 | if (intel_encoder->ddc_bus) | ||
| 2466 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
| 2467 | |||
| 2468 | if (intel_encoder->i2c_bus) | ||
| 2469 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
| 2470 | |||
| 2471 | drm_encoder_cleanup(encoder); | ||
| 2472 | kfree(intel_encoder); | ||
| 2473 | } | ||
| 2474 | |||
| 2539 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | 2475 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, |
| 2540 | struct drm_display_mode *mode, | 2476 | struct drm_display_mode *mode, |
| 2541 | struct drm_display_mode *adjusted_mode) | 2477 | struct drm_display_mode *adjusted_mode) |
| 2542 | { | 2478 | { |
| 2543 | struct drm_device *dev = crtc->dev; | 2479 | struct drm_device *dev = crtc->dev; |
| 2480 | |||
| 2544 | if (HAS_PCH_SPLIT(dev)) { | 2481 | if (HAS_PCH_SPLIT(dev)) { |
| 2545 | /* FDI link clock is fixed at 2.7G */ | 2482 | /* FDI link clock is fixed at 2.7G */ |
| 2546 | if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) | 2483 | if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) |
| 2547 | return false; | 2484 | return false; |
| 2548 | } | 2485 | } |
| 2486 | |||
| 2487 | /* XXX some encoders set the crtcinfo, others don't. | ||
| 2488 | * Obviously we need some form of conflict resolution here... | ||
| 2489 | */ | ||
| 2490 | if (adjusted_mode->crtc_htotal == 0) | ||
| 2491 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
| 2492 | |||
| 2549 | return true; | 2493 | return true; |
| 2550 | } | 2494 | } |
| 2551 | 2495 | ||
| @@ -2845,14 +2789,8 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | |||
| 2845 | /* Don't promote wm_size to unsigned... */ | 2789 | /* Don't promote wm_size to unsigned... */ |
| 2846 | if (wm_size > (long)wm->max_wm) | 2790 | if (wm_size > (long)wm->max_wm) |
| 2847 | wm_size = wm->max_wm; | 2791 | wm_size = wm->max_wm; |
| 2848 | if (wm_size <= 0) { | 2792 | if (wm_size <= 0) |
| 2849 | wm_size = wm->default_wm; | 2793 | wm_size = wm->default_wm; |
| 2850 | DRM_ERROR("Insufficient FIFO for plane, expect flickering:" | ||
| 2851 | " entries required = %ld, available = %lu.\n", | ||
| 2852 | entries_required + wm->guard_size, | ||
| 2853 | wm->fifo_size); | ||
| 2854 | } | ||
| 2855 | |||
| 2856 | return wm_size; | 2794 | return wm_size; |
| 2857 | } | 2795 | } |
| 2858 | 2796 | ||
| @@ -2867,7 +2805,7 @@ struct cxsr_latency { | |||
| 2867 | unsigned long cursor_hpll_disable; | 2805 | unsigned long cursor_hpll_disable; |
| 2868 | }; | 2806 | }; |
| 2869 | 2807 | ||
| 2870 | static struct cxsr_latency cxsr_latency_table[] = { | 2808 | static const struct cxsr_latency cxsr_latency_table[] = { |
| 2871 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | 2809 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ |
| 2872 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | 2810 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ |
| 2873 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | 2811 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ |
| @@ -2905,11 +2843,13 @@ static struct cxsr_latency cxsr_latency_table[] = { | |||
| 2905 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ | 2843 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ |
| 2906 | }; | 2844 | }; |
| 2907 | 2845 | ||
| 2908 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | 2846 | static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, |
| 2909 | int fsb, int mem) | 2847 | int is_ddr3, |
| 2848 | int fsb, | ||
| 2849 | int mem) | ||
| 2910 | { | 2850 | { |
| 2851 | const struct cxsr_latency *latency; | ||
| 2911 | int i; | 2852 | int i; |
| 2912 | struct cxsr_latency *latency; | ||
| 2913 | 2853 | ||
| 2914 | if (fsb == 0 || mem == 0) | 2854 | if (fsb == 0 || mem == 0) |
| 2915 | return NULL; | 2855 | return NULL; |
| @@ -2930,13 +2870,9 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | |||
| 2930 | static void pineview_disable_cxsr(struct drm_device *dev) | 2870 | static void pineview_disable_cxsr(struct drm_device *dev) |
| 2931 | { | 2871 | { |
| 2932 | struct drm_i915_private *dev_priv = dev->dev_private; | 2872 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2933 | u32 reg; | ||
| 2934 | 2873 | ||
| 2935 | /* deactivate cxsr */ | 2874 | /* deactivate cxsr */ |
| 2936 | reg = I915_READ(DSPFW3); | 2875 | I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN); |
| 2937 | reg &= ~(PINEVIEW_SELF_REFRESH_EN); | ||
| 2938 | I915_WRITE(DSPFW3, reg); | ||
| 2939 | DRM_INFO("Big FIFO is disabled\n"); | ||
| 2940 | } | 2876 | } |
| 2941 | 2877 | ||
| 2942 | /* | 2878 | /* |
| @@ -3024,12 +2960,12 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
| 3024 | int pixel_size) | 2960 | int pixel_size) |
| 3025 | { | 2961 | { |
| 3026 | struct drm_i915_private *dev_priv = dev->dev_private; | 2962 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2963 | const struct cxsr_latency *latency; | ||
| 3027 | u32 reg; | 2964 | u32 reg; |
| 3028 | unsigned long wm; | 2965 | unsigned long wm; |
| 3029 | struct cxsr_latency *latency; | ||
| 3030 | int sr_clock; | 2966 | int sr_clock; |
| 3031 | 2967 | ||
| 3032 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, | 2968 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, |
| 3033 | dev_priv->fsb_freq, dev_priv->mem_freq); | 2969 | dev_priv->fsb_freq, dev_priv->mem_freq); |
| 3034 | if (!latency) { | 2970 | if (!latency) { |
| 3035 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | 2971 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
| @@ -3075,9 +3011,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
| 3075 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); | 3011 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); |
| 3076 | 3012 | ||
| 3077 | /* activate cxsr */ | 3013 | /* activate cxsr */ |
| 3078 | reg = I915_READ(DSPFW3); | 3014 | I915_WRITE(DSPFW3, |
| 3079 | reg |= PINEVIEW_SELF_REFRESH_EN; | 3015 | I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN); |
| 3080 | I915_WRITE(DSPFW3, reg); | ||
| 3081 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); | 3016 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); |
| 3082 | } else { | 3017 | } else { |
| 3083 | pineview_disable_cxsr(dev); | 3018 | pineview_disable_cxsr(dev); |
| @@ -3354,12 +3289,11 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
| 3354 | int line_count; | 3289 | int line_count; |
| 3355 | int planea_htotal = 0, planeb_htotal = 0; | 3290 | int planea_htotal = 0, planeb_htotal = 0; |
| 3356 | struct drm_crtc *crtc; | 3291 | struct drm_crtc *crtc; |
| 3357 | struct intel_crtc *intel_crtc; | ||
| 3358 | 3292 | ||
| 3359 | /* Need htotal for all active display plane */ | 3293 | /* Need htotal for all active display plane */ |
| 3360 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3294 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
| 3361 | intel_crtc = to_intel_crtc(crtc); | 3295 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 3362 | if (crtc->enabled) { | 3296 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { |
| 3363 | if (intel_crtc->plane == 0) | 3297 | if (intel_crtc->plane == 0) |
| 3364 | planea_htotal = crtc->mode.htotal; | 3298 | planea_htotal = crtc->mode.htotal; |
| 3365 | else | 3299 | else |
| @@ -3470,8 +3404,7 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
| 3470 | reg_value = I915_READ(WM1_LP_ILK); | 3404 | reg_value = I915_READ(WM1_LP_ILK); |
| 3471 | reg_value &= ~(WM1_LP_LATENCY_MASK | WM1_LP_SR_MASK | | 3405 | reg_value &= ~(WM1_LP_LATENCY_MASK | WM1_LP_SR_MASK | |
| 3472 | WM1_LP_CURSOR_MASK); | 3406 | WM1_LP_CURSOR_MASK); |
| 3473 | reg_value |= WM1_LP_SR_EN | | 3407 | reg_value |= (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) | |
| 3474 | (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) | | ||
| 3475 | (sr_wm << WM1_LP_SR_SHIFT) | cursor_wm; | 3408 | (sr_wm << WM1_LP_SR_SHIFT) | cursor_wm; |
| 3476 | 3409 | ||
| 3477 | I915_WRITE(WM1_LP_ILK, reg_value); | 3410 | I915_WRITE(WM1_LP_ILK, reg_value); |
| @@ -3519,7 +3452,6 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
| 3519 | { | 3452 | { |
| 3520 | struct drm_i915_private *dev_priv = dev->dev_private; | 3453 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 3521 | struct drm_crtc *crtc; | 3454 | struct drm_crtc *crtc; |
| 3522 | struct intel_crtc *intel_crtc; | ||
| 3523 | int sr_hdisplay = 0; | 3455 | int sr_hdisplay = 0; |
| 3524 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | 3456 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; |
| 3525 | int enabled = 0, pixel_size = 0; | 3457 | int enabled = 0, pixel_size = 0; |
| @@ -3530,8 +3462,8 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
| 3530 | 3462 | ||
| 3531 | /* Get the clock config from both planes */ | 3463 | /* Get the clock config from both planes */ |
| 3532 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3464 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
| 3533 | intel_crtc = to_intel_crtc(crtc); | 3465 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 3534 | if (crtc->enabled) { | 3466 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { |
| 3535 | enabled++; | 3467 | enabled++; |
| 3536 | if (intel_crtc->plane == 0) { | 3468 | if (intel_crtc->plane == 0) { |
| 3537 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", | 3469 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", |
| @@ -3589,10 +3521,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3589 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; | 3521 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; |
| 3590 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; | 3522 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; |
| 3591 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 3523 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
| 3592 | bool is_edp = false; | 3524 | struct intel_encoder *has_edp_encoder = NULL; |
| 3593 | struct drm_mode_config *mode_config = &dev->mode_config; | 3525 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 3594 | struct drm_encoder *encoder; | 3526 | struct drm_encoder *encoder; |
| 3595 | struct intel_encoder *intel_encoder = NULL; | ||
| 3596 | const intel_limit_t *limit; | 3527 | const intel_limit_t *limit; |
| 3597 | int ret; | 3528 | int ret; |
| 3598 | struct fdi_m_n m_n = {0}; | 3529 | struct fdi_m_n m_n = {0}; |
| @@ -3613,12 +3544,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3613 | drm_vblank_pre_modeset(dev, pipe); | 3544 | drm_vblank_pre_modeset(dev, pipe); |
| 3614 | 3545 | ||
| 3615 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 3546 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
| 3547 | struct intel_encoder *intel_encoder; | ||
| 3616 | 3548 | ||
| 3617 | if (!encoder || encoder->crtc != crtc) | 3549 | if (encoder->crtc != crtc) |
| 3618 | continue; | 3550 | continue; |
| 3619 | 3551 | ||
| 3620 | intel_encoder = enc_to_intel_encoder(encoder); | 3552 | intel_encoder = enc_to_intel_encoder(encoder); |
| 3621 | |||
| 3622 | switch (intel_encoder->type) { | 3553 | switch (intel_encoder->type) { |
| 3623 | case INTEL_OUTPUT_LVDS: | 3554 | case INTEL_OUTPUT_LVDS: |
| 3624 | is_lvds = true; | 3555 | is_lvds = true; |
| @@ -3642,7 +3573,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3642 | is_dp = true; | 3573 | is_dp = true; |
| 3643 | break; | 3574 | break; |
| 3644 | case INTEL_OUTPUT_EDP: | 3575 | case INTEL_OUTPUT_EDP: |
| 3645 | is_edp = true; | 3576 | has_edp_encoder = intel_encoder; |
| 3646 | break; | 3577 | break; |
| 3647 | } | 3578 | } |
| 3648 | 3579 | ||
| @@ -3720,10 +3651,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3720 | int lane = 0, link_bw, bpp; | 3651 | int lane = 0, link_bw, bpp; |
| 3721 | /* eDP doesn't require FDI link, so just set DP M/N | 3652 | /* eDP doesn't require FDI link, so just set DP M/N |
| 3722 | according to current link config */ | 3653 | according to current link config */ |
| 3723 | if (is_edp) { | 3654 | if (has_edp_encoder) { |
| 3724 | target_clock = mode->clock; | 3655 | target_clock = mode->clock; |
| 3725 | intel_edp_link_config(intel_encoder, | 3656 | intel_edp_link_config(has_edp_encoder, |
| 3726 | &lane, &link_bw); | 3657 | &lane, &link_bw); |
| 3727 | } else { | 3658 | } else { |
| 3728 | /* DP over FDI requires target mode clock | 3659 | /* DP over FDI requires target mode clock |
| 3729 | instead of link clock */ | 3660 | instead of link clock */ |
| @@ -3744,7 +3675,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3744 | temp |= PIPE_8BPC; | 3675 | temp |= PIPE_8BPC; |
| 3745 | else | 3676 | else |
| 3746 | temp |= PIPE_6BPC; | 3677 | temp |= PIPE_6BPC; |
| 3747 | } else if (is_edp || (is_dp && intel_pch_has_edp(crtc))) { | 3678 | } else if (has_edp_encoder || (is_dp && intel_pch_has_edp(crtc))) { |
| 3748 | switch (dev_priv->edp_bpp/3) { | 3679 | switch (dev_priv->edp_bpp/3) { |
| 3749 | case 8: | 3680 | case 8: |
| 3750 | temp |= PIPE_8BPC; | 3681 | temp |= PIPE_8BPC; |
| @@ -3817,7 +3748,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3817 | 3748 | ||
| 3818 | udelay(200); | 3749 | udelay(200); |
| 3819 | 3750 | ||
| 3820 | if (is_edp) { | 3751 | if (has_edp_encoder) { |
| 3821 | if (dev_priv->lvds_use_ssc) { | 3752 | if (dev_priv->lvds_use_ssc) { |
| 3822 | temp |= DREF_SSC1_ENABLE; | 3753 | temp |= DREF_SSC1_ENABLE; |
| 3823 | I915_WRITE(PCH_DREF_CONTROL, temp); | 3754 | I915_WRITE(PCH_DREF_CONTROL, temp); |
| @@ -3966,9 +3897,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3966 | dpll_reg = pch_dpll_reg; | 3897 | dpll_reg = pch_dpll_reg; |
| 3967 | } | 3898 | } |
| 3968 | 3899 | ||
| 3969 | if (is_edp) { | 3900 | if (!has_edp_encoder) { |
| 3970 | ironlake_disable_pll_edp(crtc); | ||
| 3971 | } else if ((dpll & DPLL_VCO_ENABLE)) { | ||
| 3972 | I915_WRITE(fp_reg, fp); | 3901 | I915_WRITE(fp_reg, fp); |
| 3973 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 3902 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
| 3974 | I915_READ(dpll_reg); | 3903 | I915_READ(dpll_reg); |
| @@ -4063,7 +3992,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4063 | } | 3992 | } |
| 4064 | } | 3993 | } |
| 4065 | 3994 | ||
| 4066 | if (!is_edp) { | 3995 | if (!has_edp_encoder) { |
| 4067 | I915_WRITE(fp_reg, fp); | 3996 | I915_WRITE(fp_reg, fp); |
| 4068 | I915_WRITE(dpll_reg, dpll); | 3997 | I915_WRITE(dpll_reg, dpll); |
| 4069 | I915_READ(dpll_reg); | 3998 | I915_READ(dpll_reg); |
| @@ -4142,7 +4071,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4142 | I915_WRITE(link_m1_reg, m_n.link_m); | 4071 | I915_WRITE(link_m1_reg, m_n.link_m); |
| 4143 | I915_WRITE(link_n1_reg, m_n.link_n); | 4072 | I915_WRITE(link_n1_reg, m_n.link_n); |
| 4144 | 4073 | ||
| 4145 | if (is_edp) { | 4074 | if (has_edp_encoder) { |
| 4146 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); | 4075 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); |
| 4147 | } else { | 4076 | } else { |
| 4148 | /* enable FDI RX PLL too */ | 4077 | /* enable FDI RX PLL too */ |
| @@ -4167,7 +4096,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4167 | I915_WRITE(pipeconf_reg, pipeconf); | 4096 | I915_WRITE(pipeconf_reg, pipeconf); |
| 4168 | I915_READ(pipeconf_reg); | 4097 | I915_READ(pipeconf_reg); |
| 4169 | 4098 | ||
| 4170 | intel_wait_for_vblank(dev); | 4099 | intel_wait_for_vblank(dev, pipe); |
| 4171 | 4100 | ||
| 4172 | if (IS_IRONLAKE(dev)) { | 4101 | if (IS_IRONLAKE(dev)) { |
| 4173 | /* enable address swizzle for tiling buffer */ | 4102 | /* enable address swizzle for tiling buffer */ |
| @@ -4180,9 +4109,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4180 | /* Flush the plane changes */ | 4109 | /* Flush the plane changes */ |
| 4181 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 4110 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
| 4182 | 4111 | ||
| 4183 | if ((IS_I965G(dev) || plane == 0)) | ||
| 4184 | intel_update_fbc(crtc, &crtc->mode); | ||
| 4185 | |||
| 4186 | intel_update_watermarks(dev); | 4112 | intel_update_watermarks(dev); |
| 4187 | 4113 | ||
| 4188 | drm_vblank_post_modeset(dev, pipe); | 4114 | drm_vblank_post_modeset(dev, pipe); |
| @@ -4216,6 +4142,62 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
| 4216 | } | 4142 | } |
| 4217 | } | 4143 | } |
| 4218 | 4144 | ||
| 4145 | static void i845_update_cursor(struct drm_crtc *crtc, u32 base) | ||
| 4146 | { | ||
| 4147 | struct drm_device *dev = crtc->dev; | ||
| 4148 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 4149 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 4150 | bool visible = base != 0; | ||
| 4151 | u32 cntl; | ||
| 4152 | |||
| 4153 | if (intel_crtc->cursor_visible == visible) | ||
| 4154 | return; | ||
| 4155 | |||
| 4156 | cntl = I915_READ(CURACNTR); | ||
| 4157 | if (visible) { | ||
| 4158 | /* On these chipsets we can only modify the base whilst | ||
| 4159 | * the cursor is disabled. | ||
| 4160 | */ | ||
| 4161 | I915_WRITE(CURABASE, base); | ||
| 4162 | |||
| 4163 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
| 4164 | /* XXX width must be 64, stride 256 => 0x00 << 28 */ | ||
| 4165 | cntl |= CURSOR_ENABLE | | ||
| 4166 | CURSOR_GAMMA_ENABLE | | ||
| 4167 | CURSOR_FORMAT_ARGB; | ||
| 4168 | } else | ||
| 4169 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
| 4170 | I915_WRITE(CURACNTR, cntl); | ||
| 4171 | |||
| 4172 | intel_crtc->cursor_visible = visible; | ||
| 4173 | } | ||
| 4174 | |||
| 4175 | static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) | ||
| 4176 | { | ||
| 4177 | struct drm_device *dev = crtc->dev; | ||
| 4178 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 4179 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 4180 | int pipe = intel_crtc->pipe; | ||
| 4181 | bool visible = base != 0; | ||
| 4182 | |||
| 4183 | if (intel_crtc->cursor_visible != visible) { | ||
| 4184 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | ||
| 4185 | if (base) { | ||
| 4186 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
| 4187 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
| 4188 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
| 4189 | } else { | ||
| 4190 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
| 4191 | cntl |= CURSOR_MODE_DISABLE; | ||
| 4192 | } | ||
| 4193 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
| 4194 | |||
| 4195 | intel_crtc->cursor_visible = visible; | ||
| 4196 | } | ||
| 4197 | /* and commit changes on next vblank */ | ||
| 4198 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
| 4199 | } | ||
| 4200 | |||
| 4219 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ | 4201 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ |
| 4220 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) | 4202 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) |
| 4221 | { | 4203 | { |
| @@ -4225,12 +4207,12 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
| 4225 | int pipe = intel_crtc->pipe; | 4207 | int pipe = intel_crtc->pipe; |
| 4226 | int x = intel_crtc->cursor_x; | 4208 | int x = intel_crtc->cursor_x; |
| 4227 | int y = intel_crtc->cursor_y; | 4209 | int y = intel_crtc->cursor_y; |
| 4228 | uint32_t base, pos; | 4210 | u32 base, pos; |
| 4229 | bool visible; | 4211 | bool visible; |
| 4230 | 4212 | ||
| 4231 | pos = 0; | 4213 | pos = 0; |
| 4232 | 4214 | ||
| 4233 | if (crtc->fb) { | 4215 | if (intel_crtc->cursor_on && crtc->fb) { |
| 4234 | base = intel_crtc->cursor_addr; | 4216 | base = intel_crtc->cursor_addr; |
| 4235 | if (x > (int) crtc->fb->width) | 4217 | if (x > (int) crtc->fb->width) |
| 4236 | base = 0; | 4218 | base = 0; |
| @@ -4259,37 +4241,14 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
| 4259 | pos |= y << CURSOR_Y_SHIFT; | 4241 | pos |= y << CURSOR_Y_SHIFT; |
| 4260 | 4242 | ||
| 4261 | visible = base != 0; | 4243 | visible = base != 0; |
| 4262 | if (!visible && !intel_crtc->cursor_visble) | 4244 | if (!visible && !intel_crtc->cursor_visible) |
| 4263 | return; | 4245 | return; |
| 4264 | 4246 | ||
| 4265 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); | 4247 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); |
| 4266 | if (intel_crtc->cursor_visble != visible) { | 4248 | if (IS_845G(dev) || IS_I865G(dev)) |
| 4267 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | 4249 | i845_update_cursor(crtc, base); |
| 4268 | if (base) { | 4250 | else |
| 4269 | /* Hooray for CUR*CNTR differences */ | 4251 | i9xx_update_cursor(crtc, base); |
| 4270 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
| 4271 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
| 4272 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
| 4273 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
| 4274 | } else { | ||
| 4275 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
| 4276 | cntl |= CURSOR_ENABLE; | ||
| 4277 | cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; | ||
| 4278 | } | ||
| 4279 | } else { | ||
| 4280 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
| 4281 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
| 4282 | cntl |= CURSOR_MODE_DISABLE; | ||
| 4283 | } else { | ||
| 4284 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
| 4285 | } | ||
| 4286 | } | ||
| 4287 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
| 4288 | |||
| 4289 | intel_crtc->cursor_visble = visible; | ||
| 4290 | } | ||
| 4291 | /* and commit changes on next vblank */ | ||
| 4292 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
| 4293 | 4252 | ||
| 4294 | if (visible) | 4253 | if (visible) |
| 4295 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); | 4254 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); |
| @@ -4354,8 +4313,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
| 4354 | 4313 | ||
| 4355 | addr = obj_priv->gtt_offset; | 4314 | addr = obj_priv->gtt_offset; |
| 4356 | } else { | 4315 | } else { |
| 4316 | int align = IS_I830(dev) ? 16 * 1024 : 256; | ||
| 4357 | ret = i915_gem_attach_phys_object(dev, bo, | 4317 | ret = i915_gem_attach_phys_object(dev, bo, |
| 4358 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); | 4318 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, |
| 4319 | align); | ||
| 4359 | if (ret) { | 4320 | if (ret) { |
| 4360 | DRM_ERROR("failed to attach phys object\n"); | 4321 | DRM_ERROR("failed to attach phys object\n"); |
| 4361 | goto fail_locked; | 4322 | goto fail_locked; |
| @@ -4544,7 +4505,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | |||
| 4544 | encoder_funcs->commit(encoder); | 4505 | encoder_funcs->commit(encoder); |
| 4545 | } | 4506 | } |
| 4546 | /* let the connector get through one full cycle before testing */ | 4507 | /* let the connector get through one full cycle before testing */ |
| 4547 | intel_wait_for_vblank(dev); | 4508 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 4548 | 4509 | ||
| 4549 | return crtc; | 4510 | return crtc; |
| 4550 | } | 4511 | } |
| @@ -4749,7 +4710,7 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) | |||
| 4749 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; | 4710 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; |
| 4750 | I915_WRITE(dpll_reg, dpll); | 4711 | I915_WRITE(dpll_reg, dpll); |
| 4751 | dpll = I915_READ(dpll_reg); | 4712 | dpll = I915_READ(dpll_reg); |
| 4752 | intel_wait_for_vblank(dev); | 4713 | intel_wait_for_vblank(dev, pipe); |
| 4753 | dpll = I915_READ(dpll_reg); | 4714 | dpll = I915_READ(dpll_reg); |
| 4754 | if (dpll & DISPLAY_RATE_SELECT_FPA1) | 4715 | if (dpll & DISPLAY_RATE_SELECT_FPA1) |
| 4755 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); | 4716 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); |
| @@ -4793,7 +4754,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) | |||
| 4793 | dpll |= DISPLAY_RATE_SELECT_FPA1; | 4754 | dpll |= DISPLAY_RATE_SELECT_FPA1; |
| 4794 | I915_WRITE(dpll_reg, dpll); | 4755 | I915_WRITE(dpll_reg, dpll); |
| 4795 | dpll = I915_READ(dpll_reg); | 4756 | dpll = I915_READ(dpll_reg); |
| 4796 | intel_wait_for_vblank(dev); | 4757 | intel_wait_for_vblank(dev, pipe); |
| 4797 | dpll = I915_READ(dpll_reg); | 4758 | dpll = I915_READ(dpll_reg); |
| 4798 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) | 4759 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) |
| 4799 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); | 4760 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); |
| @@ -4916,15 +4877,6 @@ static void intel_crtc_destroy(struct drm_crtc *crtc) | |||
| 4916 | kfree(intel_crtc); | 4877 | kfree(intel_crtc); |
| 4917 | } | 4878 | } |
| 4918 | 4879 | ||
| 4919 | struct intel_unpin_work { | ||
| 4920 | struct work_struct work; | ||
| 4921 | struct drm_device *dev; | ||
| 4922 | struct drm_gem_object *old_fb_obj; | ||
| 4923 | struct drm_gem_object *pending_flip_obj; | ||
| 4924 | struct drm_pending_vblank_event *event; | ||
| 4925 | int pending; | ||
| 4926 | }; | ||
| 4927 | |||
| 4928 | static void intel_unpin_work_fn(struct work_struct *__work) | 4880 | static void intel_unpin_work_fn(struct work_struct *__work) |
| 4929 | { | 4881 | { |
| 4930 | struct intel_unpin_work *work = | 4882 | struct intel_unpin_work *work = |
| @@ -5012,7 +4964,8 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane) | |||
| 5012 | 4964 | ||
| 5013 | spin_lock_irqsave(&dev->event_lock, flags); | 4965 | spin_lock_irqsave(&dev->event_lock, flags); |
| 5014 | if (intel_crtc->unpin_work) { | 4966 | if (intel_crtc->unpin_work) { |
| 5015 | intel_crtc->unpin_work->pending = 1; | 4967 | if ((++intel_crtc->unpin_work->pending) > 1) |
| 4968 | DRM_ERROR("Prepared flip multiple times\n"); | ||
| 5016 | } else { | 4969 | } else { |
| 5017 | DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n"); | 4970 | DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n"); |
| 5018 | } | 4971 | } |
| @@ -5031,9 +4984,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
| 5031 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4984 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 5032 | struct intel_unpin_work *work; | 4985 | struct intel_unpin_work *work; |
| 5033 | unsigned long flags, offset; | 4986 | unsigned long flags, offset; |
| 5034 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; | 4987 | int pipe = intel_crtc->pipe; |
| 5035 | int ret, pipesrc; | 4988 | u32 pf, pipesrc; |
| 5036 | u32 flip_mask; | 4989 | int ret; |
| 5037 | 4990 | ||
| 5038 | work = kzalloc(sizeof *work, GFP_KERNEL); | 4991 | work = kzalloc(sizeof *work, GFP_KERNEL); |
| 5039 | if (work == NULL) | 4992 | if (work == NULL) |
| @@ -5082,34 +5035,73 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
| 5082 | atomic_inc(&obj_priv->pending_flip); | 5035 | atomic_inc(&obj_priv->pending_flip); |
| 5083 | work->pending_flip_obj = obj; | 5036 | work->pending_flip_obj = obj; |
| 5084 | 5037 | ||
| 5085 | if (intel_crtc->plane) | 5038 | if (IS_GEN3(dev) || IS_GEN2(dev)) { |
| 5086 | flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; | 5039 | u32 flip_mask; |
| 5087 | else | ||
| 5088 | flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; | ||
| 5089 | 5040 | ||
| 5090 | /* Wait for any previous flip to finish */ | 5041 | if (intel_crtc->plane) |
| 5091 | if (IS_GEN3(dev)) | 5042 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
| 5092 | while (I915_READ(ISR) & flip_mask) | 5043 | else |
| 5093 | ; | 5044 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; |
| 5045 | |||
| 5046 | BEGIN_LP_RING(2); | ||
| 5047 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); | ||
| 5048 | OUT_RING(0); | ||
| 5049 | ADVANCE_LP_RING(); | ||
| 5050 | } | ||
| 5051 | |||
| 5052 | work->enable_stall_check = true; | ||
| 5094 | 5053 | ||
| 5095 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | 5054 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ |
| 5096 | offset = obj_priv->gtt_offset; | 5055 | offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; |
| 5097 | offset += (crtc->y * fb->pitch) + (crtc->x * (fb->bits_per_pixel) / 8); | ||
| 5098 | 5056 | ||
| 5099 | BEGIN_LP_RING(4); | 5057 | BEGIN_LP_RING(4); |
| 5100 | if (IS_I965G(dev)) { | 5058 | switch(INTEL_INFO(dev)->gen) { |
| 5059 | case 2: | ||
| 5101 | OUT_RING(MI_DISPLAY_FLIP | | 5060 | OUT_RING(MI_DISPLAY_FLIP | |
| 5102 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5061 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
| 5103 | OUT_RING(fb->pitch); | 5062 | OUT_RING(fb->pitch); |
| 5104 | OUT_RING(offset | obj_priv->tiling_mode); | 5063 | OUT_RING(obj_priv->gtt_offset + offset); |
| 5105 | pipesrc = I915_READ(pipesrc_reg); | 5064 | OUT_RING(MI_NOOP); |
| 5106 | OUT_RING(pipesrc & 0x0fff0fff); | 5065 | break; |
| 5107 | } else { | 5066 | |
| 5067 | case 3: | ||
| 5108 | OUT_RING(MI_DISPLAY_FLIP_I915 | | 5068 | OUT_RING(MI_DISPLAY_FLIP_I915 | |
| 5109 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5069 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
| 5110 | OUT_RING(fb->pitch); | 5070 | OUT_RING(fb->pitch); |
| 5111 | OUT_RING(offset); | 5071 | OUT_RING(obj_priv->gtt_offset + offset); |
| 5112 | OUT_RING(MI_NOOP); | 5072 | OUT_RING(MI_NOOP); |
| 5073 | break; | ||
| 5074 | |||
| 5075 | case 4: | ||
| 5076 | case 5: | ||
| 5077 | /* i965+ uses the linear or tiled offsets from the | ||
| 5078 | * Display Registers (which do not change across a page-flip) | ||
| 5079 | * so we need only reprogram the base address. | ||
| 5080 | */ | ||
| 5081 | OUT_RING(MI_DISPLAY_FLIP | | ||
| 5082 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
| 5083 | OUT_RING(fb->pitch); | ||
| 5084 | OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); | ||
| 5085 | |||
| 5086 | /* XXX Enabling the panel-fitter across page-flip is so far | ||
| 5087 | * untested on non-native modes, so ignore it for now. | ||
| 5088 | * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; | ||
| 5089 | */ | ||
| 5090 | pf = 0; | ||
| 5091 | pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff; | ||
| 5092 | OUT_RING(pf | pipesrc); | ||
| 5093 | break; | ||
| 5094 | |||
| 5095 | case 6: | ||
| 5096 | OUT_RING(MI_DISPLAY_FLIP | | ||
| 5097 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
| 5098 | OUT_RING(fb->pitch | obj_priv->tiling_mode); | ||
| 5099 | OUT_RING(obj_priv->gtt_offset); | ||
| 5100 | |||
| 5101 | pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; | ||
| 5102 | pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff; | ||
| 5103 | OUT_RING(pf | pipesrc); | ||
| 5104 | break; | ||
| 5113 | } | 5105 | } |
| 5114 | ADVANCE_LP_RING(); | 5106 | ADVANCE_LP_RING(); |
| 5115 | 5107 | ||
| @@ -5190,7 +5182,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
| 5190 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; | 5182 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; |
| 5191 | 5183 | ||
| 5192 | intel_crtc->cursor_addr = 0; | 5184 | intel_crtc->cursor_addr = 0; |
| 5193 | intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; | 5185 | intel_crtc->dpms_mode = -1; |
| 5194 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); | 5186 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
| 5195 | 5187 | ||
| 5196 | intel_crtc->busy = false; | 5188 | intel_crtc->busy = false; |
| @@ -5432,37 +5424,37 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { | |||
| 5432 | }; | 5424 | }; |
| 5433 | 5425 | ||
| 5434 | static struct drm_gem_object * | 5426 | static struct drm_gem_object * |
| 5435 | intel_alloc_power_context(struct drm_device *dev) | 5427 | intel_alloc_context_page(struct drm_device *dev) |
| 5436 | { | 5428 | { |
| 5437 | struct drm_gem_object *pwrctx; | 5429 | struct drm_gem_object *ctx; |
| 5438 | int ret; | 5430 | int ret; |
| 5439 | 5431 | ||
| 5440 | pwrctx = i915_gem_alloc_object(dev, 4096); | 5432 | ctx = i915_gem_alloc_object(dev, 4096); |
| 5441 | if (!pwrctx) { | 5433 | if (!ctx) { |
| 5442 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | 5434 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); |
| 5443 | return NULL; | 5435 | return NULL; |
| 5444 | } | 5436 | } |
| 5445 | 5437 | ||
| 5446 | mutex_lock(&dev->struct_mutex); | 5438 | mutex_lock(&dev->struct_mutex); |
| 5447 | ret = i915_gem_object_pin(pwrctx, 4096); | 5439 | ret = i915_gem_object_pin(ctx, 4096); |
| 5448 | if (ret) { | 5440 | if (ret) { |
| 5449 | DRM_ERROR("failed to pin power context: %d\n", ret); | 5441 | DRM_ERROR("failed to pin power context: %d\n", ret); |
| 5450 | goto err_unref; | 5442 | goto err_unref; |
| 5451 | } | 5443 | } |
| 5452 | 5444 | ||
| 5453 | ret = i915_gem_object_set_to_gtt_domain(pwrctx, 1); | 5445 | ret = i915_gem_object_set_to_gtt_domain(ctx, 1); |
| 5454 | if (ret) { | 5446 | if (ret) { |
| 5455 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); | 5447 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); |
| 5456 | goto err_unpin; | 5448 | goto err_unpin; |
| 5457 | } | 5449 | } |
| 5458 | mutex_unlock(&dev->struct_mutex); | 5450 | mutex_unlock(&dev->struct_mutex); |
| 5459 | 5451 | ||
| 5460 | return pwrctx; | 5452 | return ctx; |
| 5461 | 5453 | ||
| 5462 | err_unpin: | 5454 | err_unpin: |
| 5463 | i915_gem_object_unpin(pwrctx); | 5455 | i915_gem_object_unpin(ctx); |
| 5464 | err_unref: | 5456 | err_unref: |
| 5465 | drm_gem_object_unreference(pwrctx); | 5457 | drm_gem_object_unreference(ctx); |
| 5466 | mutex_unlock(&dev->struct_mutex); | 5458 | mutex_unlock(&dev->struct_mutex); |
| 5467 | return NULL; | 5459 | return NULL; |
| 5468 | } | 5460 | } |
| @@ -5494,7 +5486,6 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
| 5494 | struct drm_i915_private *dev_priv = dev->dev_private; | 5486 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 5495 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 5487 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
| 5496 | u8 fmax, fmin, fstart, vstart; | 5488 | u8 fmax, fmin, fstart, vstart; |
| 5497 | int i = 0; | ||
| 5498 | 5489 | ||
| 5499 | /* 100ms RC evaluation intervals */ | 5490 | /* 100ms RC evaluation intervals */ |
| 5500 | I915_WRITE(RCUPEI, 100000); | 5491 | I915_WRITE(RCUPEI, 100000); |
| @@ -5538,13 +5529,8 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
| 5538 | rgvmodectl |= MEMMODE_SWMODE_EN; | 5529 | rgvmodectl |= MEMMODE_SWMODE_EN; |
| 5539 | I915_WRITE(MEMMODECTL, rgvmodectl); | 5530 | I915_WRITE(MEMMODECTL, rgvmodectl); |
| 5540 | 5531 | ||
| 5541 | while (I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) { | 5532 | if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 1, 0)) |
| 5542 | if (i++ > 100) { | 5533 | DRM_ERROR("stuck trying to change perf mode\n"); |
| 5543 | DRM_ERROR("stuck trying to change perf mode\n"); | ||
| 5544 | break; | ||
| 5545 | } | ||
| 5546 | msleep(1); | ||
| 5547 | } | ||
| 5548 | msleep(1); | 5534 | msleep(1); |
| 5549 | 5535 | ||
| 5550 | ironlake_set_drps(dev, fstart); | 5536 | ironlake_set_drps(dev, fstart); |
| @@ -5704,6 +5690,9 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
| 5704 | I915_WRITE(DISP_ARB_CTL, | 5690 | I915_WRITE(DISP_ARB_CTL, |
| 5705 | (I915_READ(DISP_ARB_CTL) | | 5691 | (I915_READ(DISP_ARB_CTL) | |
| 5706 | DISP_FBC_WM_DIS)); | 5692 | DISP_FBC_WM_DIS)); |
| 5693 | I915_WRITE(WM3_LP_ILK, 0); | ||
| 5694 | I915_WRITE(WM2_LP_ILK, 0); | ||
| 5695 | I915_WRITE(WM1_LP_ILK, 0); | ||
| 5707 | } | 5696 | } |
| 5708 | /* | 5697 | /* |
| 5709 | * Based on the document from hardware guys the following bits | 5698 | * Based on the document from hardware guys the following bits |
| @@ -5768,6 +5757,29 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
| 5768 | * GPU can automatically power down the render unit if given a page | 5757 | * GPU can automatically power down the render unit if given a page |
| 5769 | * to save state. | 5758 | * to save state. |
| 5770 | */ | 5759 | */ |
| 5760 | if (IS_IRONLAKE_M(dev)) { | ||
| 5761 | if (dev_priv->renderctx == NULL) | ||
| 5762 | dev_priv->renderctx = intel_alloc_context_page(dev); | ||
| 5763 | if (dev_priv->renderctx) { | ||
| 5764 | struct drm_i915_gem_object *obj_priv; | ||
| 5765 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
| 5766 | if (obj_priv) { | ||
| 5767 | BEGIN_LP_RING(4); | ||
| 5768 | OUT_RING(MI_SET_CONTEXT); | ||
| 5769 | OUT_RING(obj_priv->gtt_offset | | ||
| 5770 | MI_MM_SPACE_GTT | | ||
| 5771 | MI_SAVE_EXT_STATE_EN | | ||
| 5772 | MI_RESTORE_EXT_STATE_EN | | ||
| 5773 | MI_RESTORE_INHIBIT); | ||
| 5774 | OUT_RING(MI_NOOP); | ||
| 5775 | OUT_RING(MI_FLUSH); | ||
| 5776 | ADVANCE_LP_RING(); | ||
| 5777 | } | ||
| 5778 | } else | ||
| 5779 | DRM_DEBUG_KMS("Failed to allocate render context." | ||
| 5780 | "Disable RC6\n"); | ||
| 5781 | } | ||
| 5782 | |||
| 5771 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { | 5783 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { |
| 5772 | struct drm_i915_gem_object *obj_priv = NULL; | 5784 | struct drm_i915_gem_object *obj_priv = NULL; |
| 5773 | 5785 | ||
| @@ -5776,7 +5788,7 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
| 5776 | } else { | 5788 | } else { |
| 5777 | struct drm_gem_object *pwrctx; | 5789 | struct drm_gem_object *pwrctx; |
| 5778 | 5790 | ||
| 5779 | pwrctx = intel_alloc_power_context(dev); | 5791 | pwrctx = intel_alloc_context_page(dev); |
| 5780 | if (pwrctx) { | 5792 | if (pwrctx) { |
| 5781 | dev_priv->pwrctx = pwrctx; | 5793 | dev_priv->pwrctx = pwrctx; |
| 5782 | obj_priv = to_intel_bo(pwrctx); | 5794 | obj_priv = to_intel_bo(pwrctx); |
| @@ -5948,6 +5960,29 @@ static void intel_init_quirks(struct drm_device *dev) | |||
| 5948 | } | 5960 | } |
| 5949 | } | 5961 | } |
| 5950 | 5962 | ||
| 5963 | /* Disable the VGA plane that we never use */ | ||
| 5964 | static void i915_disable_vga(struct drm_device *dev) | ||
| 5965 | { | ||
| 5966 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 5967 | u8 sr1; | ||
| 5968 | u32 vga_reg; | ||
| 5969 | |||
| 5970 | if (HAS_PCH_SPLIT(dev)) | ||
| 5971 | vga_reg = CPU_VGACNTRL; | ||
| 5972 | else | ||
| 5973 | vga_reg = VGACNTRL; | ||
| 5974 | |||
| 5975 | vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
| 5976 | outb(1, VGA_SR_INDEX); | ||
| 5977 | sr1 = inb(VGA_SR_DATA); | ||
| 5978 | outb(sr1 | 1<<5, VGA_SR_DATA); | ||
| 5979 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
| 5980 | udelay(300); | ||
| 5981 | |||
| 5982 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
| 5983 | POSTING_READ(vga_reg); | ||
| 5984 | } | ||
| 5985 | |||
| 5951 | void intel_modeset_init(struct drm_device *dev) | 5986 | void intel_modeset_init(struct drm_device *dev) |
| 5952 | { | 5987 | { |
| 5953 | struct drm_i915_private *dev_priv = dev->dev_private; | 5988 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -5996,6 +6031,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
| 5996 | 6031 | ||
| 5997 | intel_init_clock_gating(dev); | 6032 | intel_init_clock_gating(dev); |
| 5998 | 6033 | ||
| 6034 | /* Just disable it once at startup */ | ||
| 6035 | i915_disable_vga(dev); | ||
| 6036 | |||
| 5999 | if (IS_IRONLAKE_M(dev)) { | 6037 | if (IS_IRONLAKE_M(dev)) { |
| 6000 | ironlake_enable_drps(dev); | 6038 | ironlake_enable_drps(dev); |
| 6001 | intel_init_emon(dev); | 6039 | intel_init_emon(dev); |
| @@ -6034,6 +6072,16 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
| 6034 | if (dev_priv->display.disable_fbc) | 6072 | if (dev_priv->display.disable_fbc) |
| 6035 | dev_priv->display.disable_fbc(dev); | 6073 | dev_priv->display.disable_fbc(dev); |
| 6036 | 6074 | ||
| 6075 | if (dev_priv->renderctx) { | ||
| 6076 | struct drm_i915_gem_object *obj_priv; | ||
| 6077 | |||
| 6078 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
| 6079 | I915_WRITE(CCID, obj_priv->gtt_offset &~ CCID_EN); | ||
| 6080 | I915_READ(CCID); | ||
| 6081 | i915_gem_object_unpin(dev_priv->renderctx); | ||
| 6082 | drm_gem_object_unreference(dev_priv->renderctx); | ||
| 6083 | } | ||
| 6084 | |||
| 6037 | if (dev_priv->pwrctx) { | 6085 | if (dev_priv->pwrctx) { |
| 6038 | struct drm_i915_gem_object *obj_priv; | 6086 | struct drm_i915_gem_object *obj_priv; |
| 6039 | 6087 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 40be1fa65be1..9ab8708ac6ba 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -42,10 +42,11 @@ | |||
| 42 | 42 | ||
| 43 | #define DP_LINK_CONFIGURATION_SIZE 9 | 43 | #define DP_LINK_CONFIGURATION_SIZE 9 |
| 44 | 44 | ||
| 45 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) | 45 | #define IS_eDP(i) ((i)->base.type == INTEL_OUTPUT_EDP) |
| 46 | #define IS_PCH_eDP(dp_priv) ((dp_priv)->is_pch_edp) | 46 | #define IS_PCH_eDP(i) ((i)->is_pch_edp) |
| 47 | 47 | ||
| 48 | struct intel_dp_priv { | 48 | struct intel_dp { |
| 49 | struct intel_encoder base; | ||
| 49 | uint32_t output_reg; | 50 | uint32_t output_reg; |
| 50 | uint32_t DP; | 51 | uint32_t DP; |
| 51 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; | 52 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; |
| @@ -54,40 +55,39 @@ struct intel_dp_priv { | |||
| 54 | uint8_t link_bw; | 55 | uint8_t link_bw; |
| 55 | uint8_t lane_count; | 56 | uint8_t lane_count; |
| 56 | uint8_t dpcd[4]; | 57 | uint8_t dpcd[4]; |
| 57 | struct intel_encoder *intel_encoder; | ||
| 58 | struct i2c_adapter adapter; | 58 | struct i2c_adapter adapter; |
| 59 | struct i2c_algo_dp_aux_data algo; | 59 | struct i2c_algo_dp_aux_data algo; |
| 60 | bool is_pch_edp; | 60 | bool is_pch_edp; |
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | static void | 63 | static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder) |
| 64 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | 64 | { |
| 65 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); | 65 | return container_of(enc_to_intel_encoder(encoder), struct intel_dp, base); |
| 66 | } | ||
| 66 | 67 | ||
| 67 | static void | 68 | static void intel_dp_link_train(struct intel_dp *intel_dp); |
| 68 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP); | 69 | static void intel_dp_link_down(struct intel_dp *intel_dp); |
| 69 | 70 | ||
| 70 | void | 71 | void |
| 71 | intel_edp_link_config (struct intel_encoder *intel_encoder, | 72 | intel_edp_link_config (struct intel_encoder *intel_encoder, |
| 72 | int *lane_num, int *link_bw) | 73 | int *lane_num, int *link_bw) |
| 73 | { | 74 | { |
| 74 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 75 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
| 75 | 76 | ||
| 76 | *lane_num = dp_priv->lane_count; | 77 | *lane_num = intel_dp->lane_count; |
| 77 | if (dp_priv->link_bw == DP_LINK_BW_1_62) | 78 | if (intel_dp->link_bw == DP_LINK_BW_1_62) |
| 78 | *link_bw = 162000; | 79 | *link_bw = 162000; |
| 79 | else if (dp_priv->link_bw == DP_LINK_BW_2_7) | 80 | else if (intel_dp->link_bw == DP_LINK_BW_2_7) |
| 80 | *link_bw = 270000; | 81 | *link_bw = 270000; |
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | static int | 84 | static int |
| 84 | intel_dp_max_lane_count(struct intel_encoder *intel_encoder) | 85 | intel_dp_max_lane_count(struct intel_dp *intel_dp) |
| 85 | { | 86 | { |
| 86 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 87 | int max_lane_count = 4; | 87 | int max_lane_count = 4; |
| 88 | 88 | ||
| 89 | if (dp_priv->dpcd[0] >= 0x11) { | 89 | if (intel_dp->dpcd[0] >= 0x11) { |
| 90 | max_lane_count = dp_priv->dpcd[2] & 0x1f; | 90 | max_lane_count = intel_dp->dpcd[2] & 0x1f; |
| 91 | switch (max_lane_count) { | 91 | switch (max_lane_count) { |
| 92 | case 1: case 2: case 4: | 92 | case 1: case 2: case 4: |
| 93 | break; | 93 | break; |
| @@ -99,10 +99,9 @@ intel_dp_max_lane_count(struct intel_encoder *intel_encoder) | |||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static int | 101 | static int |
| 102 | intel_dp_max_link_bw(struct intel_encoder *intel_encoder) | 102 | intel_dp_max_link_bw(struct intel_dp *intel_dp) |
| 103 | { | 103 | { |
| 104 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 104 | int max_link_bw = intel_dp->dpcd[1]; |
| 105 | int max_link_bw = dp_priv->dpcd[1]; | ||
| 106 | 105 | ||
| 107 | switch (max_link_bw) { | 106 | switch (max_link_bw) { |
| 108 | case DP_LINK_BW_1_62: | 107 | case DP_LINK_BW_1_62: |
| @@ -126,13 +125,11 @@ intel_dp_link_clock(uint8_t link_bw) | |||
| 126 | 125 | ||
| 127 | /* I think this is a fiction */ | 126 | /* I think this is a fiction */ |
| 128 | static int | 127 | static int |
| 129 | intel_dp_link_required(struct drm_device *dev, | 128 | intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pixel_clock) |
| 130 | struct intel_encoder *intel_encoder, int pixel_clock) | ||
| 131 | { | 129 | { |
| 132 | struct drm_i915_private *dev_priv = dev->dev_private; | 130 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 133 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 134 | 131 | ||
| 135 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) | 132 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
| 136 | return (pixel_clock * dev_priv->edp_bpp) / 8; | 133 | return (pixel_clock * dev_priv->edp_bpp) / 8; |
| 137 | else | 134 | else |
| 138 | return pixel_clock * 3; | 135 | return pixel_clock * 3; |
| @@ -149,14 +146,13 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
| 149 | struct drm_display_mode *mode) | 146 | struct drm_display_mode *mode) |
| 150 | { | 147 | { |
| 151 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 148 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 152 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 149 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 153 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 154 | struct drm_device *dev = connector->dev; | 150 | struct drm_device *dev = connector->dev; |
| 155 | struct drm_i915_private *dev_priv = dev->dev_private; | 151 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 156 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); | 152 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); |
| 157 | int max_lanes = intel_dp_max_lane_count(intel_encoder); | 153 | int max_lanes = intel_dp_max_lane_count(intel_dp); |
| 158 | 154 | ||
| 159 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 155 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
| 160 | dev_priv->panel_fixed_mode) { | 156 | dev_priv->panel_fixed_mode) { |
| 161 | if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) | 157 | if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) |
| 162 | return MODE_PANEL; | 158 | return MODE_PANEL; |
| @@ -167,8 +163,8 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
| 167 | 163 | ||
| 168 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels | 164 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels |
| 169 | which are outside spec tolerances but somehow work by magic */ | 165 | which are outside spec tolerances but somehow work by magic */ |
| 170 | if (!IS_eDP(intel_encoder) && | 166 | if (!IS_eDP(intel_dp) && |
| 171 | (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) | 167 | (intel_dp_link_required(connector->dev, intel_dp, mode->clock) |
| 172 | > intel_dp_max_data_rate(max_link_clock, max_lanes))) | 168 | > intel_dp_max_data_rate(max_link_clock, max_lanes))) |
| 173 | return MODE_CLOCK_HIGH; | 169 | return MODE_CLOCK_HIGH; |
| 174 | 170 | ||
| @@ -232,19 +228,17 @@ intel_hrawclk(struct drm_device *dev) | |||
| 232 | } | 228 | } |
| 233 | 229 | ||
| 234 | static int | 230 | static int |
| 235 | intel_dp_aux_ch(struct intel_encoder *intel_encoder, | 231 | intel_dp_aux_ch(struct intel_dp *intel_dp, |
| 236 | uint8_t *send, int send_bytes, | 232 | uint8_t *send, int send_bytes, |
| 237 | uint8_t *recv, int recv_size) | 233 | uint8_t *recv, int recv_size) |
| 238 | { | 234 | { |
| 239 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 235 | uint32_t output_reg = intel_dp->output_reg; |
| 240 | uint32_t output_reg = dp_priv->output_reg; | 236 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 241 | struct drm_device *dev = intel_encoder->enc.dev; | ||
| 242 | struct drm_i915_private *dev_priv = dev->dev_private; | 237 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 243 | uint32_t ch_ctl = output_reg + 0x10; | 238 | uint32_t ch_ctl = output_reg + 0x10; |
| 244 | uint32_t ch_data = ch_ctl + 4; | 239 | uint32_t ch_data = ch_ctl + 4; |
| 245 | int i; | 240 | int i; |
| 246 | int recv_bytes; | 241 | int recv_bytes; |
| 247 | uint32_t ctl; | ||
| 248 | uint32_t status; | 242 | uint32_t status; |
| 249 | uint32_t aux_clock_divider; | 243 | uint32_t aux_clock_divider; |
| 250 | int try, precharge; | 244 | int try, precharge; |
| @@ -253,7 +247,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
| 253 | * and would like to run at 2MHz. So, take the | 247 | * and would like to run at 2MHz. So, take the |
| 254 | * hrawclk value and divide by 2 and use that | 248 | * hrawclk value and divide by 2 and use that |
| 255 | */ | 249 | */ |
| 256 | if (IS_eDP(intel_encoder)) { | 250 | if (IS_eDP(intel_dp)) { |
| 257 | if (IS_GEN6(dev)) | 251 | if (IS_GEN6(dev)) |
| 258 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ | 252 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ |
| 259 | else | 253 | else |
| @@ -268,41 +262,43 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
| 268 | else | 262 | else |
| 269 | precharge = 5; | 263 | precharge = 5; |
| 270 | 264 | ||
| 265 | if (I915_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) { | ||
| 266 | DRM_ERROR("dp_aux_ch not started status 0x%08x\n", | ||
| 267 | I915_READ(ch_ctl)); | ||
| 268 | return -EBUSY; | ||
| 269 | } | ||
| 270 | |||
| 271 | /* Must try at least 3 times according to DP spec */ | 271 | /* Must try at least 3 times according to DP spec */ |
| 272 | for (try = 0; try < 5; try++) { | 272 | for (try = 0; try < 5; try++) { |
| 273 | /* Load the send data into the aux channel data registers */ | 273 | /* Load the send data into the aux channel data registers */ |
| 274 | for (i = 0; i < send_bytes; i += 4) { | 274 | for (i = 0; i < send_bytes; i += 4) |
| 275 | uint32_t d = pack_aux(send + i, send_bytes - i); | 275 | I915_WRITE(ch_data + i, |
| 276 | 276 | pack_aux(send + i, send_bytes - i)); | |
| 277 | I915_WRITE(ch_data + i, d); | ||
| 278 | } | ||
| 279 | |||
| 280 | ctl = (DP_AUX_CH_CTL_SEND_BUSY | | ||
| 281 | DP_AUX_CH_CTL_TIME_OUT_400us | | ||
| 282 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | ||
| 283 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | ||
| 284 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | ||
| 285 | DP_AUX_CH_CTL_DONE | | ||
| 286 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
| 287 | DP_AUX_CH_CTL_RECEIVE_ERROR); | ||
| 288 | 277 | ||
| 289 | /* Send the command and wait for it to complete */ | 278 | /* Send the command and wait for it to complete */ |
| 290 | I915_WRITE(ch_ctl, ctl); | 279 | I915_WRITE(ch_ctl, |
| 291 | (void) I915_READ(ch_ctl); | 280 | DP_AUX_CH_CTL_SEND_BUSY | |
| 281 | DP_AUX_CH_CTL_TIME_OUT_400us | | ||
| 282 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | ||
| 283 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | ||
| 284 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | ||
| 285 | DP_AUX_CH_CTL_DONE | | ||
| 286 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
| 287 | DP_AUX_CH_CTL_RECEIVE_ERROR); | ||
| 292 | for (;;) { | 288 | for (;;) { |
| 293 | udelay(100); | ||
| 294 | status = I915_READ(ch_ctl); | 289 | status = I915_READ(ch_ctl); |
| 295 | if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) | 290 | if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) |
| 296 | break; | 291 | break; |
| 292 | udelay(100); | ||
| 297 | } | 293 | } |
| 298 | 294 | ||
| 299 | /* Clear done status and any errors */ | 295 | /* Clear done status and any errors */ |
| 300 | I915_WRITE(ch_ctl, (status | | 296 | I915_WRITE(ch_ctl, |
| 301 | DP_AUX_CH_CTL_DONE | | 297 | status | |
| 302 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | 298 | DP_AUX_CH_CTL_DONE | |
| 303 | DP_AUX_CH_CTL_RECEIVE_ERROR)); | 299 | DP_AUX_CH_CTL_TIME_OUT_ERROR | |
| 304 | (void) I915_READ(ch_ctl); | 300 | DP_AUX_CH_CTL_RECEIVE_ERROR); |
| 305 | if ((status & DP_AUX_CH_CTL_TIME_OUT_ERROR) == 0) | 301 | if (status & DP_AUX_CH_CTL_DONE) |
| 306 | break; | 302 | break; |
| 307 | } | 303 | } |
| 308 | 304 | ||
| @@ -329,22 +325,19 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
| 329 | /* Unload any bytes sent back from the other side */ | 325 | /* Unload any bytes sent back from the other side */ |
| 330 | recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> | 326 | recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> |
| 331 | DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); | 327 | DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); |
| 332 | |||
| 333 | if (recv_bytes > recv_size) | 328 | if (recv_bytes > recv_size) |
| 334 | recv_bytes = recv_size; | 329 | recv_bytes = recv_size; |
| 335 | 330 | ||
| 336 | for (i = 0; i < recv_bytes; i += 4) { | 331 | for (i = 0; i < recv_bytes; i += 4) |
| 337 | uint32_t d = I915_READ(ch_data + i); | 332 | unpack_aux(I915_READ(ch_data + i), |
| 338 | 333 | recv + i, recv_bytes - i); | |
| 339 | unpack_aux(d, recv + i, recv_bytes - i); | ||
| 340 | } | ||
| 341 | 334 | ||
| 342 | return recv_bytes; | 335 | return recv_bytes; |
| 343 | } | 336 | } |
| 344 | 337 | ||
| 345 | /* Write data to the aux channel in native mode */ | 338 | /* Write data to the aux channel in native mode */ |
| 346 | static int | 339 | static int |
| 347 | intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | 340 | intel_dp_aux_native_write(struct intel_dp *intel_dp, |
| 348 | uint16_t address, uint8_t *send, int send_bytes) | 341 | uint16_t address, uint8_t *send, int send_bytes) |
| 349 | { | 342 | { |
| 350 | int ret; | 343 | int ret; |
| @@ -361,7 +354,7 @@ intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | |||
| 361 | memcpy(&msg[4], send, send_bytes); | 354 | memcpy(&msg[4], send, send_bytes); |
| 362 | msg_bytes = send_bytes + 4; | 355 | msg_bytes = send_bytes + 4; |
| 363 | for (;;) { | 356 | for (;;) { |
| 364 | ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1); | 357 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); |
| 365 | if (ret < 0) | 358 | if (ret < 0) |
| 366 | return ret; | 359 | return ret; |
| 367 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) | 360 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) |
| @@ -376,15 +369,15 @@ intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | |||
| 376 | 369 | ||
| 377 | /* Write a single byte to the aux channel in native mode */ | 370 | /* Write a single byte to the aux channel in native mode */ |
| 378 | static int | 371 | static int |
| 379 | intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder, | 372 | intel_dp_aux_native_write_1(struct intel_dp *intel_dp, |
| 380 | uint16_t address, uint8_t byte) | 373 | uint16_t address, uint8_t byte) |
| 381 | { | 374 | { |
| 382 | return intel_dp_aux_native_write(intel_encoder, address, &byte, 1); | 375 | return intel_dp_aux_native_write(intel_dp, address, &byte, 1); |
| 383 | } | 376 | } |
| 384 | 377 | ||
| 385 | /* read bytes from a native aux channel */ | 378 | /* read bytes from a native aux channel */ |
| 386 | static int | 379 | static int |
| 387 | intel_dp_aux_native_read(struct intel_encoder *intel_encoder, | 380 | intel_dp_aux_native_read(struct intel_dp *intel_dp, |
| 388 | uint16_t address, uint8_t *recv, int recv_bytes) | 381 | uint16_t address, uint8_t *recv, int recv_bytes) |
| 389 | { | 382 | { |
| 390 | uint8_t msg[4]; | 383 | uint8_t msg[4]; |
| @@ -403,7 +396,7 @@ intel_dp_aux_native_read(struct intel_encoder *intel_encoder, | |||
| 403 | reply_bytes = recv_bytes + 1; | 396 | reply_bytes = recv_bytes + 1; |
| 404 | 397 | ||
| 405 | for (;;) { | 398 | for (;;) { |
| 406 | ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, | 399 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, |
| 407 | reply, reply_bytes); | 400 | reply, reply_bytes); |
| 408 | if (ret == 0) | 401 | if (ret == 0) |
| 409 | return -EPROTO; | 402 | return -EPROTO; |
| @@ -426,10 +419,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
| 426 | uint8_t write_byte, uint8_t *read_byte) | 419 | uint8_t write_byte, uint8_t *read_byte) |
| 427 | { | 420 | { |
| 428 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | 421 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; |
| 429 | struct intel_dp_priv *dp_priv = container_of(adapter, | 422 | struct intel_dp *intel_dp = container_of(adapter, |
| 430 | struct intel_dp_priv, | 423 | struct intel_dp, |
| 431 | adapter); | 424 | adapter); |
| 432 | struct intel_encoder *intel_encoder = dp_priv->intel_encoder; | ||
| 433 | uint16_t address = algo_data->address; | 425 | uint16_t address = algo_data->address; |
| 434 | uint8_t msg[5]; | 426 | uint8_t msg[5]; |
| 435 | uint8_t reply[2]; | 427 | uint8_t reply[2]; |
| @@ -468,7 +460,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
| 468 | } | 460 | } |
| 469 | 461 | ||
| 470 | for (;;) { | 462 | for (;;) { |
| 471 | ret = intel_dp_aux_ch(intel_encoder, | 463 | ret = intel_dp_aux_ch(intel_dp, |
| 472 | msg, msg_bytes, | 464 | msg, msg_bytes, |
| 473 | reply, reply_bytes); | 465 | reply, reply_bytes); |
| 474 | if (ret < 0) { | 466 | if (ret < 0) { |
| @@ -496,57 +488,42 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
| 496 | } | 488 | } |
| 497 | 489 | ||
| 498 | static int | 490 | static int |
| 499 | intel_dp_i2c_init(struct intel_encoder *intel_encoder, | 491 | intel_dp_i2c_init(struct intel_dp *intel_dp, |
| 500 | struct intel_connector *intel_connector, const char *name) | 492 | struct intel_connector *intel_connector, const char *name) |
| 501 | { | 493 | { |
| 502 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 503 | |||
| 504 | DRM_DEBUG_KMS("i2c_init %s\n", name); | 494 | DRM_DEBUG_KMS("i2c_init %s\n", name); |
| 505 | dp_priv->algo.running = false; | 495 | intel_dp->algo.running = false; |
| 506 | dp_priv->algo.address = 0; | 496 | intel_dp->algo.address = 0; |
| 507 | dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; | 497 | intel_dp->algo.aux_ch = intel_dp_i2c_aux_ch; |
| 508 | 498 | ||
| 509 | memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); | 499 | memset(&intel_dp->adapter, '\0', sizeof (intel_dp->adapter)); |
| 510 | dp_priv->adapter.owner = THIS_MODULE; | 500 | intel_dp->adapter.owner = THIS_MODULE; |
| 511 | dp_priv->adapter.class = I2C_CLASS_DDC; | 501 | intel_dp->adapter.class = I2C_CLASS_DDC; |
| 512 | strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); | 502 | strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1); |
| 513 | dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; | 503 | intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0'; |
| 514 | dp_priv->adapter.algo_data = &dp_priv->algo; | 504 | intel_dp->adapter.algo_data = &intel_dp->algo; |
| 515 | dp_priv->adapter.dev.parent = &intel_connector->base.kdev; | 505 | intel_dp->adapter.dev.parent = &intel_connector->base.kdev; |
| 516 | 506 | ||
| 517 | return i2c_dp_aux_add_bus(&dp_priv->adapter); | 507 | return i2c_dp_aux_add_bus(&intel_dp->adapter); |
| 518 | } | 508 | } |
| 519 | 509 | ||
| 520 | static bool | 510 | static bool |
| 521 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 511 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, |
| 522 | struct drm_display_mode *adjusted_mode) | 512 | struct drm_display_mode *adjusted_mode) |
| 523 | { | 513 | { |
| 524 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 525 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 526 | struct drm_device *dev = encoder->dev; | 514 | struct drm_device *dev = encoder->dev; |
| 527 | struct drm_i915_private *dev_priv = dev->dev_private; | 515 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 516 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
| 528 | int lane_count, clock; | 517 | int lane_count, clock; |
| 529 | int max_lane_count = intel_dp_max_lane_count(intel_encoder); | 518 | int max_lane_count = intel_dp_max_lane_count(intel_dp); |
| 530 | int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; | 519 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; |
| 531 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 520 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
| 532 | 521 | ||
| 533 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 522 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
| 534 | dev_priv->panel_fixed_mode) { | 523 | dev_priv->panel_fixed_mode) { |
| 535 | struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; | 524 | intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); |
| 536 | 525 | intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, | |
| 537 | adjusted_mode->hdisplay = fixed_mode->hdisplay; | 526 | mode, adjusted_mode); |
| 538 | adjusted_mode->hsync_start = fixed_mode->hsync_start; | ||
| 539 | adjusted_mode->hsync_end = fixed_mode->hsync_end; | ||
| 540 | adjusted_mode->htotal = fixed_mode->htotal; | ||
| 541 | |||
| 542 | adjusted_mode->vdisplay = fixed_mode->vdisplay; | ||
| 543 | adjusted_mode->vsync_start = fixed_mode->vsync_start; | ||
| 544 | adjusted_mode->vsync_end = fixed_mode->vsync_end; | ||
| 545 | adjusted_mode->vtotal = fixed_mode->vtotal; | ||
| 546 | |||
| 547 | adjusted_mode->clock = fixed_mode->clock; | ||
| 548 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
| 549 | |||
| 550 | /* | 527 | /* |
| 551 | * the mode->clock is used to calculate the Data&Link M/N | 528 | * the mode->clock is used to calculate the Data&Link M/N |
| 552 | * of the pipe. For the eDP the fixed clock should be used. | 529 | * of the pipe. For the eDP the fixed clock should be used. |
| @@ -558,31 +535,33 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 558 | for (clock = 0; clock <= max_clock; clock++) { | 535 | for (clock = 0; clock <= max_clock; clock++) { |
| 559 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 536 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
| 560 | 537 | ||
| 561 | if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) | 538 | if (intel_dp_link_required(encoder->dev, intel_dp, mode->clock) |
| 562 | <= link_avail) { | 539 | <= link_avail) { |
| 563 | dp_priv->link_bw = bws[clock]; | 540 | intel_dp->link_bw = bws[clock]; |
| 564 | dp_priv->lane_count = lane_count; | 541 | intel_dp->lane_count = lane_count; |
| 565 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 542 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); |
| 566 | DRM_DEBUG_KMS("Display port link bw %02x lane " | 543 | DRM_DEBUG_KMS("Display port link bw %02x lane " |
| 567 | "count %d clock %d\n", | 544 | "count %d clock %d\n", |
| 568 | dp_priv->link_bw, dp_priv->lane_count, | 545 | intel_dp->link_bw, intel_dp->lane_count, |
| 569 | adjusted_mode->clock); | 546 | adjusted_mode->clock); |
| 570 | return true; | 547 | return true; |
| 571 | } | 548 | } |
| 572 | } | 549 | } |
| 573 | } | 550 | } |
| 574 | 551 | ||
| 575 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 552 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
| 576 | /* okay we failed just pick the highest */ | 553 | /* okay we failed just pick the highest */ |
| 577 | dp_priv->lane_count = max_lane_count; | 554 | intel_dp->lane_count = max_lane_count; |
| 578 | dp_priv->link_bw = bws[max_clock]; | 555 | intel_dp->link_bw = bws[max_clock]; |
| 579 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 556 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); |
| 580 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " | 557 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " |
| 581 | "count %d clock %d\n", | 558 | "count %d clock %d\n", |
| 582 | dp_priv->link_bw, dp_priv->lane_count, | 559 | intel_dp->link_bw, intel_dp->lane_count, |
| 583 | adjusted_mode->clock); | 560 | adjusted_mode->clock); |
| 561 | |||
| 584 | return true; | 562 | return true; |
| 585 | } | 563 | } |
| 564 | |||
| 586 | return false; | 565 | return false; |
| 587 | } | 566 | } |
| 588 | 567 | ||
| @@ -626,17 +605,14 @@ bool intel_pch_has_edp(struct drm_crtc *crtc) | |||
| 626 | struct drm_encoder *encoder; | 605 | struct drm_encoder *encoder; |
| 627 | 606 | ||
| 628 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 607 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
| 629 | struct intel_encoder *intel_encoder; | 608 | struct intel_dp *intel_dp; |
| 630 | struct intel_dp_priv *dp_priv; | ||
| 631 | 609 | ||
| 632 | if (!encoder || encoder->crtc != crtc) | 610 | if (encoder->crtc != crtc) |
| 633 | continue; | 611 | continue; |
| 634 | 612 | ||
| 635 | intel_encoder = enc_to_intel_encoder(encoder); | 613 | intel_dp = enc_to_intel_dp(encoder); |
| 636 | dp_priv = intel_encoder->dev_priv; | 614 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) |
| 637 | 615 | return intel_dp->is_pch_edp; | |
| 638 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) | ||
| 639 | return dp_priv->is_pch_edp; | ||
| 640 | } | 616 | } |
| 641 | return false; | 617 | return false; |
| 642 | } | 618 | } |
| @@ -657,18 +633,15 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
| 657 | * Find the lane count in the intel_encoder private | 633 | * Find the lane count in the intel_encoder private |
| 658 | */ | 634 | */ |
| 659 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 635 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
| 660 | struct intel_encoder *intel_encoder; | 636 | struct intel_dp *intel_dp; |
| 661 | struct intel_dp_priv *dp_priv; | ||
| 662 | 637 | ||
| 663 | if (encoder->crtc != crtc) | 638 | if (encoder->crtc != crtc) |
| 664 | continue; | 639 | continue; |
| 665 | 640 | ||
| 666 | intel_encoder = enc_to_intel_encoder(encoder); | 641 | intel_dp = enc_to_intel_dp(encoder); |
| 667 | dp_priv = intel_encoder->dev_priv; | 642 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) { |
| 668 | 643 | lane_count = intel_dp->lane_count; | |
| 669 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 644 | if (IS_PCH_eDP(intel_dp)) |
| 670 | lane_count = dp_priv->lane_count; | ||
| 671 | if (IS_PCH_eDP(dp_priv)) | ||
| 672 | bpp = dev_priv->edp_bpp; | 645 | bpp = dev_priv->edp_bpp; |
| 673 | break; | 646 | break; |
| 674 | } | 647 | } |
| @@ -724,107 +697,114 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 724 | struct drm_display_mode *adjusted_mode) | 697 | struct drm_display_mode *adjusted_mode) |
| 725 | { | 698 | { |
| 726 | struct drm_device *dev = encoder->dev; | 699 | struct drm_device *dev = encoder->dev; |
| 727 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 700 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 728 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 701 | struct drm_crtc *crtc = intel_dp->base.enc.crtc; |
| 729 | struct drm_crtc *crtc = intel_encoder->enc.crtc; | ||
| 730 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 702 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 731 | 703 | ||
| 732 | dp_priv->DP = (DP_VOLTAGE_0_4 | | 704 | intel_dp->DP = (DP_VOLTAGE_0_4 | |
| 733 | DP_PRE_EMPHASIS_0); | 705 | DP_PRE_EMPHASIS_0); |
| 734 | 706 | ||
| 735 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 707 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
| 736 | dp_priv->DP |= DP_SYNC_HS_HIGH; | 708 | intel_dp->DP |= DP_SYNC_HS_HIGH; |
| 737 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 709 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
| 738 | dp_priv->DP |= DP_SYNC_VS_HIGH; | 710 | intel_dp->DP |= DP_SYNC_VS_HIGH; |
| 739 | 711 | ||
| 740 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 712 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
| 741 | dp_priv->DP |= DP_LINK_TRAIN_OFF_CPT; | 713 | intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; |
| 742 | else | 714 | else |
| 743 | dp_priv->DP |= DP_LINK_TRAIN_OFF; | 715 | intel_dp->DP |= DP_LINK_TRAIN_OFF; |
| 744 | 716 | ||
| 745 | switch (dp_priv->lane_count) { | 717 | switch (intel_dp->lane_count) { |
| 746 | case 1: | 718 | case 1: |
| 747 | dp_priv->DP |= DP_PORT_WIDTH_1; | 719 | intel_dp->DP |= DP_PORT_WIDTH_1; |
| 748 | break; | 720 | break; |
| 749 | case 2: | 721 | case 2: |
| 750 | dp_priv->DP |= DP_PORT_WIDTH_2; | 722 | intel_dp->DP |= DP_PORT_WIDTH_2; |
| 751 | break; | 723 | break; |
| 752 | case 4: | 724 | case 4: |
| 753 | dp_priv->DP |= DP_PORT_WIDTH_4; | 725 | intel_dp->DP |= DP_PORT_WIDTH_4; |
| 754 | break; | 726 | break; |
| 755 | } | 727 | } |
| 756 | if (dp_priv->has_audio) | 728 | if (intel_dp->has_audio) |
| 757 | dp_priv->DP |= DP_AUDIO_OUTPUT_ENABLE; | 729 | intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; |
| 758 | 730 | ||
| 759 | memset(dp_priv->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | 731 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); |
| 760 | dp_priv->link_configuration[0] = dp_priv->link_bw; | 732 | intel_dp->link_configuration[0] = intel_dp->link_bw; |
| 761 | dp_priv->link_configuration[1] = dp_priv->lane_count; | 733 | intel_dp->link_configuration[1] = intel_dp->lane_count; |
| 762 | 734 | ||
| 763 | /* | 735 | /* |
| 764 | * Check for DPCD version > 1.1 and enhanced framing support | 736 | * Check for DPCD version > 1.1 and enhanced framing support |
| 765 | */ | 737 | */ |
| 766 | if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { | 738 | if (intel_dp->dpcd[0] >= 0x11 && (intel_dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { |
| 767 | dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 739 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
| 768 | dp_priv->DP |= DP_ENHANCED_FRAMING; | 740 | intel_dp->DP |= DP_ENHANCED_FRAMING; |
| 769 | } | 741 | } |
| 770 | 742 | ||
| 771 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ | 743 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ |
| 772 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) | 744 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) |
| 773 | dp_priv->DP |= DP_PIPEB_SELECT; | 745 | intel_dp->DP |= DP_PIPEB_SELECT; |
| 774 | 746 | ||
| 775 | if (IS_eDP(intel_encoder)) { | 747 | if (IS_eDP(intel_dp)) { |
| 776 | /* don't miss out required setting for eDP */ | 748 | /* don't miss out required setting for eDP */ |
| 777 | dp_priv->DP |= DP_PLL_ENABLE; | 749 | intel_dp->DP |= DP_PLL_ENABLE; |
| 778 | if (adjusted_mode->clock < 200000) | 750 | if (adjusted_mode->clock < 200000) |
| 779 | dp_priv->DP |= DP_PLL_FREQ_160MHZ; | 751 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; |
| 780 | else | 752 | else |
| 781 | dp_priv->DP |= DP_PLL_FREQ_270MHZ; | 753 | intel_dp->DP |= DP_PLL_FREQ_270MHZ; |
| 782 | } | 754 | } |
| 783 | } | 755 | } |
| 784 | 756 | ||
| 785 | static void ironlake_edp_panel_on (struct drm_device *dev) | 757 | static void ironlake_edp_panel_on (struct drm_device *dev) |
| 786 | { | 758 | { |
| 787 | struct drm_i915_private *dev_priv = dev->dev_private; | 759 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 788 | unsigned long timeout = jiffies + msecs_to_jiffies(5000); | 760 | u32 pp; |
| 789 | u32 pp, pp_status; | ||
| 790 | 761 | ||
| 791 | pp_status = I915_READ(PCH_PP_STATUS); | 762 | if (I915_READ(PCH_PP_STATUS) & PP_ON) |
| 792 | if (pp_status & PP_ON) | ||
| 793 | return; | 763 | return; |
| 794 | 764 | ||
| 795 | pp = I915_READ(PCH_PP_CONTROL); | 765 | pp = I915_READ(PCH_PP_CONTROL); |
| 766 | |||
| 767 | /* ILK workaround: disable reset around power sequence */ | ||
| 768 | pp &= ~PANEL_POWER_RESET; | ||
| 769 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
| 770 | POSTING_READ(PCH_PP_CONTROL); | ||
| 771 | |||
| 796 | pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON; | 772 | pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON; |
| 797 | I915_WRITE(PCH_PP_CONTROL, pp); | 773 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 798 | do { | ||
| 799 | pp_status = I915_READ(PCH_PP_STATUS); | ||
| 800 | } while (((pp_status & PP_ON) == 0) && !time_after(jiffies, timeout)); | ||
| 801 | 774 | ||
| 802 | if (time_after(jiffies, timeout)) | 775 | if (wait_for(I915_READ(PCH_PP_STATUS) & PP_ON, 5000, 10)) |
| 803 | DRM_DEBUG_KMS("panel on wait timed out: 0x%08x\n", pp_status); | 776 | DRM_ERROR("panel on wait timed out: 0x%08x\n", |
| 777 | I915_READ(PCH_PP_STATUS)); | ||
| 804 | 778 | ||
| 805 | pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD); | 779 | pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD); |
| 780 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ | ||
| 806 | I915_WRITE(PCH_PP_CONTROL, pp); | 781 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 782 | POSTING_READ(PCH_PP_CONTROL); | ||
| 807 | } | 783 | } |
| 808 | 784 | ||
| 809 | static void ironlake_edp_panel_off (struct drm_device *dev) | 785 | static void ironlake_edp_panel_off (struct drm_device *dev) |
| 810 | { | 786 | { |
| 811 | struct drm_i915_private *dev_priv = dev->dev_private; | 787 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 812 | unsigned long timeout = jiffies + msecs_to_jiffies(5000); | 788 | u32 pp; |
| 813 | u32 pp, pp_status; | ||
| 814 | 789 | ||
| 815 | pp = I915_READ(PCH_PP_CONTROL); | 790 | pp = I915_READ(PCH_PP_CONTROL); |
| 791 | |||
| 792 | /* ILK workaround: disable reset around power sequence */ | ||
| 793 | pp &= ~PANEL_POWER_RESET; | ||
| 794 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
| 795 | POSTING_READ(PCH_PP_CONTROL); | ||
| 796 | |||
| 816 | pp &= ~POWER_TARGET_ON; | 797 | pp &= ~POWER_TARGET_ON; |
| 817 | I915_WRITE(PCH_PP_CONTROL, pp); | 798 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 818 | do { | ||
| 819 | pp_status = I915_READ(PCH_PP_STATUS); | ||
| 820 | } while ((pp_status & PP_ON) && !time_after(jiffies, timeout)); | ||
| 821 | 799 | ||
| 822 | if (time_after(jiffies, timeout)) | 800 | if (wait_for((I915_READ(PCH_PP_STATUS) & PP_ON) == 0, 5000, 10)) |
| 823 | DRM_DEBUG_KMS("panel off wait timed out\n"); | 801 | DRM_ERROR("panel off wait timed out: 0x%08x\n", |
| 802 | I915_READ(PCH_PP_STATUS)); | ||
| 824 | 803 | ||
| 825 | /* Make sure VDD is enabled so DP AUX will work */ | 804 | /* Make sure VDD is enabled so DP AUX will work */ |
| 826 | pp |= EDP_FORCE_VDD; | 805 | pp |= EDP_FORCE_VDD | PANEL_POWER_RESET; /* restore panel reset bit */ |
| 827 | I915_WRITE(PCH_PP_CONTROL, pp); | 806 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 807 | POSTING_READ(PCH_PP_CONTROL); | ||
| 828 | } | 808 | } |
| 829 | 809 | ||
| 830 | static void ironlake_edp_backlight_on (struct drm_device *dev) | 810 | static void ironlake_edp_backlight_on (struct drm_device *dev) |
| @@ -849,33 +829,87 @@ static void ironlake_edp_backlight_off (struct drm_device *dev) | |||
| 849 | I915_WRITE(PCH_PP_CONTROL, pp); | 829 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 850 | } | 830 | } |
| 851 | 831 | ||
| 832 | static void ironlake_edp_pll_on(struct drm_encoder *encoder) | ||
| 833 | { | ||
| 834 | struct drm_device *dev = encoder->dev; | ||
| 835 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 836 | u32 dpa_ctl; | ||
| 837 | |||
| 838 | DRM_DEBUG_KMS("\n"); | ||
| 839 | dpa_ctl = I915_READ(DP_A); | ||
| 840 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
| 841 | I915_WRITE(DP_A, dpa_ctl); | ||
| 842 | } | ||
| 843 | |||
| 844 | static void ironlake_edp_pll_off(struct drm_encoder *encoder) | ||
| 845 | { | ||
| 846 | struct drm_device *dev = encoder->dev; | ||
| 847 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 848 | u32 dpa_ctl; | ||
| 849 | |||
| 850 | dpa_ctl = I915_READ(DP_A); | ||
| 851 | dpa_ctl |= DP_PLL_ENABLE; | ||
| 852 | I915_WRITE(DP_A, dpa_ctl); | ||
| 853 | udelay(200); | ||
| 854 | } | ||
| 855 | |||
| 856 | static void intel_dp_prepare(struct drm_encoder *encoder) | ||
| 857 | { | ||
| 858 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
| 859 | struct drm_device *dev = encoder->dev; | ||
| 860 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 861 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | ||
| 862 | |||
| 863 | if (IS_eDP(intel_dp)) { | ||
| 864 | ironlake_edp_backlight_off(dev); | ||
| 865 | ironlake_edp_panel_on(dev); | ||
| 866 | ironlake_edp_pll_on(encoder); | ||
| 867 | } | ||
| 868 | if (dp_reg & DP_PORT_EN) | ||
| 869 | intel_dp_link_down(intel_dp); | ||
| 870 | } | ||
| 871 | |||
| 872 | static void intel_dp_commit(struct drm_encoder *encoder) | ||
| 873 | { | ||
| 874 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
| 875 | struct drm_device *dev = encoder->dev; | ||
| 876 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 877 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | ||
| 878 | |||
| 879 | if (!(dp_reg & DP_PORT_EN)) { | ||
| 880 | intel_dp_link_train(intel_dp); | ||
| 881 | } | ||
| 882 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
| 883 | ironlake_edp_backlight_on(dev); | ||
| 884 | } | ||
| 885 | |||
| 852 | static void | 886 | static void |
| 853 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | 887 | intel_dp_dpms(struct drm_encoder *encoder, int mode) |
| 854 | { | 888 | { |
| 855 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 889 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 856 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 857 | struct drm_device *dev = encoder->dev; | 890 | struct drm_device *dev = encoder->dev; |
| 858 | struct drm_i915_private *dev_priv = dev->dev_private; | 891 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 859 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | 892 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); |
| 860 | 893 | ||
| 861 | if (mode != DRM_MODE_DPMS_ON) { | 894 | if (mode != DRM_MODE_DPMS_ON) { |
| 862 | if (dp_reg & DP_PORT_EN) { | 895 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
| 863 | intel_dp_link_down(intel_encoder, dp_priv->DP); | 896 | ironlake_edp_backlight_off(dev); |
| 864 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 897 | ironlake_edp_panel_off(dev); |
| 865 | ironlake_edp_backlight_off(dev); | ||
| 866 | ironlake_edp_panel_off(dev); | ||
| 867 | } | ||
| 868 | } | 898 | } |
| 899 | if (dp_reg & DP_PORT_EN) | ||
| 900 | intel_dp_link_down(intel_dp); | ||
| 901 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
| 902 | ironlake_edp_pll_off(encoder); | ||
| 869 | } else { | 903 | } else { |
| 870 | if (!(dp_reg & DP_PORT_EN)) { | 904 | if (!(dp_reg & DP_PORT_EN)) { |
| 871 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); | 905 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
| 872 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | ||
| 873 | ironlake_edp_panel_on(dev); | 906 | ironlake_edp_panel_on(dev); |
| 907 | intel_dp_link_train(intel_dp); | ||
| 908 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
| 874 | ironlake_edp_backlight_on(dev); | 909 | ironlake_edp_backlight_on(dev); |
| 875 | } | ||
| 876 | } | 910 | } |
| 877 | } | 911 | } |
| 878 | dp_priv->dpms_mode = mode; | 912 | intel_dp->dpms_mode = mode; |
| 879 | } | 913 | } |
| 880 | 914 | ||
| 881 | /* | 915 | /* |
| @@ -883,12 +917,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
| 883 | * link status information | 917 | * link status information |
| 884 | */ | 918 | */ |
| 885 | static bool | 919 | static bool |
| 886 | intel_dp_get_link_status(struct intel_encoder *intel_encoder, | 920 | intel_dp_get_link_status(struct intel_dp *intel_dp, |
| 887 | uint8_t link_status[DP_LINK_STATUS_SIZE]) | 921 | uint8_t link_status[DP_LINK_STATUS_SIZE]) |
| 888 | { | 922 | { |
| 889 | int ret; | 923 | int ret; |
| 890 | 924 | ||
| 891 | ret = intel_dp_aux_native_read(intel_encoder, | 925 | ret = intel_dp_aux_native_read(intel_dp, |
| 892 | DP_LANE0_1_STATUS, | 926 | DP_LANE0_1_STATUS, |
| 893 | link_status, DP_LINK_STATUS_SIZE); | 927 | link_status, DP_LINK_STATUS_SIZE); |
| 894 | if (ret != DP_LINK_STATUS_SIZE) | 928 | if (ret != DP_LINK_STATUS_SIZE) |
| @@ -965,7 +999,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) | |||
| 965 | } | 999 | } |
| 966 | 1000 | ||
| 967 | static void | 1001 | static void |
| 968 | intel_get_adjust_train(struct intel_encoder *intel_encoder, | 1002 | intel_get_adjust_train(struct intel_dp *intel_dp, |
| 969 | uint8_t link_status[DP_LINK_STATUS_SIZE], | 1003 | uint8_t link_status[DP_LINK_STATUS_SIZE], |
| 970 | int lane_count, | 1004 | int lane_count, |
| 971 | uint8_t train_set[4]) | 1005 | uint8_t train_set[4]) |
| @@ -1101,27 +1135,23 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | |||
| 1101 | } | 1135 | } |
| 1102 | 1136 | ||
| 1103 | static bool | 1137 | static bool |
| 1104 | intel_dp_set_link_train(struct intel_encoder *intel_encoder, | 1138 | intel_dp_set_link_train(struct intel_dp *intel_dp, |
| 1105 | uint32_t dp_reg_value, | 1139 | uint32_t dp_reg_value, |
| 1106 | uint8_t dp_train_pat, | 1140 | uint8_t dp_train_pat, |
| 1107 | uint8_t train_set[4], | 1141 | uint8_t train_set[4]) |
| 1108 | bool first) | ||
| 1109 | { | 1142 | { |
| 1110 | struct drm_device *dev = intel_encoder->enc.dev; | 1143 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 1111 | struct drm_i915_private *dev_priv = dev->dev_private; | 1144 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1112 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1113 | int ret; | 1145 | int ret; |
| 1114 | 1146 | ||
| 1115 | I915_WRITE(dp_priv->output_reg, dp_reg_value); | 1147 | I915_WRITE(intel_dp->output_reg, dp_reg_value); |
| 1116 | POSTING_READ(dp_priv->output_reg); | 1148 | POSTING_READ(intel_dp->output_reg); |
| 1117 | if (first) | ||
| 1118 | intel_wait_for_vblank(dev); | ||
| 1119 | 1149 | ||
| 1120 | intel_dp_aux_native_write_1(intel_encoder, | 1150 | intel_dp_aux_native_write_1(intel_dp, |
| 1121 | DP_TRAINING_PATTERN_SET, | 1151 | DP_TRAINING_PATTERN_SET, |
| 1122 | dp_train_pat); | 1152 | dp_train_pat); |
| 1123 | 1153 | ||
| 1124 | ret = intel_dp_aux_native_write(intel_encoder, | 1154 | ret = intel_dp_aux_native_write(intel_dp, |
| 1125 | DP_TRAINING_LANE0_SET, train_set, 4); | 1155 | DP_TRAINING_LANE0_SET, train_set, 4); |
| 1126 | if (ret != 4) | 1156 | if (ret != 4) |
| 1127 | return false; | 1157 | return false; |
| @@ -1130,28 +1160,33 @@ intel_dp_set_link_train(struct intel_encoder *intel_encoder, | |||
| 1130 | } | 1160 | } |
| 1131 | 1161 | ||
| 1132 | static void | 1162 | static void |
| 1133 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | 1163 | intel_dp_link_train(struct intel_dp *intel_dp) |
| 1134 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) | ||
| 1135 | { | 1164 | { |
| 1136 | struct drm_device *dev = intel_encoder->enc.dev; | 1165 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 1137 | struct drm_i915_private *dev_priv = dev->dev_private; | 1166 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1138 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1139 | uint8_t train_set[4]; | 1167 | uint8_t train_set[4]; |
| 1140 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1168 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
| 1141 | int i; | 1169 | int i; |
| 1142 | uint8_t voltage; | 1170 | uint8_t voltage; |
| 1143 | bool clock_recovery = false; | 1171 | bool clock_recovery = false; |
| 1144 | bool channel_eq = false; | 1172 | bool channel_eq = false; |
| 1145 | bool first = true; | ||
| 1146 | int tries; | 1173 | int tries; |
| 1147 | u32 reg; | 1174 | u32 reg; |
| 1175 | uint32_t DP = intel_dp->DP; | ||
| 1176 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); | ||
| 1177 | |||
| 1178 | /* Enable output, wait for it to become active */ | ||
| 1179 | I915_WRITE(intel_dp->output_reg, intel_dp->DP); | ||
| 1180 | POSTING_READ(intel_dp->output_reg); | ||
| 1181 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
| 1148 | 1182 | ||
| 1149 | /* Write the link configuration data */ | 1183 | /* Write the link configuration data */ |
| 1150 | intel_dp_aux_native_write(intel_encoder, DP_LINK_BW_SET, | 1184 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, |
| 1151 | link_configuration, DP_LINK_CONFIGURATION_SIZE); | 1185 | intel_dp->link_configuration, |
| 1186 | DP_LINK_CONFIGURATION_SIZE); | ||
| 1152 | 1187 | ||
| 1153 | DP |= DP_PORT_EN; | 1188 | DP |= DP_PORT_EN; |
| 1154 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1189 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
| 1155 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1190 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
| 1156 | else | 1191 | else |
| 1157 | DP &= ~DP_LINK_TRAIN_MASK; | 1192 | DP &= ~DP_LINK_TRAIN_MASK; |
| @@ -1162,39 +1197,38 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
| 1162 | for (;;) { | 1197 | for (;;) { |
| 1163 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1198 | /* Use train_set[0] to set the voltage and pre emphasis values */ |
| 1164 | uint32_t signal_levels; | 1199 | uint32_t signal_levels; |
| 1165 | if (IS_GEN6(dev) && IS_eDP(intel_encoder)) { | 1200 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { |
| 1166 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | 1201 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); |
| 1167 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1202 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
| 1168 | } else { | 1203 | } else { |
| 1169 | signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1204 | signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count); |
| 1170 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1205 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
| 1171 | } | 1206 | } |
| 1172 | 1207 | ||
| 1173 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1208 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
| 1174 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; | 1209 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; |
| 1175 | else | 1210 | else |
| 1176 | reg = DP | DP_LINK_TRAIN_PAT_1; | 1211 | reg = DP | DP_LINK_TRAIN_PAT_1; |
| 1177 | 1212 | ||
| 1178 | if (!intel_dp_set_link_train(intel_encoder, reg, | 1213 | if (!intel_dp_set_link_train(intel_dp, reg, |
| 1179 | DP_TRAINING_PATTERN_1, train_set, first)) | 1214 | DP_TRAINING_PATTERN_1, train_set)) |
| 1180 | break; | 1215 | break; |
| 1181 | first = false; | ||
| 1182 | /* Set training pattern 1 */ | 1216 | /* Set training pattern 1 */ |
| 1183 | 1217 | ||
| 1184 | udelay(100); | 1218 | udelay(100); |
| 1185 | if (!intel_dp_get_link_status(intel_encoder, link_status)) | 1219 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
| 1186 | break; | 1220 | break; |
| 1187 | 1221 | ||
| 1188 | if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { | 1222 | if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { |
| 1189 | clock_recovery = true; | 1223 | clock_recovery = true; |
| 1190 | break; | 1224 | break; |
| 1191 | } | 1225 | } |
| 1192 | 1226 | ||
| 1193 | /* Check to see if we've tried the max voltage */ | 1227 | /* Check to see if we've tried the max voltage */ |
| 1194 | for (i = 0; i < dp_priv->lane_count; i++) | 1228 | for (i = 0; i < intel_dp->lane_count; i++) |
| 1195 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1229 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
| 1196 | break; | 1230 | break; |
| 1197 | if (i == dp_priv->lane_count) | 1231 | if (i == intel_dp->lane_count) |
| 1198 | break; | 1232 | break; |
| 1199 | 1233 | ||
| 1200 | /* Check to see if we've tried the same voltage 5 times */ | 1234 | /* Check to see if we've tried the same voltage 5 times */ |
| @@ -1207,7 +1241,7 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
| 1207 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1241 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
| 1208 | 1242 | ||
| 1209 | /* Compute new train_set as requested by target */ | 1243 | /* Compute new train_set as requested by target */ |
| 1210 | intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); | 1244 | intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set); |
| 1211 | } | 1245 | } |
| 1212 | 1246 | ||
| 1213 | /* channel equalization */ | 1247 | /* channel equalization */ |
| @@ -1217,30 +1251,29 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
| 1217 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1251 | /* Use train_set[0] to set the voltage and pre emphasis values */ |
| 1218 | uint32_t signal_levels; | 1252 | uint32_t signal_levels; |
| 1219 | 1253 | ||
| 1220 | if (IS_GEN6(dev) && IS_eDP(intel_encoder)) { | 1254 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { |
| 1221 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | 1255 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); |
| 1222 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1256 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
| 1223 | } else { | 1257 | } else { |
| 1224 | signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1258 | signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count); |
| 1225 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1259 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
| 1226 | } | 1260 | } |
| 1227 | 1261 | ||
| 1228 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1262 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
| 1229 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; | 1263 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; |
| 1230 | else | 1264 | else |
| 1231 | reg = DP | DP_LINK_TRAIN_PAT_2; | 1265 | reg = DP | DP_LINK_TRAIN_PAT_2; |
| 1232 | 1266 | ||
| 1233 | /* channel eq pattern */ | 1267 | /* channel eq pattern */ |
| 1234 | if (!intel_dp_set_link_train(intel_encoder, reg, | 1268 | if (!intel_dp_set_link_train(intel_dp, reg, |
| 1235 | DP_TRAINING_PATTERN_2, train_set, | 1269 | DP_TRAINING_PATTERN_2, train_set)) |
| 1236 | false)) | ||
| 1237 | break; | 1270 | break; |
| 1238 | 1271 | ||
| 1239 | udelay(400); | 1272 | udelay(400); |
| 1240 | if (!intel_dp_get_link_status(intel_encoder, link_status)) | 1273 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
| 1241 | break; | 1274 | break; |
| 1242 | 1275 | ||
| 1243 | if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { | 1276 | if (intel_channel_eq_ok(link_status, intel_dp->lane_count)) { |
| 1244 | channel_eq = true; | 1277 | channel_eq = true; |
| 1245 | break; | 1278 | break; |
| 1246 | } | 1279 | } |
| @@ -1250,53 +1283,53 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
| 1250 | break; | 1283 | break; |
| 1251 | 1284 | ||
| 1252 | /* Compute new train_set as requested by target */ | 1285 | /* Compute new train_set as requested by target */ |
| 1253 | intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); | 1286 | intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set); |
| 1254 | ++tries; | 1287 | ++tries; |
| 1255 | } | 1288 | } |
| 1256 | 1289 | ||
| 1257 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1290 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
| 1258 | reg = DP | DP_LINK_TRAIN_OFF_CPT; | 1291 | reg = DP | DP_LINK_TRAIN_OFF_CPT; |
| 1259 | else | 1292 | else |
| 1260 | reg = DP | DP_LINK_TRAIN_OFF; | 1293 | reg = DP | DP_LINK_TRAIN_OFF; |
| 1261 | 1294 | ||
| 1262 | I915_WRITE(dp_priv->output_reg, reg); | 1295 | I915_WRITE(intel_dp->output_reg, reg); |
| 1263 | POSTING_READ(dp_priv->output_reg); | 1296 | POSTING_READ(intel_dp->output_reg); |
| 1264 | intel_dp_aux_native_write_1(intel_encoder, | 1297 | intel_dp_aux_native_write_1(intel_dp, |
| 1265 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); | 1298 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); |
| 1266 | } | 1299 | } |
| 1267 | 1300 | ||
| 1268 | static void | 1301 | static void |
| 1269 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | 1302 | intel_dp_link_down(struct intel_dp *intel_dp) |
| 1270 | { | 1303 | { |
| 1271 | struct drm_device *dev = intel_encoder->enc.dev; | 1304 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 1272 | struct drm_i915_private *dev_priv = dev->dev_private; | 1305 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1273 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1306 | uint32_t DP = intel_dp->DP; |
| 1274 | 1307 | ||
| 1275 | DRM_DEBUG_KMS("\n"); | 1308 | DRM_DEBUG_KMS("\n"); |
| 1276 | 1309 | ||
| 1277 | if (IS_eDP(intel_encoder)) { | 1310 | if (IS_eDP(intel_dp)) { |
| 1278 | DP &= ~DP_PLL_ENABLE; | 1311 | DP &= ~DP_PLL_ENABLE; |
| 1279 | I915_WRITE(dp_priv->output_reg, DP); | 1312 | I915_WRITE(intel_dp->output_reg, DP); |
| 1280 | POSTING_READ(dp_priv->output_reg); | 1313 | POSTING_READ(intel_dp->output_reg); |
| 1281 | udelay(100); | 1314 | udelay(100); |
| 1282 | } | 1315 | } |
| 1283 | 1316 | ||
| 1284 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) { | 1317 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) { |
| 1285 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1318 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
| 1286 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); | 1319 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); |
| 1287 | POSTING_READ(dp_priv->output_reg); | 1320 | POSTING_READ(intel_dp->output_reg); |
| 1288 | } else { | 1321 | } else { |
| 1289 | DP &= ~DP_LINK_TRAIN_MASK; | 1322 | DP &= ~DP_LINK_TRAIN_MASK; |
| 1290 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | 1323 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); |
| 1291 | POSTING_READ(dp_priv->output_reg); | 1324 | POSTING_READ(intel_dp->output_reg); |
| 1292 | } | 1325 | } |
| 1293 | 1326 | ||
| 1294 | udelay(17000); | 1327 | udelay(17000); |
| 1295 | 1328 | ||
| 1296 | if (IS_eDP(intel_encoder)) | 1329 | if (IS_eDP(intel_dp)) |
| 1297 | DP |= DP_LINK_TRAIN_OFF; | 1330 | DP |= DP_LINK_TRAIN_OFF; |
| 1298 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); | 1331 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
| 1299 | POSTING_READ(dp_priv->output_reg); | 1332 | POSTING_READ(intel_dp->output_reg); |
| 1300 | } | 1333 | } |
| 1301 | 1334 | ||
| 1302 | /* | 1335 | /* |
| @@ -1309,41 +1342,39 @@ intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | |||
| 1309 | */ | 1342 | */ |
| 1310 | 1343 | ||
| 1311 | static void | 1344 | static void |
| 1312 | intel_dp_check_link_status(struct intel_encoder *intel_encoder) | 1345 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
| 1313 | { | 1346 | { |
| 1314 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1315 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1347 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
| 1316 | 1348 | ||
| 1317 | if (!intel_encoder->enc.crtc) | 1349 | if (!intel_dp->base.enc.crtc) |
| 1318 | return; | 1350 | return; |
| 1319 | 1351 | ||
| 1320 | if (!intel_dp_get_link_status(intel_encoder, link_status)) { | 1352 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
| 1321 | intel_dp_link_down(intel_encoder, dp_priv->DP); | 1353 | intel_dp_link_down(intel_dp); |
| 1322 | return; | 1354 | return; |
| 1323 | } | 1355 | } |
| 1324 | 1356 | ||
| 1325 | if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) | 1357 | if (!intel_channel_eq_ok(link_status, intel_dp->lane_count)) |
| 1326 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); | 1358 | intel_dp_link_train(intel_dp); |
| 1327 | } | 1359 | } |
| 1328 | 1360 | ||
| 1329 | static enum drm_connector_status | 1361 | static enum drm_connector_status |
| 1330 | ironlake_dp_detect(struct drm_connector *connector) | 1362 | ironlake_dp_detect(struct drm_connector *connector) |
| 1331 | { | 1363 | { |
| 1332 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1364 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1333 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1365 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 1334 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1335 | enum drm_connector_status status; | 1366 | enum drm_connector_status status; |
| 1336 | 1367 | ||
| 1337 | status = connector_status_disconnected; | 1368 | status = connector_status_disconnected; |
| 1338 | if (intel_dp_aux_native_read(intel_encoder, | 1369 | if (intel_dp_aux_native_read(intel_dp, |
| 1339 | 0x000, dp_priv->dpcd, | 1370 | 0x000, intel_dp->dpcd, |
| 1340 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | 1371 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
| 1341 | { | 1372 | { |
| 1342 | if (dp_priv->dpcd[0] != 0) | 1373 | if (intel_dp->dpcd[0] != 0) |
| 1343 | status = connector_status_connected; | 1374 | status = connector_status_connected; |
| 1344 | } | 1375 | } |
| 1345 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0], | 1376 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], |
| 1346 | dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]); | 1377 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); |
| 1347 | return status; | 1378 | return status; |
| 1348 | } | 1379 | } |
| 1349 | 1380 | ||
| @@ -1354,22 +1385,21 @@ ironlake_dp_detect(struct drm_connector *connector) | |||
| 1354 | * \return false if DP port is disconnected. | 1385 | * \return false if DP port is disconnected. |
| 1355 | */ | 1386 | */ |
| 1356 | static enum drm_connector_status | 1387 | static enum drm_connector_status |
| 1357 | intel_dp_detect(struct drm_connector *connector) | 1388 | intel_dp_detect(struct drm_connector *connector, bool force) |
| 1358 | { | 1389 | { |
| 1359 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1390 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1360 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1391 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 1361 | struct drm_device *dev = intel_encoder->enc.dev; | 1392 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 1362 | struct drm_i915_private *dev_priv = dev->dev_private; | 1393 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1363 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1364 | uint32_t temp, bit; | 1394 | uint32_t temp, bit; |
| 1365 | enum drm_connector_status status; | 1395 | enum drm_connector_status status; |
| 1366 | 1396 | ||
| 1367 | dp_priv->has_audio = false; | 1397 | intel_dp->has_audio = false; |
| 1368 | 1398 | ||
| 1369 | if (HAS_PCH_SPLIT(dev)) | 1399 | if (HAS_PCH_SPLIT(dev)) |
| 1370 | return ironlake_dp_detect(connector); | 1400 | return ironlake_dp_detect(connector); |
| 1371 | 1401 | ||
| 1372 | switch (dp_priv->output_reg) { | 1402 | switch (intel_dp->output_reg) { |
| 1373 | case DP_B: | 1403 | case DP_B: |
| 1374 | bit = DPB_HOTPLUG_INT_STATUS; | 1404 | bit = DPB_HOTPLUG_INT_STATUS; |
| 1375 | break; | 1405 | break; |
| @@ -1389,11 +1419,11 @@ intel_dp_detect(struct drm_connector *connector) | |||
| 1389 | return connector_status_disconnected; | 1419 | return connector_status_disconnected; |
| 1390 | 1420 | ||
| 1391 | status = connector_status_disconnected; | 1421 | status = connector_status_disconnected; |
| 1392 | if (intel_dp_aux_native_read(intel_encoder, | 1422 | if (intel_dp_aux_native_read(intel_dp, |
| 1393 | 0x000, dp_priv->dpcd, | 1423 | 0x000, intel_dp->dpcd, |
| 1394 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | 1424 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
| 1395 | { | 1425 | { |
| 1396 | if (dp_priv->dpcd[0] != 0) | 1426 | if (intel_dp->dpcd[0] != 0) |
| 1397 | status = connector_status_connected; | 1427 | status = connector_status_connected; |
| 1398 | } | 1428 | } |
| 1399 | return status; | 1429 | return status; |
| @@ -1402,18 +1432,17 @@ intel_dp_detect(struct drm_connector *connector) | |||
| 1402 | static int intel_dp_get_modes(struct drm_connector *connector) | 1432 | static int intel_dp_get_modes(struct drm_connector *connector) |
| 1403 | { | 1433 | { |
| 1404 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1434 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1405 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1435 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 1406 | struct drm_device *dev = intel_encoder->enc.dev; | 1436 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 1407 | struct drm_i915_private *dev_priv = dev->dev_private; | 1437 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1408 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1409 | int ret; | 1438 | int ret; |
| 1410 | 1439 | ||
| 1411 | /* We should parse the EDID data and find out if it has an audio sink | 1440 | /* We should parse the EDID data and find out if it has an audio sink |
| 1412 | */ | 1441 | */ |
| 1413 | 1442 | ||
| 1414 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1443 | ret = intel_ddc_get_modes(connector, intel_dp->base.ddc_bus); |
| 1415 | if (ret) { | 1444 | if (ret) { |
| 1416 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 1445 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
| 1417 | !dev_priv->panel_fixed_mode) { | 1446 | !dev_priv->panel_fixed_mode) { |
| 1418 | struct drm_display_mode *newmode; | 1447 | struct drm_display_mode *newmode; |
| 1419 | list_for_each_entry(newmode, &connector->probed_modes, | 1448 | list_for_each_entry(newmode, &connector->probed_modes, |
| @@ -1430,7 +1459,7 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
| 1430 | } | 1459 | } |
| 1431 | 1460 | ||
| 1432 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ | 1461 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ |
| 1433 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 1462 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
| 1434 | if (dev_priv->panel_fixed_mode != NULL) { | 1463 | if (dev_priv->panel_fixed_mode != NULL) { |
| 1435 | struct drm_display_mode *mode; | 1464 | struct drm_display_mode *mode; |
| 1436 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | 1465 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); |
| @@ -1452,9 +1481,9 @@ intel_dp_destroy (struct drm_connector *connector) | |||
| 1452 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | 1481 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { |
| 1453 | .dpms = intel_dp_dpms, | 1482 | .dpms = intel_dp_dpms, |
| 1454 | .mode_fixup = intel_dp_mode_fixup, | 1483 | .mode_fixup = intel_dp_mode_fixup, |
| 1455 | .prepare = intel_encoder_prepare, | 1484 | .prepare = intel_dp_prepare, |
| 1456 | .mode_set = intel_dp_mode_set, | 1485 | .mode_set = intel_dp_mode_set, |
| 1457 | .commit = intel_encoder_commit, | 1486 | .commit = intel_dp_commit, |
| 1458 | }; | 1487 | }; |
| 1459 | 1488 | ||
| 1460 | static const struct drm_connector_funcs intel_dp_connector_funcs = { | 1489 | static const struct drm_connector_funcs intel_dp_connector_funcs = { |
| @@ -1470,27 +1499,17 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = | |||
| 1470 | .best_encoder = intel_attached_encoder, | 1499 | .best_encoder = intel_attached_encoder, |
| 1471 | }; | 1500 | }; |
| 1472 | 1501 | ||
| 1473 | static void intel_dp_enc_destroy(struct drm_encoder *encoder) | ||
| 1474 | { | ||
| 1475 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 1476 | |||
| 1477 | if (intel_encoder->i2c_bus) | ||
| 1478 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
| 1479 | drm_encoder_cleanup(encoder); | ||
| 1480 | kfree(intel_encoder); | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { | 1502 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { |
| 1484 | .destroy = intel_dp_enc_destroy, | 1503 | .destroy = intel_encoder_destroy, |
| 1485 | }; | 1504 | }; |
| 1486 | 1505 | ||
| 1487 | void | 1506 | void |
| 1488 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) | 1507 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) |
| 1489 | { | 1508 | { |
| 1490 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1509 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
| 1491 | 1510 | ||
| 1492 | if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) | 1511 | if (intel_dp->dpms_mode == DRM_MODE_DPMS_ON) |
| 1493 | intel_dp_check_link_status(intel_encoder); | 1512 | intel_dp_check_link_status(intel_dp); |
| 1494 | } | 1513 | } |
| 1495 | 1514 | ||
| 1496 | /* Return which DP Port should be selected for Transcoder DP control */ | 1515 | /* Return which DP Port should be selected for Transcoder DP control */ |
| @@ -1500,18 +1519,18 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) | |||
| 1500 | struct drm_device *dev = crtc->dev; | 1519 | struct drm_device *dev = crtc->dev; |
| 1501 | struct drm_mode_config *mode_config = &dev->mode_config; | 1520 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 1502 | struct drm_encoder *encoder; | 1521 | struct drm_encoder *encoder; |
| 1503 | struct intel_encoder *intel_encoder = NULL; | ||
| 1504 | 1522 | ||
| 1505 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 1523 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
| 1524 | struct intel_dp *intel_dp; | ||
| 1525 | |||
| 1506 | if (encoder->crtc != crtc) | 1526 | if (encoder->crtc != crtc) |
| 1507 | continue; | 1527 | continue; |
| 1508 | 1528 | ||
| 1509 | intel_encoder = enc_to_intel_encoder(encoder); | 1529 | intel_dp = enc_to_intel_dp(encoder); |
| 1510 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 1530 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) |
| 1511 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1531 | return intel_dp->output_reg; |
| 1512 | return dp_priv->output_reg; | ||
| 1513 | } | ||
| 1514 | } | 1532 | } |
| 1533 | |||
| 1515 | return -1; | 1534 | return -1; |
| 1516 | } | 1535 | } |
| 1517 | 1536 | ||
| @@ -1540,30 +1559,28 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
| 1540 | { | 1559 | { |
| 1541 | struct drm_i915_private *dev_priv = dev->dev_private; | 1560 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1542 | struct drm_connector *connector; | 1561 | struct drm_connector *connector; |
| 1562 | struct intel_dp *intel_dp; | ||
| 1543 | struct intel_encoder *intel_encoder; | 1563 | struct intel_encoder *intel_encoder; |
| 1544 | struct intel_connector *intel_connector; | 1564 | struct intel_connector *intel_connector; |
| 1545 | struct intel_dp_priv *dp_priv; | ||
| 1546 | const char *name = NULL; | 1565 | const char *name = NULL; |
| 1547 | int type; | 1566 | int type; |
| 1548 | 1567 | ||
| 1549 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + | 1568 | intel_dp = kzalloc(sizeof(struct intel_dp), GFP_KERNEL); |
| 1550 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | 1569 | if (!intel_dp) |
| 1551 | if (!intel_encoder) | ||
| 1552 | return; | 1570 | return; |
| 1553 | 1571 | ||
| 1554 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1572 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 1555 | if (!intel_connector) { | 1573 | if (!intel_connector) { |
| 1556 | kfree(intel_encoder); | 1574 | kfree(intel_dp); |
| 1557 | return; | 1575 | return; |
| 1558 | } | 1576 | } |
| 1577 | intel_encoder = &intel_dp->base; | ||
| 1559 | 1578 | ||
| 1560 | dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); | 1579 | if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D) |
| 1561 | |||
| 1562 | if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D)) | ||
| 1563 | if (intel_dpd_is_edp(dev)) | 1580 | if (intel_dpd_is_edp(dev)) |
| 1564 | dp_priv->is_pch_edp = true; | 1581 | intel_dp->is_pch_edp = true; |
| 1565 | 1582 | ||
| 1566 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { | 1583 | if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) { |
| 1567 | type = DRM_MODE_CONNECTOR_eDP; | 1584 | type = DRM_MODE_CONNECTOR_eDP; |
| 1568 | intel_encoder->type = INTEL_OUTPUT_EDP; | 1585 | intel_encoder->type = INTEL_OUTPUT_EDP; |
| 1569 | } else { | 1586 | } else { |
| @@ -1584,18 +1601,16 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
| 1584 | else if (output_reg == DP_D || output_reg == PCH_DP_D) | 1601 | else if (output_reg == DP_D || output_reg == PCH_DP_D) |
| 1585 | intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); | 1602 | intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); |
| 1586 | 1603 | ||
| 1587 | if (IS_eDP(intel_encoder)) | 1604 | if (IS_eDP(intel_dp)) |
| 1588 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); | 1605 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); |
| 1589 | 1606 | ||
| 1590 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1607 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
| 1591 | connector->interlace_allowed = true; | 1608 | connector->interlace_allowed = true; |
| 1592 | connector->doublescan_allowed = 0; | 1609 | connector->doublescan_allowed = 0; |
| 1593 | 1610 | ||
| 1594 | dp_priv->intel_encoder = intel_encoder; | 1611 | intel_dp->output_reg = output_reg; |
| 1595 | dp_priv->output_reg = output_reg; | 1612 | intel_dp->has_audio = false; |
| 1596 | dp_priv->has_audio = false; | 1613 | intel_dp->dpms_mode = DRM_MODE_DPMS_ON; |
| 1597 | dp_priv->dpms_mode = DRM_MODE_DPMS_ON; | ||
| 1598 | intel_encoder->dev_priv = dp_priv; | ||
| 1599 | 1614 | ||
| 1600 | drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, | 1615 | drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, |
| 1601 | DRM_MODE_ENCODER_TMDS); | 1616 | DRM_MODE_ENCODER_TMDS); |
| @@ -1630,12 +1645,12 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
| 1630 | break; | 1645 | break; |
| 1631 | } | 1646 | } |
| 1632 | 1647 | ||
| 1633 | intel_dp_i2c_init(intel_encoder, intel_connector, name); | 1648 | intel_dp_i2c_init(intel_dp, intel_connector, name); |
| 1634 | 1649 | ||
| 1635 | intel_encoder->ddc_bus = &dp_priv->adapter; | 1650 | intel_encoder->ddc_bus = &intel_dp->adapter; |
| 1636 | intel_encoder->hot_plug = intel_dp_hot_plug; | 1651 | intel_encoder->hot_plug = intel_dp_hot_plug; |
| 1637 | 1652 | ||
| 1638 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { | 1653 | if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) { |
| 1639 | /* initialize panel mode from VBT if available for eDP */ | 1654 | /* initialize panel mode from VBT if available for eDP */ |
| 1640 | if (dev_priv->lfp_lvds_vbt_mode) { | 1655 | if (dev_priv->lfp_lvds_vbt_mode) { |
| 1641 | dev_priv->panel_fixed_mode = | 1656 | dev_priv->panel_fixed_mode = |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b2190148703a..8828b3ac6414 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -32,6 +32,20 @@ | |||
| 32 | #include "drm_crtc.h" | 32 | #include "drm_crtc.h" |
| 33 | 33 | ||
| 34 | #include "drm_crtc_helper.h" | 34 | #include "drm_crtc_helper.h" |
| 35 | |||
| 36 | #define wait_for(COND, MS, W) ({ \ | ||
| 37 | unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ | ||
| 38 | int ret__ = 0; \ | ||
| 39 | while (! (COND)) { \ | ||
| 40 | if (time_after(jiffies, timeout__)) { \ | ||
| 41 | ret__ = -ETIMEDOUT; \ | ||
| 42 | break; \ | ||
| 43 | } \ | ||
| 44 | if (W) msleep(W); \ | ||
| 45 | } \ | ||
| 46 | ret__; \ | ||
| 47 | }) | ||
| 48 | |||
| 35 | /* | 49 | /* |
| 36 | * Display related stuff | 50 | * Display related stuff |
| 37 | */ | 51 | */ |
| @@ -102,7 +116,6 @@ struct intel_encoder { | |||
| 102 | struct i2c_adapter *ddc_bus; | 116 | struct i2c_adapter *ddc_bus; |
| 103 | bool load_detect_temp; | 117 | bool load_detect_temp; |
| 104 | bool needs_tv_clock; | 118 | bool needs_tv_clock; |
| 105 | void *dev_priv; | ||
| 106 | void (*hot_plug)(struct intel_encoder *); | 119 | void (*hot_plug)(struct intel_encoder *); |
| 107 | int crtc_mask; | 120 | int crtc_mask; |
| 108 | int clone_mask; | 121 | int clone_mask; |
| @@ -110,7 +123,6 @@ struct intel_encoder { | |||
| 110 | 123 | ||
| 111 | struct intel_connector { | 124 | struct intel_connector { |
| 112 | struct drm_connector base; | 125 | struct drm_connector base; |
| 113 | void *dev_priv; | ||
| 114 | }; | 126 | }; |
| 115 | 127 | ||
| 116 | struct intel_crtc; | 128 | struct intel_crtc; |
| @@ -156,7 +168,7 @@ struct intel_crtc { | |||
| 156 | uint32_t cursor_addr; | 168 | uint32_t cursor_addr; |
| 157 | int16_t cursor_x, cursor_y; | 169 | int16_t cursor_x, cursor_y; |
| 158 | int16_t cursor_width, cursor_height; | 170 | int16_t cursor_width, cursor_height; |
| 159 | bool cursor_visble; | 171 | bool cursor_visible, cursor_on; |
| 160 | }; | 172 | }; |
| 161 | 173 | ||
| 162 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 174 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
| @@ -164,6 +176,16 @@ struct intel_crtc { | |||
| 164 | #define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) | 176 | #define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) |
| 165 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) | 177 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) |
| 166 | 178 | ||
| 179 | struct intel_unpin_work { | ||
| 180 | struct work_struct work; | ||
| 181 | struct drm_device *dev; | ||
| 182 | struct drm_gem_object *old_fb_obj; | ||
| 183 | struct drm_gem_object *pending_flip_obj; | ||
| 184 | struct drm_pending_vblank_event *event; | ||
| 185 | int pending; | ||
| 186 | bool enable_stall_check; | ||
| 187 | }; | ||
| 188 | |||
| 167 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, | 189 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, |
| 168 | const char *name); | 190 | const char *name); |
| 169 | void intel_i2c_destroy(struct i2c_adapter *adapter); | 191 | void intel_i2c_destroy(struct i2c_adapter *adapter); |
| @@ -188,10 +210,18 @@ extern bool intel_dpd_is_edp(struct drm_device *dev); | |||
| 188 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); | 210 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); |
| 189 | 211 | ||
| 190 | 212 | ||
| 213 | extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | ||
| 214 | struct drm_display_mode *adjusted_mode); | ||
| 215 | extern void intel_pch_panel_fitting(struct drm_device *dev, | ||
| 216 | int fitting_mode, | ||
| 217 | struct drm_display_mode *mode, | ||
| 218 | struct drm_display_mode *adjusted_mode); | ||
| 219 | |||
| 191 | extern int intel_panel_fitter_pipe (struct drm_device *dev); | 220 | extern int intel_panel_fitter_pipe (struct drm_device *dev); |
| 192 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 221 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
| 193 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 222 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
| 194 | extern void intel_encoder_commit (struct drm_encoder *encoder); | 223 | extern void intel_encoder_commit (struct drm_encoder *encoder); |
| 224 | extern void intel_encoder_destroy(struct drm_encoder *encoder); | ||
| 195 | 225 | ||
| 196 | extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector); | 226 | extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector); |
| 197 | 227 | ||
| @@ -199,7 +229,7 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | |||
| 199 | struct drm_crtc *crtc); | 229 | struct drm_crtc *crtc); |
| 200 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 230 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
| 201 | struct drm_file *file_priv); | 231 | struct drm_file *file_priv); |
| 202 | extern void intel_wait_for_vblank(struct drm_device *dev); | 232 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); |
| 203 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); | 233 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); |
| 204 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | 234 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
| 205 | struct drm_connector *connector, | 235 | struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 227feca7cf8d..7c9ec1472d46 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | #define CH7xxx_ADDR 0x76 | 38 | #define CH7xxx_ADDR 0x76 |
| 39 | #define TFP410_ADDR 0x38 | 39 | #define TFP410_ADDR 0x38 |
| 40 | 40 | ||
| 41 | static struct intel_dvo_device intel_dvo_devices[] = { | 41 | static const struct intel_dvo_device intel_dvo_devices[] = { |
| 42 | { | 42 | { |
| 43 | .type = INTEL_DVO_CHIP_TMDS, | 43 | .type = INTEL_DVO_CHIP_TMDS, |
| 44 | .name = "sil164", | 44 | .name = "sil164", |
| @@ -77,20 +77,33 @@ static struct intel_dvo_device intel_dvo_devices[] = { | |||
| 77 | } | 77 | } |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | struct intel_dvo { | ||
| 81 | struct intel_encoder base; | ||
| 82 | |||
| 83 | struct intel_dvo_device dev; | ||
| 84 | |||
| 85 | struct drm_display_mode *panel_fixed_mode; | ||
| 86 | bool panel_wants_dither; | ||
| 87 | }; | ||
| 88 | |||
| 89 | static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder) | ||
| 90 | { | ||
| 91 | return container_of(enc_to_intel_encoder(encoder), struct intel_dvo, base); | ||
| 92 | } | ||
| 93 | |||
| 80 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | 94 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) |
| 81 | { | 95 | { |
| 82 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 96 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
| 83 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 97 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 84 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 98 | u32 dvo_reg = intel_dvo->dev.dvo_reg; |
| 85 | u32 dvo_reg = dvo->dvo_reg; | ||
| 86 | u32 temp = I915_READ(dvo_reg); | 99 | u32 temp = I915_READ(dvo_reg); |
| 87 | 100 | ||
| 88 | if (mode == DRM_MODE_DPMS_ON) { | 101 | if (mode == DRM_MODE_DPMS_ON) { |
| 89 | I915_WRITE(dvo_reg, temp | DVO_ENABLE); | 102 | I915_WRITE(dvo_reg, temp | DVO_ENABLE); |
| 90 | I915_READ(dvo_reg); | 103 | I915_READ(dvo_reg); |
| 91 | dvo->dev_ops->dpms(dvo, mode); | 104 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); |
| 92 | } else { | 105 | } else { |
| 93 | dvo->dev_ops->dpms(dvo, mode); | 106 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); |
| 94 | I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); | 107 | I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); |
| 95 | I915_READ(dvo_reg); | 108 | I915_READ(dvo_reg); |
| 96 | } | 109 | } |
| @@ -100,38 +113,36 @@ static int intel_dvo_mode_valid(struct drm_connector *connector, | |||
| 100 | struct drm_display_mode *mode) | 113 | struct drm_display_mode *mode) |
| 101 | { | 114 | { |
| 102 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 115 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 103 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 116 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 104 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
| 105 | 117 | ||
| 106 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 118 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
| 107 | return MODE_NO_DBLESCAN; | 119 | return MODE_NO_DBLESCAN; |
| 108 | 120 | ||
| 109 | /* XXX: Validate clock range */ | 121 | /* XXX: Validate clock range */ |
| 110 | 122 | ||
| 111 | if (dvo->panel_fixed_mode) { | 123 | if (intel_dvo->panel_fixed_mode) { |
| 112 | if (mode->hdisplay > dvo->panel_fixed_mode->hdisplay) | 124 | if (mode->hdisplay > intel_dvo->panel_fixed_mode->hdisplay) |
| 113 | return MODE_PANEL; | 125 | return MODE_PANEL; |
| 114 | if (mode->vdisplay > dvo->panel_fixed_mode->vdisplay) | 126 | if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay) |
| 115 | return MODE_PANEL; | 127 | return MODE_PANEL; |
| 116 | } | 128 | } |
| 117 | 129 | ||
| 118 | return dvo->dev_ops->mode_valid(dvo, mode); | 130 | return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode); |
| 119 | } | 131 | } |
| 120 | 132 | ||
| 121 | static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, | 133 | static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, |
| 122 | struct drm_display_mode *mode, | 134 | struct drm_display_mode *mode, |
| 123 | struct drm_display_mode *adjusted_mode) | 135 | struct drm_display_mode *adjusted_mode) |
| 124 | { | 136 | { |
| 125 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 137 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 126 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
| 127 | 138 | ||
| 128 | /* If we have timings from the BIOS for the panel, put them in | 139 | /* If we have timings from the BIOS for the panel, put them in |
| 129 | * to the adjusted mode. The CRTC will be set up for this mode, | 140 | * to the adjusted mode. The CRTC will be set up for this mode, |
| 130 | * with the panel scaling set up to source from the H/VDisplay | 141 | * with the panel scaling set up to source from the H/VDisplay |
| 131 | * of the original mode. | 142 | * of the original mode. |
| 132 | */ | 143 | */ |
| 133 | if (dvo->panel_fixed_mode != NULL) { | 144 | if (intel_dvo->panel_fixed_mode != NULL) { |
| 134 | #define C(x) adjusted_mode->x = dvo->panel_fixed_mode->x | 145 | #define C(x) adjusted_mode->x = intel_dvo->panel_fixed_mode->x |
| 135 | C(hdisplay); | 146 | C(hdisplay); |
| 136 | C(hsync_start); | 147 | C(hsync_start); |
| 137 | C(hsync_end); | 148 | C(hsync_end); |
| @@ -145,8 +156,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, | |||
| 145 | #undef C | 156 | #undef C |
| 146 | } | 157 | } |
| 147 | 158 | ||
| 148 | if (dvo->dev_ops->mode_fixup) | 159 | if (intel_dvo->dev.dev_ops->mode_fixup) |
| 149 | return dvo->dev_ops->mode_fixup(dvo, mode, adjusted_mode); | 160 | return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, mode, adjusted_mode); |
| 150 | 161 | ||
| 151 | return true; | 162 | return true; |
| 152 | } | 163 | } |
| @@ -158,11 +169,10 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
| 158 | struct drm_device *dev = encoder->dev; | 169 | struct drm_device *dev = encoder->dev; |
| 159 | struct drm_i915_private *dev_priv = dev->dev_private; | 170 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 160 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 171 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
| 161 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 172 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 162 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
| 163 | int pipe = intel_crtc->pipe; | 173 | int pipe = intel_crtc->pipe; |
| 164 | u32 dvo_val; | 174 | u32 dvo_val; |
| 165 | u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg; | 175 | u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg; |
| 166 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | 176 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; |
| 167 | 177 | ||
| 168 | switch (dvo_reg) { | 178 | switch (dvo_reg) { |
| @@ -178,7 +188,7 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
| 178 | break; | 188 | break; |
| 179 | } | 189 | } |
| 180 | 190 | ||
| 181 | dvo->dev_ops->mode_set(dvo, mode, adjusted_mode); | 191 | intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, mode, adjusted_mode); |
| 182 | 192 | ||
| 183 | /* Save the data order, since I don't know what it should be set to. */ | 193 | /* Save the data order, since I don't know what it should be set to. */ |
| 184 | dvo_val = I915_READ(dvo_reg) & | 194 | dvo_val = I915_READ(dvo_reg) & |
| @@ -211,43 +221,42 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
| 211 | * | 221 | * |
| 212 | * Unimplemented. | 222 | * Unimplemented. |
| 213 | */ | 223 | */ |
| 214 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) | 224 | static enum drm_connector_status |
| 225 | intel_dvo_detect(struct drm_connector *connector, bool force) | ||
| 215 | { | 226 | { |
| 216 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 227 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 217 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 228 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 218 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
| 219 | 229 | ||
| 220 | return dvo->dev_ops->detect(dvo); | 230 | return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev); |
| 221 | } | 231 | } |
| 222 | 232 | ||
| 223 | static int intel_dvo_get_modes(struct drm_connector *connector) | 233 | static int intel_dvo_get_modes(struct drm_connector *connector) |
| 224 | { | 234 | { |
| 225 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 235 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 226 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 236 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 227 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
| 228 | 237 | ||
| 229 | /* We should probably have an i2c driver get_modes function for those | 238 | /* We should probably have an i2c driver get_modes function for those |
| 230 | * devices which will have a fixed set of modes determined by the chip | 239 | * devices which will have a fixed set of modes determined by the chip |
| 231 | * (TV-out, for example), but for now with just TMDS and LVDS, | 240 | * (TV-out, for example), but for now with just TMDS and LVDS, |
| 232 | * that's not the case. | 241 | * that's not the case. |
| 233 | */ | 242 | */ |
| 234 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 243 | intel_ddc_get_modes(connector, intel_dvo->base.ddc_bus); |
| 235 | if (!list_empty(&connector->probed_modes)) | 244 | if (!list_empty(&connector->probed_modes)) |
| 236 | return 1; | 245 | return 1; |
| 237 | 246 | ||
| 238 | 247 | if (intel_dvo->panel_fixed_mode != NULL) { | |
| 239 | if (dvo->panel_fixed_mode != NULL) { | ||
| 240 | struct drm_display_mode *mode; | 248 | struct drm_display_mode *mode; |
| 241 | mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode); | 249 | mode = drm_mode_duplicate(connector->dev, intel_dvo->panel_fixed_mode); |
| 242 | if (mode) { | 250 | if (mode) { |
| 243 | drm_mode_probed_add(connector, mode); | 251 | drm_mode_probed_add(connector, mode); |
| 244 | return 1; | 252 | return 1; |
| 245 | } | 253 | } |
| 246 | } | 254 | } |
| 255 | |||
| 247 | return 0; | 256 | return 0; |
| 248 | } | 257 | } |
| 249 | 258 | ||
| 250 | static void intel_dvo_destroy (struct drm_connector *connector) | 259 | static void intel_dvo_destroy(struct drm_connector *connector) |
| 251 | { | 260 | { |
| 252 | drm_sysfs_connector_remove(connector); | 261 | drm_sysfs_connector_remove(connector); |
| 253 | drm_connector_cleanup(connector); | 262 | drm_connector_cleanup(connector); |
| @@ -277,28 +286,20 @@ static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs | |||
| 277 | 286 | ||
| 278 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) | 287 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) |
| 279 | { | 288 | { |
| 280 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 289 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 281 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 290 | |
| 282 | 291 | if (intel_dvo->dev.dev_ops->destroy) | |
| 283 | if (dvo) { | 292 | intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev); |
| 284 | if (dvo->dev_ops->destroy) | 293 | |
| 285 | dvo->dev_ops->destroy(dvo); | 294 | kfree(intel_dvo->panel_fixed_mode); |
| 286 | if (dvo->panel_fixed_mode) | 295 | |
| 287 | kfree(dvo->panel_fixed_mode); | 296 | intel_encoder_destroy(encoder); |
| 288 | } | ||
| 289 | if (intel_encoder->i2c_bus) | ||
| 290 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
| 291 | if (intel_encoder->ddc_bus) | ||
| 292 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
| 293 | drm_encoder_cleanup(encoder); | ||
| 294 | kfree(intel_encoder); | ||
| 295 | } | 297 | } |
| 296 | 298 | ||
| 297 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { | 299 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { |
| 298 | .destroy = intel_dvo_enc_destroy, | 300 | .destroy = intel_dvo_enc_destroy, |
| 299 | }; | 301 | }; |
| 300 | 302 | ||
| 301 | |||
| 302 | /** | 303 | /** |
| 303 | * Attempts to get a fixed panel timing for LVDS (currently only the i830). | 304 | * Attempts to get a fixed panel timing for LVDS (currently only the i830). |
| 304 | * | 305 | * |
| @@ -306,15 +307,13 @@ static const struct drm_encoder_funcs intel_dvo_enc_funcs = { | |||
| 306 | * chip being on DVOB/C and having multiple pipes. | 307 | * chip being on DVOB/C and having multiple pipes. |
| 307 | */ | 308 | */ |
| 308 | static struct drm_display_mode * | 309 | static struct drm_display_mode * |
| 309 | intel_dvo_get_current_mode (struct drm_connector *connector) | 310 | intel_dvo_get_current_mode(struct drm_connector *connector) |
| 310 | { | 311 | { |
| 311 | struct drm_device *dev = connector->dev; | 312 | struct drm_device *dev = connector->dev; |
| 312 | struct drm_i915_private *dev_priv = dev->dev_private; | 313 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 313 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 314 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 314 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 315 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 315 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 316 | uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg); |
| 316 | uint32_t dvo_reg = dvo->dvo_reg; | ||
| 317 | uint32_t dvo_val = I915_READ(dvo_reg); | ||
| 318 | struct drm_display_mode *mode = NULL; | 317 | struct drm_display_mode *mode = NULL; |
| 319 | 318 | ||
| 320 | /* If the DVO port is active, that'll be the LVDS, so we can pull out | 319 | /* If the DVO port is active, that'll be the LVDS, so we can pull out |
| @@ -327,7 +326,6 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
| 327 | crtc = intel_get_crtc_from_pipe(dev, pipe); | 326 | crtc = intel_get_crtc_from_pipe(dev, pipe); |
| 328 | if (crtc) { | 327 | if (crtc) { |
| 329 | mode = intel_crtc_mode_get(dev, crtc); | 328 | mode = intel_crtc_mode_get(dev, crtc); |
| 330 | |||
| 331 | if (mode) { | 329 | if (mode) { |
| 332 | mode->type |= DRM_MODE_TYPE_PREFERRED; | 330 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
| 333 | if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) | 331 | if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) |
| @@ -337,28 +335,32 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
| 337 | } | 335 | } |
| 338 | } | 336 | } |
| 339 | } | 337 | } |
| 338 | |||
| 340 | return mode; | 339 | return mode; |
| 341 | } | 340 | } |
| 342 | 341 | ||
| 343 | void intel_dvo_init(struct drm_device *dev) | 342 | void intel_dvo_init(struct drm_device *dev) |
| 344 | { | 343 | { |
| 345 | struct intel_encoder *intel_encoder; | 344 | struct intel_encoder *intel_encoder; |
| 345 | struct intel_dvo *intel_dvo; | ||
| 346 | struct intel_connector *intel_connector; | 346 | struct intel_connector *intel_connector; |
| 347 | struct intel_dvo_device *dvo; | ||
| 348 | struct i2c_adapter *i2cbus = NULL; | 347 | struct i2c_adapter *i2cbus = NULL; |
| 349 | int ret = 0; | 348 | int ret = 0; |
| 350 | int i; | 349 | int i; |
| 351 | int encoder_type = DRM_MODE_ENCODER_NONE; | 350 | int encoder_type = DRM_MODE_ENCODER_NONE; |
| 352 | intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL); | 351 | |
| 353 | if (!intel_encoder) | 352 | intel_dvo = kzalloc(sizeof(struct intel_dvo), GFP_KERNEL); |
| 353 | if (!intel_dvo) | ||
| 354 | return; | 354 | return; |
| 355 | 355 | ||
| 356 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 356 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 357 | if (!intel_connector) { | 357 | if (!intel_connector) { |
| 358 | kfree(intel_encoder); | 358 | kfree(intel_dvo); |
| 359 | return; | 359 | return; |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | intel_encoder = &intel_dvo->base; | ||
| 363 | |||
| 362 | /* Set up the DDC bus */ | 364 | /* Set up the DDC bus */ |
| 363 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); | 365 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); |
| 364 | if (!intel_encoder->ddc_bus) | 366 | if (!intel_encoder->ddc_bus) |
| @@ -367,10 +369,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 367 | /* Now, try to find a controller */ | 369 | /* Now, try to find a controller */ |
| 368 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 370 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |
| 369 | struct drm_connector *connector = &intel_connector->base; | 371 | struct drm_connector *connector = &intel_connector->base; |
| 372 | const struct intel_dvo_device *dvo = &intel_dvo_devices[i]; | ||
| 370 | int gpio; | 373 | int gpio; |
| 371 | 374 | ||
| 372 | dvo = &intel_dvo_devices[i]; | ||
| 373 | |||
| 374 | /* Allow the I2C driver info to specify the GPIO to be used in | 375 | /* Allow the I2C driver info to specify the GPIO to be used in |
| 375 | * special cases, but otherwise default to what's defined | 376 | * special cases, but otherwise default to what's defined |
| 376 | * in the spec. | 377 | * in the spec. |
| @@ -393,11 +394,8 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 393 | continue; | 394 | continue; |
| 394 | } | 395 | } |
| 395 | 396 | ||
| 396 | if (dvo->dev_ops!= NULL) | 397 | intel_dvo->dev = *dvo; |
| 397 | ret = dvo->dev_ops->init(dvo, i2cbus); | 398 | ret = dvo->dev_ops->init(&intel_dvo->dev, i2cbus); |
| 398 | else | ||
| 399 | ret = false; | ||
| 400 | |||
| 401 | if (!ret) | 399 | if (!ret) |
| 402 | continue; | 400 | continue; |
| 403 | 401 | ||
| @@ -429,9 +427,6 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 429 | connector->interlace_allowed = false; | 427 | connector->interlace_allowed = false; |
| 430 | connector->doublescan_allowed = false; | 428 | connector->doublescan_allowed = false; |
| 431 | 429 | ||
| 432 | intel_encoder->dev_priv = dvo; | ||
| 433 | intel_encoder->i2c_bus = i2cbus; | ||
| 434 | |||
| 435 | drm_encoder_init(dev, &intel_encoder->enc, | 430 | drm_encoder_init(dev, &intel_encoder->enc, |
| 436 | &intel_dvo_enc_funcs, encoder_type); | 431 | &intel_dvo_enc_funcs, encoder_type); |
| 437 | drm_encoder_helper_add(&intel_encoder->enc, | 432 | drm_encoder_helper_add(&intel_encoder->enc, |
| @@ -447,9 +442,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 447 | * headers, likely), so for now, just get the current | 442 | * headers, likely), so for now, just get the current |
| 448 | * mode being output through DVO. | 443 | * mode being output through DVO. |
| 449 | */ | 444 | */ |
| 450 | dvo->panel_fixed_mode = | 445 | intel_dvo->panel_fixed_mode = |
| 451 | intel_dvo_get_current_mode(connector); | 446 | intel_dvo_get_current_mode(connector); |
| 452 | dvo->panel_wants_dither = true; | 447 | intel_dvo->panel_wants_dither = true; |
| 453 | } | 448 | } |
| 454 | 449 | ||
| 455 | drm_sysfs_connector_add(connector); | 450 | drm_sysfs_connector_add(connector); |
| @@ -461,6 +456,6 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 461 | if (i2cbus != NULL) | 456 | if (i2cbus != NULL) |
| 462 | intel_i2c_destroy(i2cbus); | 457 | intel_i2c_destroy(i2cbus); |
| 463 | free_intel: | 458 | free_intel: |
| 464 | kfree(intel_encoder); | 459 | kfree(intel_dvo); |
| 465 | kfree(intel_connector); | 460 | kfree(intel_connector); |
| 466 | } | 461 | } |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 7bdc96256bf5..b61966c126d3 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
| @@ -237,8 +237,10 @@ int intel_fbdev_destroy(struct drm_device *dev, | |||
| 237 | drm_fb_helper_fini(&ifbdev->helper); | 237 | drm_fb_helper_fini(&ifbdev->helper); |
| 238 | 238 | ||
| 239 | drm_framebuffer_cleanup(&ifb->base); | 239 | drm_framebuffer_cleanup(&ifb->base); |
| 240 | if (ifb->obj) | 240 | if (ifb->obj) { |
| 241 | drm_gem_object_unreference(ifb->obj); | 241 | drm_gem_object_unreference(ifb->obj); |
| 242 | ifb->obj = NULL; | ||
| 243 | } | ||
| 242 | 244 | ||
| 243 | return 0; | 245 | return 0; |
| 244 | } | 246 | } |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 197887ed1823..926934a482ec 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
| @@ -37,11 +37,17 @@ | |||
| 37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
| 38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
| 39 | 39 | ||
| 40 | struct intel_hdmi_priv { | 40 | struct intel_hdmi { |
| 41 | struct intel_encoder base; | ||
| 41 | u32 sdvox_reg; | 42 | u32 sdvox_reg; |
| 42 | bool has_hdmi_sink; | 43 | bool has_hdmi_sink; |
| 43 | }; | 44 | }; |
| 44 | 45 | ||
| 46 | static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) | ||
| 47 | { | ||
| 48 | return container_of(enc_to_intel_encoder(encoder), struct intel_hdmi, base); | ||
| 49 | } | ||
| 50 | |||
| 45 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, | 51 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, |
| 46 | struct drm_display_mode *mode, | 52 | struct drm_display_mode *mode, |
| 47 | struct drm_display_mode *adjusted_mode) | 53 | struct drm_display_mode *adjusted_mode) |
| @@ -50,8 +56,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
| 50 | struct drm_i915_private *dev_priv = dev->dev_private; | 56 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 51 | struct drm_crtc *crtc = encoder->crtc; | 57 | struct drm_crtc *crtc = encoder->crtc; |
| 52 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 58 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 53 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 59 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
| 54 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
| 55 | u32 sdvox; | 60 | u32 sdvox; |
| 56 | 61 | ||
| 57 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; | 62 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; |
| @@ -60,7 +65,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
| 60 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 65 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
| 61 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | 66 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; |
| 62 | 67 | ||
| 63 | if (hdmi_priv->has_hdmi_sink) { | 68 | if (intel_hdmi->has_hdmi_sink) { |
| 64 | sdvox |= SDVO_AUDIO_ENABLE; | 69 | sdvox |= SDVO_AUDIO_ENABLE; |
| 65 | if (HAS_PCH_CPT(dev)) | 70 | if (HAS_PCH_CPT(dev)) |
| 66 | sdvox |= HDMI_MODE_SELECT; | 71 | sdvox |= HDMI_MODE_SELECT; |
| @@ -73,26 +78,25 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
| 73 | sdvox |= SDVO_PIPE_B_SELECT; | 78 | sdvox |= SDVO_PIPE_B_SELECT; |
| 74 | } | 79 | } |
| 75 | 80 | ||
| 76 | I915_WRITE(hdmi_priv->sdvox_reg, sdvox); | 81 | I915_WRITE(intel_hdmi->sdvox_reg, sdvox); |
| 77 | POSTING_READ(hdmi_priv->sdvox_reg); | 82 | POSTING_READ(intel_hdmi->sdvox_reg); |
| 78 | } | 83 | } |
| 79 | 84 | ||
| 80 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | 85 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) |
| 81 | { | 86 | { |
| 82 | struct drm_device *dev = encoder->dev; | 87 | struct drm_device *dev = encoder->dev; |
| 83 | struct drm_i915_private *dev_priv = dev->dev_private; | 88 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 84 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 89 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
| 85 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
| 86 | u32 temp; | 90 | u32 temp; |
| 87 | 91 | ||
| 88 | temp = I915_READ(hdmi_priv->sdvox_reg); | 92 | temp = I915_READ(intel_hdmi->sdvox_reg); |
| 89 | 93 | ||
| 90 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but | 94 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but |
| 91 | * we do this anyway which shows more stable in testing. | 95 | * we do this anyway which shows more stable in testing. |
| 92 | */ | 96 | */ |
| 93 | if (HAS_PCH_SPLIT(dev)) { | 97 | if (HAS_PCH_SPLIT(dev)) { |
| 94 | I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); | 98 | I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE); |
| 95 | POSTING_READ(hdmi_priv->sdvox_reg); | 99 | POSTING_READ(intel_hdmi->sdvox_reg); |
| 96 | } | 100 | } |
| 97 | 101 | ||
| 98 | if (mode != DRM_MODE_DPMS_ON) { | 102 | if (mode != DRM_MODE_DPMS_ON) { |
| @@ -101,15 +105,15 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
| 101 | temp |= SDVO_ENABLE; | 105 | temp |= SDVO_ENABLE; |
| 102 | } | 106 | } |
| 103 | 107 | ||
| 104 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | 108 | I915_WRITE(intel_hdmi->sdvox_reg, temp); |
| 105 | POSTING_READ(hdmi_priv->sdvox_reg); | 109 | POSTING_READ(intel_hdmi->sdvox_reg); |
| 106 | 110 | ||
| 107 | /* HW workaround, need to write this twice for issue that may result | 111 | /* HW workaround, need to write this twice for issue that may result |
| 108 | * in first write getting masked. | 112 | * in first write getting masked. |
| 109 | */ | 113 | */ |
| 110 | if (HAS_PCH_SPLIT(dev)) { | 114 | if (HAS_PCH_SPLIT(dev)) { |
| 111 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | 115 | I915_WRITE(intel_hdmi->sdvox_reg, temp); |
| 112 | POSTING_READ(hdmi_priv->sdvox_reg); | 116 | POSTING_READ(intel_hdmi->sdvox_reg); |
| 113 | } | 117 | } |
| 114 | } | 118 | } |
| 115 | 119 | ||
| @@ -135,22 +139,20 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
| 135 | } | 139 | } |
| 136 | 140 | ||
| 137 | static enum drm_connector_status | 141 | static enum drm_connector_status |
| 138 | intel_hdmi_detect(struct drm_connector *connector) | 142 | intel_hdmi_detect(struct drm_connector *connector, bool force) |
| 139 | { | 143 | { |
| 140 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 144 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 141 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 145 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
| 142 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
| 143 | struct edid *edid = NULL; | 146 | struct edid *edid = NULL; |
| 144 | enum drm_connector_status status = connector_status_disconnected; | 147 | enum drm_connector_status status = connector_status_disconnected; |
| 145 | 148 | ||
| 146 | hdmi_priv->has_hdmi_sink = false; | 149 | intel_hdmi->has_hdmi_sink = false; |
| 147 | edid = drm_get_edid(connector, | 150 | edid = drm_get_edid(connector, intel_hdmi->base.ddc_bus); |
| 148 | intel_encoder->ddc_bus); | ||
| 149 | 151 | ||
| 150 | if (edid) { | 152 | if (edid) { |
| 151 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 153 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
| 152 | status = connector_status_connected; | 154 | status = connector_status_connected; |
| 153 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | 155 | intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); |
| 154 | } | 156 | } |
| 155 | connector->display_info.raw_edid = NULL; | 157 | connector->display_info.raw_edid = NULL; |
| 156 | kfree(edid); | 158 | kfree(edid); |
| @@ -162,13 +164,13 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
| 162 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 164 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
| 163 | { | 165 | { |
| 164 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 166 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 165 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 167 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
| 166 | 168 | ||
| 167 | /* We should parse the EDID data and find out if it's an HDMI sink so | 169 | /* We should parse the EDID data and find out if it's an HDMI sink so |
| 168 | * we can send audio to it. | 170 | * we can send audio to it. |
| 169 | */ | 171 | */ |
| 170 | 172 | ||
| 171 | return intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 173 | return intel_ddc_get_modes(connector, intel_hdmi->base.ddc_bus); |
| 172 | } | 174 | } |
| 173 | 175 | ||
| 174 | static void intel_hdmi_destroy(struct drm_connector *connector) | 176 | static void intel_hdmi_destroy(struct drm_connector *connector) |
| @@ -199,18 +201,8 @@ static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs | |||
| 199 | .best_encoder = intel_attached_encoder, | 201 | .best_encoder = intel_attached_encoder, |
| 200 | }; | 202 | }; |
| 201 | 203 | ||
| 202 | static void intel_hdmi_enc_destroy(struct drm_encoder *encoder) | ||
| 203 | { | ||
| 204 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 205 | |||
| 206 | if (intel_encoder->i2c_bus) | ||
| 207 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
| 208 | drm_encoder_cleanup(encoder); | ||
| 209 | kfree(intel_encoder); | ||
| 210 | } | ||
| 211 | |||
| 212 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { | 204 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { |
| 213 | .destroy = intel_hdmi_enc_destroy, | 205 | .destroy = intel_encoder_destroy, |
| 214 | }; | 206 | }; |
| 215 | 207 | ||
| 216 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | 208 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) |
| @@ -219,21 +211,19 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
| 219 | struct drm_connector *connector; | 211 | struct drm_connector *connector; |
| 220 | struct intel_encoder *intel_encoder; | 212 | struct intel_encoder *intel_encoder; |
| 221 | struct intel_connector *intel_connector; | 213 | struct intel_connector *intel_connector; |
| 222 | struct intel_hdmi_priv *hdmi_priv; | 214 | struct intel_hdmi *intel_hdmi; |
| 223 | 215 | ||
| 224 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + | 216 | intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); |
| 225 | sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); | 217 | if (!intel_hdmi) |
| 226 | if (!intel_encoder) | ||
| 227 | return; | 218 | return; |
| 228 | 219 | ||
| 229 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 220 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 230 | if (!intel_connector) { | 221 | if (!intel_connector) { |
| 231 | kfree(intel_encoder); | 222 | kfree(intel_hdmi); |
| 232 | return; | 223 | return; |
| 233 | } | 224 | } |
| 234 | 225 | ||
| 235 | hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1); | 226 | intel_encoder = &intel_hdmi->base; |
| 236 | |||
| 237 | connector = &intel_connector->base; | 227 | connector = &intel_connector->base; |
| 238 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, | 228 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, |
| 239 | DRM_MODE_CONNECTOR_HDMIA); | 229 | DRM_MODE_CONNECTOR_HDMIA); |
| @@ -274,8 +264,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
| 274 | if (!intel_encoder->ddc_bus) | 264 | if (!intel_encoder->ddc_bus) |
| 275 | goto err_connector; | 265 | goto err_connector; |
| 276 | 266 | ||
| 277 | hdmi_priv->sdvox_reg = sdvox_reg; | 267 | intel_hdmi->sdvox_reg = sdvox_reg; |
| 278 | intel_encoder->dev_priv = hdmi_priv; | ||
| 279 | 268 | ||
| 280 | drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, | 269 | drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, |
| 281 | DRM_MODE_ENCODER_TMDS); | 270 | DRM_MODE_ENCODER_TMDS); |
| @@ -298,7 +287,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
| 298 | 287 | ||
| 299 | err_connector: | 288 | err_connector: |
| 300 | drm_connector_cleanup(connector); | 289 | drm_connector_cleanup(connector); |
| 301 | kfree(intel_encoder); | 290 | kfree(intel_hdmi); |
| 302 | kfree(intel_connector); | 291 | kfree(intel_connector); |
| 303 | 292 | ||
| 304 | return; | 293 | return; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 0a2e60059fb3..6ec39a86ed06 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -41,12 +41,18 @@ | |||
| 41 | #include <linux/acpi.h> | 41 | #include <linux/acpi.h> |
| 42 | 42 | ||
| 43 | /* Private structure for the integrated LVDS support */ | 43 | /* Private structure for the integrated LVDS support */ |
| 44 | struct intel_lvds_priv { | 44 | struct intel_lvds { |
| 45 | struct intel_encoder base; | ||
| 45 | int fitting_mode; | 46 | int fitting_mode; |
| 46 | u32 pfit_control; | 47 | u32 pfit_control; |
| 47 | u32 pfit_pgm_ratios; | 48 | u32 pfit_pgm_ratios; |
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 51 | static struct intel_lvds *enc_to_intel_lvds(struct drm_encoder *encoder) | ||
| 52 | { | ||
| 53 | return container_of(enc_to_intel_encoder(encoder), struct intel_lvds, base); | ||
| 54 | } | ||
| 55 | |||
| 50 | /** | 56 | /** |
| 51 | * Sets the backlight level. | 57 | * Sets the backlight level. |
| 52 | * | 58 | * |
| @@ -90,7 +96,7 @@ static u32 intel_lvds_get_max_backlight(struct drm_device *dev) | |||
| 90 | static void intel_lvds_set_power(struct drm_device *dev, bool on) | 96 | static void intel_lvds_set_power(struct drm_device *dev, bool on) |
| 91 | { | 97 | { |
| 92 | struct drm_i915_private *dev_priv = dev->dev_private; | 98 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 93 | u32 pp_status, ctl_reg, status_reg, lvds_reg; | 99 | u32 ctl_reg, status_reg, lvds_reg; |
| 94 | 100 | ||
| 95 | if (HAS_PCH_SPLIT(dev)) { | 101 | if (HAS_PCH_SPLIT(dev)) { |
| 96 | ctl_reg = PCH_PP_CONTROL; | 102 | ctl_reg = PCH_PP_CONTROL; |
| @@ -108,9 +114,8 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) | |||
| 108 | 114 | ||
| 109 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | | 115 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | |
| 110 | POWER_TARGET_ON); | 116 | POWER_TARGET_ON); |
| 111 | do { | 117 | if (wait_for(I915_READ(status_reg) & PP_ON, 1000, 0)) |
| 112 | pp_status = I915_READ(status_reg); | 118 | DRM_ERROR("timed out waiting to enable LVDS pipe"); |
| 113 | } while ((pp_status & PP_ON) == 0); | ||
| 114 | 119 | ||
| 115 | intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); | 120 | intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); |
| 116 | } else { | 121 | } else { |
| @@ -118,9 +123,8 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) | |||
| 118 | 123 | ||
| 119 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & | 124 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & |
| 120 | ~POWER_TARGET_ON); | 125 | ~POWER_TARGET_ON); |
| 121 | do { | 126 | if (wait_for((I915_READ(status_reg) & PP_ON) == 0, 1000, 0)) |
| 122 | pp_status = I915_READ(status_reg); | 127 | DRM_ERROR("timed out waiting for LVDS pipe to turn off"); |
| 123 | } while (pp_status & PP_ON); | ||
| 124 | 128 | ||
| 125 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | 129 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); |
| 126 | POSTING_READ(lvds_reg); | 130 | POSTING_READ(lvds_reg); |
| @@ -219,9 +223,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 219 | struct drm_device *dev = encoder->dev; | 223 | struct drm_device *dev = encoder->dev; |
| 220 | struct drm_i915_private *dev_priv = dev->dev_private; | 224 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 221 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 225 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
| 226 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); | ||
| 222 | struct drm_encoder *tmp_encoder; | 227 | struct drm_encoder *tmp_encoder; |
| 223 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 224 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
| 225 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; | 228 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
| 226 | 229 | ||
| 227 | /* Should never happen!! */ | 230 | /* Should never happen!! */ |
| @@ -241,26 +244,20 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 241 | /* If we don't have a panel mode, there is nothing we can do */ | 244 | /* If we don't have a panel mode, there is nothing we can do */ |
| 242 | if (dev_priv->panel_fixed_mode == NULL) | 245 | if (dev_priv->panel_fixed_mode == NULL) |
| 243 | return true; | 246 | return true; |
| 247 | |||
| 244 | /* | 248 | /* |
| 245 | * We have timings from the BIOS for the panel, put them in | 249 | * We have timings from the BIOS for the panel, put them in |
| 246 | * to the adjusted mode. The CRTC will be set up for this mode, | 250 | * to the adjusted mode. The CRTC will be set up for this mode, |
| 247 | * with the panel scaling set up to source from the H/VDisplay | 251 | * with the panel scaling set up to source from the H/VDisplay |
| 248 | * of the original mode. | 252 | * of the original mode. |
| 249 | */ | 253 | */ |
| 250 | adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; | 254 | intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); |
| 251 | adjusted_mode->hsync_start = | 255 | |
| 252 | dev_priv->panel_fixed_mode->hsync_start; | 256 | if (HAS_PCH_SPLIT(dev)) { |
| 253 | adjusted_mode->hsync_end = | 257 | intel_pch_panel_fitting(dev, intel_lvds->fitting_mode, |
| 254 | dev_priv->panel_fixed_mode->hsync_end; | 258 | mode, adjusted_mode); |
| 255 | adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; | 259 | return true; |
| 256 | adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; | 260 | } |
| 257 | adjusted_mode->vsync_start = | ||
| 258 | dev_priv->panel_fixed_mode->vsync_start; | ||
| 259 | adjusted_mode->vsync_end = | ||
| 260 | dev_priv->panel_fixed_mode->vsync_end; | ||
| 261 | adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; | ||
| 262 | adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; | ||
| 263 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
| 264 | 261 | ||
| 265 | /* Make sure pre-965s set dither correctly */ | 262 | /* Make sure pre-965s set dither correctly */ |
| 266 | if (!IS_I965G(dev)) { | 263 | if (!IS_I965G(dev)) { |
| @@ -273,10 +270,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 273 | adjusted_mode->vdisplay == mode->vdisplay) | 270 | adjusted_mode->vdisplay == mode->vdisplay) |
| 274 | goto out; | 271 | goto out; |
| 275 | 272 | ||
| 276 | /* full screen scale for now */ | ||
| 277 | if (HAS_PCH_SPLIT(dev)) | ||
| 278 | goto out; | ||
| 279 | |||
| 280 | /* 965+ wants fuzzy fitting */ | 273 | /* 965+ wants fuzzy fitting */ |
| 281 | if (IS_I965G(dev)) | 274 | if (IS_I965G(dev)) |
| 282 | pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | | 275 | pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | |
| @@ -288,12 +281,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 288 | * to register description and PRM. | 281 | * to register description and PRM. |
| 289 | * Change the value here to see the borders for debugging | 282 | * Change the value here to see the borders for debugging |
| 290 | */ | 283 | */ |
| 291 | if (!HAS_PCH_SPLIT(dev)) { | 284 | I915_WRITE(BCLRPAT_A, 0); |
| 292 | I915_WRITE(BCLRPAT_A, 0); | 285 | I915_WRITE(BCLRPAT_B, 0); |
| 293 | I915_WRITE(BCLRPAT_B, 0); | ||
| 294 | } | ||
| 295 | 286 | ||
| 296 | switch (lvds_priv->fitting_mode) { | 287 | switch (intel_lvds->fitting_mode) { |
| 297 | case DRM_MODE_SCALE_CENTER: | 288 | case DRM_MODE_SCALE_CENTER: |
| 298 | /* | 289 | /* |
| 299 | * For centered modes, we have to calculate border widths & | 290 | * For centered modes, we have to calculate border widths & |
| @@ -378,8 +369,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 378 | } | 369 | } |
| 379 | 370 | ||
| 380 | out: | 371 | out: |
| 381 | lvds_priv->pfit_control = pfit_control; | 372 | intel_lvds->pfit_control = pfit_control; |
| 382 | lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; | 373 | intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios; |
| 383 | dev_priv->lvds_border_bits = border; | 374 | dev_priv->lvds_border_bits = border; |
| 384 | 375 | ||
| 385 | /* | 376 | /* |
| @@ -427,8 +418,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
| 427 | { | 418 | { |
| 428 | struct drm_device *dev = encoder->dev; | 419 | struct drm_device *dev = encoder->dev; |
| 429 | struct drm_i915_private *dev_priv = dev->dev_private; | 420 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 430 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 421 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); |
| 431 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
| 432 | 422 | ||
| 433 | /* | 423 | /* |
| 434 | * The LVDS pin pair will already have been turned on in the | 424 | * The LVDS pin pair will already have been turned on in the |
| @@ -444,8 +434,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
| 444 | * screen. Should be enabled before the pipe is enabled, according to | 434 | * screen. Should be enabled before the pipe is enabled, according to |
| 445 | * register description and PRM. | 435 | * register description and PRM. |
| 446 | */ | 436 | */ |
| 447 | I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios); | 437 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); |
| 448 | I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); | 438 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); |
| 449 | } | 439 | } |
| 450 | 440 | ||
| 451 | /** | 441 | /** |
| @@ -455,7 +445,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
| 455 | * connected and closed means disconnected. We also send hotplug events as | 445 | * connected and closed means disconnected. We also send hotplug events as |
| 456 | * needed, using lid status notification from the input layer. | 446 | * needed, using lid status notification from the input layer. |
| 457 | */ | 447 | */ |
| 458 | static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) | 448 | static enum drm_connector_status |
| 449 | intel_lvds_detect(struct drm_connector *connector, bool force) | ||
| 459 | { | 450 | { |
| 460 | struct drm_device *dev = connector->dev; | 451 | struct drm_device *dev = connector->dev; |
| 461 | enum drm_connector_status status = connector_status_connected; | 452 | enum drm_connector_status status = connector_status_connected; |
| @@ -550,7 +541,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | |||
| 550 | * the LID nofication event. | 541 | * the LID nofication event. |
| 551 | */ | 542 | */ |
| 552 | if (connector) | 543 | if (connector) |
| 553 | connector->status = connector->funcs->detect(connector); | 544 | connector->status = connector->funcs->detect(connector, |
| 545 | false); | ||
| 546 | |||
| 554 | /* Don't force modeset on machines where it causes a GPU lockup */ | 547 | /* Don't force modeset on machines where it causes a GPU lockup */ |
| 555 | if (dmi_check_system(intel_no_modeset_on_lid)) | 548 | if (dmi_check_system(intel_no_modeset_on_lid)) |
| 556 | return NOTIFY_OK; | 549 | return NOTIFY_OK; |
| @@ -600,18 +593,17 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
| 600 | connector->encoder) { | 593 | connector->encoder) { |
| 601 | struct drm_crtc *crtc = connector->encoder->crtc; | 594 | struct drm_crtc *crtc = connector->encoder->crtc; |
| 602 | struct drm_encoder *encoder = connector->encoder; | 595 | struct drm_encoder *encoder = connector->encoder; |
| 603 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 596 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); |
| 604 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
| 605 | 597 | ||
| 606 | if (value == DRM_MODE_SCALE_NONE) { | 598 | if (value == DRM_MODE_SCALE_NONE) { |
| 607 | DRM_DEBUG_KMS("no scaling not supported\n"); | 599 | DRM_DEBUG_KMS("no scaling not supported\n"); |
| 608 | return 0; | 600 | return 0; |
| 609 | } | 601 | } |
| 610 | if (lvds_priv->fitting_mode == value) { | 602 | if (intel_lvds->fitting_mode == value) { |
| 611 | /* the LVDS scaling property is not changed */ | 603 | /* the LVDS scaling property is not changed */ |
| 612 | return 0; | 604 | return 0; |
| 613 | } | 605 | } |
| 614 | lvds_priv->fitting_mode = value; | 606 | intel_lvds->fitting_mode = value; |
| 615 | if (crtc && crtc->enabled) { | 607 | if (crtc && crtc->enabled) { |
| 616 | /* | 608 | /* |
| 617 | * If the CRTC is enabled, the display will be changed | 609 | * If the CRTC is enabled, the display will be changed |
| @@ -647,19 +639,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = { | |||
| 647 | .destroy = intel_lvds_destroy, | 639 | .destroy = intel_lvds_destroy, |
| 648 | }; | 640 | }; |
| 649 | 641 | ||
| 650 | |||
| 651 | static void intel_lvds_enc_destroy(struct drm_encoder *encoder) | ||
| 652 | { | ||
| 653 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 654 | |||
| 655 | if (intel_encoder->ddc_bus) | ||
| 656 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
| 657 | drm_encoder_cleanup(encoder); | ||
| 658 | kfree(intel_encoder); | ||
| 659 | } | ||
| 660 | |||
| 661 | static const struct drm_encoder_funcs intel_lvds_enc_funcs = { | 642 | static const struct drm_encoder_funcs intel_lvds_enc_funcs = { |
| 662 | .destroy = intel_lvds_enc_destroy, | 643 | .destroy = intel_encoder_destroy, |
| 663 | }; | 644 | }; |
| 664 | 645 | ||
| 665 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) | 646 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) |
| @@ -843,13 +824,13 @@ static int lvds_is_present_in_vbt(struct drm_device *dev) | |||
| 843 | void intel_lvds_init(struct drm_device *dev) | 824 | void intel_lvds_init(struct drm_device *dev) |
| 844 | { | 825 | { |
| 845 | struct drm_i915_private *dev_priv = dev->dev_private; | 826 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 827 | struct intel_lvds *intel_lvds; | ||
| 846 | struct intel_encoder *intel_encoder; | 828 | struct intel_encoder *intel_encoder; |
| 847 | struct intel_connector *intel_connector; | 829 | struct intel_connector *intel_connector; |
| 848 | struct drm_connector *connector; | 830 | struct drm_connector *connector; |
| 849 | struct drm_encoder *encoder; | 831 | struct drm_encoder *encoder; |
| 850 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ | 832 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
| 851 | struct drm_crtc *crtc; | 833 | struct drm_crtc *crtc; |
| 852 | struct intel_lvds_priv *lvds_priv; | ||
| 853 | u32 lvds; | 834 | u32 lvds; |
| 854 | int pipe, gpio = GPIOC; | 835 | int pipe, gpio = GPIOC; |
| 855 | 836 | ||
| @@ -872,20 +853,20 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 872 | gpio = PCH_GPIOC; | 853 | gpio = PCH_GPIOC; |
| 873 | } | 854 | } |
| 874 | 855 | ||
| 875 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + | 856 | intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL); |
| 876 | sizeof(struct intel_lvds_priv), GFP_KERNEL); | 857 | if (!intel_lvds) { |
| 877 | if (!intel_encoder) { | ||
| 878 | return; | 858 | return; |
| 879 | } | 859 | } |
| 880 | 860 | ||
| 881 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 861 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 882 | if (!intel_connector) { | 862 | if (!intel_connector) { |
| 883 | kfree(intel_encoder); | 863 | kfree(intel_lvds); |
| 884 | return; | 864 | return; |
| 885 | } | 865 | } |
| 886 | 866 | ||
| 887 | connector = &intel_connector->base; | 867 | intel_encoder = &intel_lvds->base; |
| 888 | encoder = &intel_encoder->enc; | 868 | encoder = &intel_encoder->enc; |
| 869 | connector = &intel_connector->base; | ||
| 889 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, | 870 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, |
| 890 | DRM_MODE_CONNECTOR_LVDS); | 871 | DRM_MODE_CONNECTOR_LVDS); |
| 891 | 872 | ||
| @@ -897,16 +878,12 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 897 | 878 | ||
| 898 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); | 879 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); |
| 899 | intel_encoder->crtc_mask = (1 << 1); | 880 | intel_encoder->crtc_mask = (1 << 1); |
| 900 | if (IS_I965G(dev)) | ||
| 901 | intel_encoder->crtc_mask |= (1 << 0); | ||
| 902 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); | 881 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); |
| 903 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); | 882 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); |
| 904 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 883 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
| 905 | connector->interlace_allowed = false; | 884 | connector->interlace_allowed = false; |
| 906 | connector->doublescan_allowed = false; | 885 | connector->doublescan_allowed = false; |
| 907 | 886 | ||
| 908 | lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1); | ||
| 909 | intel_encoder->dev_priv = lvds_priv; | ||
| 910 | /* create the scaling mode property */ | 887 | /* create the scaling mode property */ |
| 911 | drm_mode_create_scaling_mode_property(dev); | 888 | drm_mode_create_scaling_mode_property(dev); |
| 912 | /* | 889 | /* |
| @@ -916,7 +893,7 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 916 | drm_connector_attach_property(&intel_connector->base, | 893 | drm_connector_attach_property(&intel_connector->base, |
| 917 | dev->mode_config.scaling_mode_property, | 894 | dev->mode_config.scaling_mode_property, |
| 918 | DRM_MODE_SCALE_ASPECT); | 895 | DRM_MODE_SCALE_ASPECT); |
| 919 | lvds_priv->fitting_mode = DRM_MODE_SCALE_ASPECT; | 896 | intel_lvds->fitting_mode = DRM_MODE_SCALE_ASPECT; |
| 920 | /* | 897 | /* |
| 921 | * LVDS discovery: | 898 | * LVDS discovery: |
| 922 | * 1) check for EDID on DDC | 899 | * 1) check for EDID on DDC |
| @@ -1024,6 +1001,6 @@ failed: | |||
| 1024 | intel_i2c_destroy(intel_encoder->ddc_bus); | 1001 | intel_i2c_destroy(intel_encoder->ddc_bus); |
| 1025 | drm_connector_cleanup(connector); | 1002 | drm_connector_cleanup(connector); |
| 1026 | drm_encoder_cleanup(encoder); | 1003 | drm_encoder_cleanup(encoder); |
| 1027 | kfree(intel_encoder); | 1004 | kfree(intel_lvds); |
| 1028 | kfree(intel_connector); | 1005 | kfree(intel_connector); |
| 1029 | } | 1006 | } |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d39aea24eabe..1d306a458be6 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | * | 25 | * |
| 26 | * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c | 26 | * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c |
| 27 | */ | 27 | */ |
| 28 | |||
| 29 | #include <linux/seq_file.h> | ||
| 28 | #include "drmP.h" | 30 | #include "drmP.h" |
| 29 | #include "drm.h" | 31 | #include "drm.h" |
| 30 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
| @@ -1367,7 +1369,8 @@ void intel_setup_overlay(struct drm_device *dev) | |||
| 1367 | overlay->flip_addr = overlay->reg_bo->gtt_offset; | 1369 | overlay->flip_addr = overlay->reg_bo->gtt_offset; |
| 1368 | } else { | 1370 | } else { |
| 1369 | ret = i915_gem_attach_phys_object(dev, reg_bo, | 1371 | ret = i915_gem_attach_phys_object(dev, reg_bo, |
| 1370 | I915_GEM_PHYS_OVERLAY_REGS); | 1372 | I915_GEM_PHYS_OVERLAY_REGS, |
| 1373 | 0); | ||
| 1371 | if (ret) { | 1374 | if (ret) { |
| 1372 | DRM_ERROR("failed to attach phys overlay regs\n"); | 1375 | DRM_ERROR("failed to attach phys overlay regs\n"); |
| 1373 | goto out_free_bo; | 1376 | goto out_free_bo; |
| @@ -1416,3 +1419,99 @@ void intel_cleanup_overlay(struct drm_device *dev) | |||
| 1416 | kfree(dev_priv->overlay); | 1419 | kfree(dev_priv->overlay); |
| 1417 | } | 1420 | } |
| 1418 | } | 1421 | } |
| 1422 | |||
| 1423 | struct intel_overlay_error_state { | ||
| 1424 | struct overlay_registers regs; | ||
| 1425 | unsigned long base; | ||
| 1426 | u32 dovsta; | ||
| 1427 | u32 isr; | ||
| 1428 | }; | ||
| 1429 | |||
| 1430 | struct intel_overlay_error_state * | ||
| 1431 | intel_overlay_capture_error_state(struct drm_device *dev) | ||
| 1432 | { | ||
| 1433 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 1434 | struct intel_overlay *overlay = dev_priv->overlay; | ||
| 1435 | struct intel_overlay_error_state *error; | ||
| 1436 | struct overlay_registers __iomem *regs; | ||
| 1437 | |||
| 1438 | if (!overlay || !overlay->active) | ||
| 1439 | return NULL; | ||
| 1440 | |||
| 1441 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | ||
| 1442 | if (error == NULL) | ||
| 1443 | return NULL; | ||
| 1444 | |||
| 1445 | error->dovsta = I915_READ(DOVSTA); | ||
| 1446 | error->isr = I915_READ(ISR); | ||
| 1447 | if (OVERLAY_NONPHYSICAL(overlay->dev)) | ||
| 1448 | error->base = (long) overlay->reg_bo->gtt_offset; | ||
| 1449 | else | ||
| 1450 | error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr; | ||
| 1451 | |||
| 1452 | regs = intel_overlay_map_regs_atomic(overlay); | ||
| 1453 | if (!regs) | ||
| 1454 | goto err; | ||
| 1455 | |||
| 1456 | memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers)); | ||
| 1457 | intel_overlay_unmap_regs_atomic(overlay); | ||
| 1458 | |||
| 1459 | return error; | ||
| 1460 | |||
| 1461 | err: | ||
| 1462 | kfree(error); | ||
| 1463 | return NULL; | ||
| 1464 | } | ||
| 1465 | |||
| 1466 | void | ||
| 1467 | intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error) | ||
| 1468 | { | ||
| 1469 | seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", | ||
| 1470 | error->dovsta, error->isr); | ||
| 1471 | seq_printf(m, " Register file at 0x%08lx:\n", | ||
| 1472 | error->base); | ||
| 1473 | |||
| 1474 | #define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x) | ||
| 1475 | P(OBUF_0Y); | ||
| 1476 | P(OBUF_1Y); | ||
| 1477 | P(OBUF_0U); | ||
| 1478 | P(OBUF_0V); | ||
| 1479 | P(OBUF_1U); | ||
| 1480 | P(OBUF_1V); | ||
| 1481 | P(OSTRIDE); | ||
| 1482 | P(YRGB_VPH); | ||
| 1483 | P(UV_VPH); | ||
| 1484 | P(HORZ_PH); | ||
| 1485 | P(INIT_PHS); | ||
| 1486 | P(DWINPOS); | ||
| 1487 | P(DWINSZ); | ||
| 1488 | P(SWIDTH); | ||
| 1489 | P(SWIDTHSW); | ||
| 1490 | P(SHEIGHT); | ||
| 1491 | P(YRGBSCALE); | ||
| 1492 | P(UVSCALE); | ||
| 1493 | P(OCLRC0); | ||
| 1494 | P(OCLRC1); | ||
| 1495 | P(DCLRKV); | ||
| 1496 | P(DCLRKM); | ||
| 1497 | P(SCLRKVH); | ||
| 1498 | P(SCLRKVL); | ||
| 1499 | P(SCLRKEN); | ||
| 1500 | P(OCONFIG); | ||
| 1501 | P(OCMD); | ||
| 1502 | P(OSTART_0Y); | ||
| 1503 | P(OSTART_1Y); | ||
| 1504 | P(OSTART_0U); | ||
| 1505 | P(OSTART_0V); | ||
| 1506 | P(OSTART_1U); | ||
| 1507 | P(OSTART_1V); | ||
| 1508 | P(OTILEOFF_0Y); | ||
| 1509 | P(OTILEOFF_1Y); | ||
| 1510 | P(OTILEOFF_0U); | ||
| 1511 | P(OTILEOFF_0V); | ||
| 1512 | P(OTILEOFF_1U); | ||
| 1513 | P(OTILEOFF_1V); | ||
| 1514 | P(FASTHSCALE); | ||
| 1515 | P(UVSCALEV); | ||
| 1516 | #undef P | ||
| 1517 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c new file mode 100644 index 000000000000..e7f5299d9d57 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | /* | ||
| 2 | * Copyright © 2006-2010 Intel Corporation | ||
| 3 | * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> | ||
| 4 | * | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 6 | * copy of this software and associated documentation files (the "Software"), | ||
| 7 | * to deal in the Software without restriction, including without limitation | ||
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 10 | * Software is furnished to do so, subject to the following conditions: | ||
| 11 | * | ||
| 12 | * The above copyright notice and this permission notice (including the next | ||
| 13 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 14 | * Software. | ||
| 15 | * | ||
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 22 | * DEALINGS IN THE SOFTWARE. | ||
| 23 | * | ||
| 24 | * Authors: | ||
| 25 | * Eric Anholt <eric@anholt.net> | ||
| 26 | * Dave Airlie <airlied@linux.ie> | ||
| 27 | * Jesse Barnes <jesse.barnes@intel.com> | ||
| 28 | * Chris Wilson <chris@chris-wilson.co.uk> | ||
| 29 | */ | ||
| 30 | |||
| 31 | #include "intel_drv.h" | ||
| 32 | |||
| 33 | void | ||
| 34 | intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | ||
| 35 | struct drm_display_mode *adjusted_mode) | ||
| 36 | { | ||
| 37 | adjusted_mode->hdisplay = fixed_mode->hdisplay; | ||
| 38 | adjusted_mode->hsync_start = fixed_mode->hsync_start; | ||
| 39 | adjusted_mode->hsync_end = fixed_mode->hsync_end; | ||
| 40 | adjusted_mode->htotal = fixed_mode->htotal; | ||
| 41 | |||
| 42 | adjusted_mode->vdisplay = fixed_mode->vdisplay; | ||
| 43 | adjusted_mode->vsync_start = fixed_mode->vsync_start; | ||
| 44 | adjusted_mode->vsync_end = fixed_mode->vsync_end; | ||
| 45 | adjusted_mode->vtotal = fixed_mode->vtotal; | ||
| 46 | |||
| 47 | adjusted_mode->clock = fixed_mode->clock; | ||
| 48 | |||
| 49 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
| 50 | } | ||
| 51 | |||
| 52 | /* adjusted_mode has been preset to be the panel's fixed mode */ | ||
| 53 | void | ||
| 54 | intel_pch_panel_fitting(struct drm_device *dev, | ||
| 55 | int fitting_mode, | ||
| 56 | struct drm_display_mode *mode, | ||
| 57 | struct drm_display_mode *adjusted_mode) | ||
| 58 | { | ||
| 59 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 60 | int x, y, width, height; | ||
| 61 | |||
| 62 | x = y = width = height = 0; | ||
| 63 | |||
| 64 | /* Native modes don't need fitting */ | ||
| 65 | if (adjusted_mode->hdisplay == mode->hdisplay && | ||
| 66 | adjusted_mode->vdisplay == mode->vdisplay) | ||
| 67 | goto done; | ||
| 68 | |||
| 69 | switch (fitting_mode) { | ||
| 70 | case DRM_MODE_SCALE_CENTER: | ||
| 71 | width = mode->hdisplay; | ||
| 72 | height = mode->vdisplay; | ||
| 73 | x = (adjusted_mode->hdisplay - width + 1)/2; | ||
| 74 | y = (adjusted_mode->vdisplay - height + 1)/2; | ||
| 75 | break; | ||
| 76 | |||
| 77 | case DRM_MODE_SCALE_ASPECT: | ||
| 78 | /* Scale but preserve the aspect ratio */ | ||
| 79 | { | ||
| 80 | u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; | ||
| 81 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; | ||
| 82 | if (scaled_width > scaled_height) { /* pillar */ | ||
| 83 | width = scaled_height / mode->vdisplay; | ||
| 84 | x = (adjusted_mode->hdisplay - width + 1) / 2; | ||
| 85 | y = 0; | ||
| 86 | height = adjusted_mode->vdisplay; | ||
| 87 | } else if (scaled_width < scaled_height) { /* letter */ | ||
| 88 | height = scaled_width / mode->hdisplay; | ||
| 89 | y = (adjusted_mode->vdisplay - height + 1) / 2; | ||
| 90 | x = 0; | ||
| 91 | width = adjusted_mode->hdisplay; | ||
| 92 | } else { | ||
| 93 | x = y = 0; | ||
| 94 | width = adjusted_mode->hdisplay; | ||
| 95 | height = adjusted_mode->vdisplay; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | break; | ||
| 99 | |||
| 100 | default: | ||
| 101 | case DRM_MODE_SCALE_FULLSCREEN: | ||
| 102 | x = y = 0; | ||
| 103 | width = adjusted_mode->hdisplay; | ||
| 104 | height = adjusted_mode->vdisplay; | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | |||
| 108 | done: | ||
| 109 | dev_priv->pch_pf_pos = (x << 16) | y; | ||
| 110 | dev_priv->pch_pf_size = (width << 16) | height; | ||
| 111 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 26362f8495a8..cb3508f78bc3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -33,18 +33,35 @@ | |||
| 33 | #include "i915_drm.h" | 33 | #include "i915_drm.h" |
| 34 | #include "i915_trace.h" | 34 | #include "i915_trace.h" |
| 35 | 35 | ||
| 36 | static u32 i915_gem_get_seqno(struct drm_device *dev) | ||
| 37 | { | ||
| 38 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 39 | u32 seqno; | ||
| 40 | |||
| 41 | seqno = dev_priv->next_seqno; | ||
| 42 | |||
| 43 | /* reserve 0 for non-seqno */ | ||
| 44 | if (++dev_priv->next_seqno == 0) | ||
| 45 | dev_priv->next_seqno = 1; | ||
| 46 | |||
| 47 | return seqno; | ||
| 48 | } | ||
| 49 | |||
| 36 | static void | 50 | static void |
| 37 | render_ring_flush(struct drm_device *dev, | 51 | render_ring_flush(struct drm_device *dev, |
| 38 | struct intel_ring_buffer *ring, | 52 | struct intel_ring_buffer *ring, |
| 39 | u32 invalidate_domains, | 53 | u32 invalidate_domains, |
| 40 | u32 flush_domains) | 54 | u32 flush_domains) |
| 41 | { | 55 | { |
| 56 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 57 | u32 cmd; | ||
| 58 | |||
| 42 | #if WATCH_EXEC | 59 | #if WATCH_EXEC |
| 43 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, | 60 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, |
| 44 | invalidate_domains, flush_domains); | 61 | invalidate_domains, flush_domains); |
| 45 | #endif | 62 | #endif |
| 46 | u32 cmd; | 63 | |
| 47 | trace_i915_gem_request_flush(dev, ring->next_seqno, | 64 | trace_i915_gem_request_flush(dev, dev_priv->next_seqno, |
| 48 | invalidate_domains, flush_domains); | 65 | invalidate_domains, flush_domains); |
| 49 | 66 | ||
| 50 | if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { | 67 | if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { |
| @@ -203,9 +220,13 @@ static int init_render_ring(struct drm_device *dev, | |||
| 203 | { | 220 | { |
| 204 | drm_i915_private_t *dev_priv = dev->dev_private; | 221 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 205 | int ret = init_ring_common(dev, ring); | 222 | int ret = init_ring_common(dev, ring); |
| 223 | int mode; | ||
| 224 | |||
| 206 | if (IS_I9XX(dev) && !IS_GEN3(dev)) { | 225 | if (IS_I9XX(dev) && !IS_GEN3(dev)) { |
| 207 | I915_WRITE(MI_MODE, | 226 | mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; |
| 208 | (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); | 227 | if (IS_GEN6(dev)) |
| 228 | mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; | ||
| 229 | I915_WRITE(MI_MODE, mode); | ||
| 209 | } | 230 | } |
| 210 | return ret; | 231 | return ret; |
| 211 | } | 232 | } |
| @@ -233,9 +254,10 @@ render_ring_add_request(struct drm_device *dev, | |||
| 233 | struct drm_file *file_priv, | 254 | struct drm_file *file_priv, |
| 234 | u32 flush_domains) | 255 | u32 flush_domains) |
| 235 | { | 256 | { |
| 236 | u32 seqno; | ||
| 237 | drm_i915_private_t *dev_priv = dev->dev_private; | 257 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 238 | seqno = intel_ring_get_seqno(dev, ring); | 258 | u32 seqno; |
| 259 | |||
| 260 | seqno = i915_gem_get_seqno(dev); | ||
| 239 | 261 | ||
| 240 | if (IS_GEN6(dev)) { | 262 | if (IS_GEN6(dev)) { |
| 241 | BEGIN_LP_RING(6); | 263 | BEGIN_LP_RING(6); |
| @@ -405,7 +427,9 @@ bsd_ring_add_request(struct drm_device *dev, | |||
| 405 | u32 flush_domains) | 427 | u32 flush_domains) |
| 406 | { | 428 | { |
| 407 | u32 seqno; | 429 | u32 seqno; |
| 408 | seqno = intel_ring_get_seqno(dev, ring); | 430 | |
| 431 | seqno = i915_gem_get_seqno(dev); | ||
| 432 | |||
| 409 | intel_ring_begin(dev, ring, 4); | 433 | intel_ring_begin(dev, ring, 4); |
| 410 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); | 434 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); |
| 411 | intel_ring_emit(dev, ring, | 435 | intel_ring_emit(dev, ring, |
| @@ -479,7 +503,7 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | |||
| 479 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | 503 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; |
| 480 | exec_len = (uint32_t) exec->batch_len; | 504 | exec_len = (uint32_t) exec->batch_len; |
| 481 | 505 | ||
| 482 | trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); | 506 | trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1); |
| 483 | 507 | ||
| 484 | count = nbox ? nbox : 1; | 508 | count = nbox ? nbox : 1; |
| 485 | 509 | ||
| @@ -515,7 +539,16 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | |||
| 515 | intel_ring_advance(dev, ring); | 539 | intel_ring_advance(dev, ring); |
| 516 | } | 540 | } |
| 517 | 541 | ||
| 542 | if (IS_G4X(dev) || IS_IRONLAKE(dev)) { | ||
| 543 | intel_ring_begin(dev, ring, 2); | ||
| 544 | intel_ring_emit(dev, ring, MI_FLUSH | | ||
| 545 | MI_NO_WRITE_FLUSH | | ||
| 546 | MI_INVALIDATE_ISP ); | ||
| 547 | intel_ring_emit(dev, ring, MI_NOOP); | ||
| 548 | intel_ring_advance(dev, ring); | ||
| 549 | } | ||
| 518 | /* XXX breadcrumb */ | 550 | /* XXX breadcrumb */ |
| 551 | |||
| 519 | return 0; | 552 | return 0; |
| 520 | } | 553 | } |
| 521 | 554 | ||
| @@ -588,9 +621,10 @@ err: | |||
| 588 | int intel_init_ring_buffer(struct drm_device *dev, | 621 | int intel_init_ring_buffer(struct drm_device *dev, |
| 589 | struct intel_ring_buffer *ring) | 622 | struct intel_ring_buffer *ring) |
| 590 | { | 623 | { |
| 591 | int ret; | ||
| 592 | struct drm_i915_gem_object *obj_priv; | 624 | struct drm_i915_gem_object *obj_priv; |
| 593 | struct drm_gem_object *obj; | 625 | struct drm_gem_object *obj; |
| 626 | int ret; | ||
| 627 | |||
| 594 | ring->dev = dev; | 628 | ring->dev = dev; |
| 595 | 629 | ||
| 596 | if (I915_NEED_GFX_HWS(dev)) { | 630 | if (I915_NEED_GFX_HWS(dev)) { |
| @@ -603,16 +637,14 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
| 603 | if (obj == NULL) { | 637 | if (obj == NULL) { |
| 604 | DRM_ERROR("Failed to allocate ringbuffer\n"); | 638 | DRM_ERROR("Failed to allocate ringbuffer\n"); |
| 605 | ret = -ENOMEM; | 639 | ret = -ENOMEM; |
| 606 | goto cleanup; | 640 | goto err_hws; |
| 607 | } | 641 | } |
| 608 | 642 | ||
| 609 | ring->gem_object = obj; | 643 | ring->gem_object = obj; |
| 610 | 644 | ||
| 611 | ret = i915_gem_object_pin(obj, ring->alignment); | 645 | ret = i915_gem_object_pin(obj, ring->alignment); |
| 612 | if (ret != 0) { | 646 | if (ret) |
| 613 | drm_gem_object_unreference(obj); | 647 | goto err_unref; |
| 614 | goto cleanup; | ||
| 615 | } | ||
| 616 | 648 | ||
| 617 | obj_priv = to_intel_bo(obj); | 649 | obj_priv = to_intel_bo(obj); |
| 618 | ring->map.size = ring->size; | 650 | ring->map.size = ring->size; |
| @@ -624,18 +656,14 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
| 624 | drm_core_ioremap_wc(&ring->map, dev); | 656 | drm_core_ioremap_wc(&ring->map, dev); |
| 625 | if (ring->map.handle == NULL) { | 657 | if (ring->map.handle == NULL) { |
| 626 | DRM_ERROR("Failed to map ringbuffer.\n"); | 658 | DRM_ERROR("Failed to map ringbuffer.\n"); |
| 627 | i915_gem_object_unpin(obj); | ||
| 628 | drm_gem_object_unreference(obj); | ||
| 629 | ret = -EINVAL; | 659 | ret = -EINVAL; |
| 630 | goto cleanup; | 660 | goto err_unpin; |
| 631 | } | 661 | } |
| 632 | 662 | ||
| 633 | ring->virtual_start = ring->map.handle; | 663 | ring->virtual_start = ring->map.handle; |
| 634 | ret = ring->init(dev, ring); | 664 | ret = ring->init(dev, ring); |
| 635 | if (ret != 0) { | 665 | if (ret) |
| 636 | intel_cleanup_ring_buffer(dev, ring); | 666 | goto err_unmap; |
| 637 | return ret; | ||
| 638 | } | ||
| 639 | 667 | ||
| 640 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 668 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 641 | i915_kernel_lost_context(dev); | 669 | i915_kernel_lost_context(dev); |
| @@ -649,7 +677,15 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
| 649 | INIT_LIST_HEAD(&ring->active_list); | 677 | INIT_LIST_HEAD(&ring->active_list); |
| 650 | INIT_LIST_HEAD(&ring->request_list); | 678 | INIT_LIST_HEAD(&ring->request_list); |
| 651 | return ret; | 679 | return ret; |
| 652 | cleanup: | 680 | |
| 681 | err_unmap: | ||
| 682 | drm_core_ioremapfree(&ring->map, dev); | ||
| 683 | err_unpin: | ||
| 684 | i915_gem_object_unpin(obj); | ||
| 685 | err_unref: | ||
| 686 | drm_gem_object_unreference(obj); | ||
| 687 | ring->gem_object = NULL; | ||
| 688 | err_hws: | ||
| 653 | cleanup_status_page(dev, ring); | 689 | cleanup_status_page(dev, ring); |
| 654 | return ret; | 690 | return ret; |
| 655 | } | 691 | } |
| @@ -682,9 +718,11 @@ int intel_wrap_ring_buffer(struct drm_device *dev, | |||
| 682 | } | 718 | } |
| 683 | 719 | ||
| 684 | virt = (unsigned int *)(ring->virtual_start + ring->tail); | 720 | virt = (unsigned int *)(ring->virtual_start + ring->tail); |
| 685 | rem /= 4; | 721 | rem /= 8; |
| 686 | while (rem--) | 722 | while (rem--) { |
| 723 | *virt++ = MI_NOOP; | ||
| 687 | *virt++ = MI_NOOP; | 724 | *virt++ = MI_NOOP; |
| 725 | } | ||
| 688 | 726 | ||
| 689 | ring->tail = 0; | 727 | ring->tail = 0; |
| 690 | ring->space = ring->head - 8; | 728 | ring->space = ring->head - 8; |
| @@ -729,21 +767,14 @@ void intel_ring_begin(struct drm_device *dev, | |||
| 729 | intel_wrap_ring_buffer(dev, ring); | 767 | intel_wrap_ring_buffer(dev, ring); |
| 730 | if (unlikely(ring->space < n)) | 768 | if (unlikely(ring->space < n)) |
| 731 | intel_wait_ring_buffer(dev, ring, n); | 769 | intel_wait_ring_buffer(dev, ring, n); |
| 732 | } | ||
| 733 | 770 | ||
| 734 | void intel_ring_emit(struct drm_device *dev, | 771 | ring->space -= n; |
| 735 | struct intel_ring_buffer *ring, unsigned int data) | ||
| 736 | { | ||
| 737 | unsigned int *virt = ring->virtual_start + ring->tail; | ||
| 738 | *virt = data; | ||
| 739 | ring->tail += 4; | ||
| 740 | ring->tail &= ring->size - 1; | ||
| 741 | ring->space -= 4; | ||
| 742 | } | 772 | } |
| 743 | 773 | ||
| 744 | void intel_ring_advance(struct drm_device *dev, | 774 | void intel_ring_advance(struct drm_device *dev, |
| 745 | struct intel_ring_buffer *ring) | 775 | struct intel_ring_buffer *ring) |
| 746 | { | 776 | { |
| 777 | ring->tail &= ring->size - 1; | ||
| 747 | ring->advance_ring(dev, ring); | 778 | ring->advance_ring(dev, ring); |
| 748 | } | 779 | } |
| 749 | 780 | ||
| @@ -762,18 +793,6 @@ void intel_fill_struct(struct drm_device *dev, | |||
| 762 | intel_ring_advance(dev, ring); | 793 | intel_ring_advance(dev, ring); |
| 763 | } | 794 | } |
| 764 | 795 | ||
| 765 | u32 intel_ring_get_seqno(struct drm_device *dev, | ||
| 766 | struct intel_ring_buffer *ring) | ||
| 767 | { | ||
| 768 | u32 seqno; | ||
| 769 | seqno = ring->next_seqno; | ||
| 770 | |||
| 771 | /* reserve 0 for non-seqno */ | ||
| 772 | if (++ring->next_seqno == 0) | ||
| 773 | ring->next_seqno = 1; | ||
| 774 | return seqno; | ||
| 775 | } | ||
| 776 | |||
| 777 | struct intel_ring_buffer render_ring = { | 796 | struct intel_ring_buffer render_ring = { |
| 778 | .name = "render ring", | 797 | .name = "render ring", |
| 779 | .regs = { | 798 | .regs = { |
| @@ -791,7 +810,6 @@ struct intel_ring_buffer render_ring = { | |||
| 791 | .head = 0, | 810 | .head = 0, |
| 792 | .tail = 0, | 811 | .tail = 0, |
| 793 | .space = 0, | 812 | .space = 0, |
| 794 | .next_seqno = 1, | ||
| 795 | .user_irq_refcount = 0, | 813 | .user_irq_refcount = 0, |
| 796 | .irq_gem_seqno = 0, | 814 | .irq_gem_seqno = 0, |
| 797 | .waiting_gem_seqno = 0, | 815 | .waiting_gem_seqno = 0, |
| @@ -830,7 +848,6 @@ struct intel_ring_buffer bsd_ring = { | |||
| 830 | .head = 0, | 848 | .head = 0, |
| 831 | .tail = 0, | 849 | .tail = 0, |
| 832 | .space = 0, | 850 | .space = 0, |
| 833 | .next_seqno = 1, | ||
| 834 | .user_irq_refcount = 0, | 851 | .user_irq_refcount = 0, |
| 835 | .irq_gem_seqno = 0, | 852 | .irq_gem_seqno = 0, |
| 836 | .waiting_gem_seqno = 0, | 853 | .waiting_gem_seqno = 0, |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index d5568d3766de..525e7d3edda8 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
| @@ -26,7 +26,6 @@ struct intel_ring_buffer { | |||
| 26 | unsigned int head; | 26 | unsigned int head; |
| 27 | unsigned int tail; | 27 | unsigned int tail; |
| 28 | unsigned int space; | 28 | unsigned int space; |
| 29 | u32 next_seqno; | ||
| 30 | struct intel_hw_status_page status_page; | 29 | struct intel_hw_status_page status_page; |
| 31 | 30 | ||
| 32 | u32 irq_gem_seqno; /* last seq seem at irq time */ | 31 | u32 irq_gem_seqno; /* last seq seem at irq time */ |
| @@ -106,8 +105,16 @@ int intel_wrap_ring_buffer(struct drm_device *dev, | |||
| 106 | struct intel_ring_buffer *ring); | 105 | struct intel_ring_buffer *ring); |
| 107 | void intel_ring_begin(struct drm_device *dev, | 106 | void intel_ring_begin(struct drm_device *dev, |
| 108 | struct intel_ring_buffer *ring, int n); | 107 | struct intel_ring_buffer *ring, int n); |
| 109 | void intel_ring_emit(struct drm_device *dev, | 108 | |
| 110 | struct intel_ring_buffer *ring, u32 data); | 109 | static inline void intel_ring_emit(struct drm_device *dev, |
| 110 | struct intel_ring_buffer *ring, | ||
| 111 | unsigned int data) | ||
| 112 | { | ||
| 113 | unsigned int *virt = ring->virtual_start + ring->tail; | ||
| 114 | *virt = data; | ||
| 115 | ring->tail += 4; | ||
| 116 | } | ||
| 117 | |||
| 111 | void intel_fill_struct(struct drm_device *dev, | 118 | void intel_fill_struct(struct drm_device *dev, |
| 112 | struct intel_ring_buffer *ring, | 119 | struct intel_ring_buffer *ring, |
| 113 | void *data, | 120 | void *data, |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d9d4d51aa89e..ee73e428a84a 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -31,8 +31,8 @@ | |||
| 31 | #include "drmP.h" | 31 | #include "drmP.h" |
| 32 | #include "drm.h" | 32 | #include "drm.h" |
| 33 | #include "drm_crtc.h" | 33 | #include "drm_crtc.h" |
| 34 | #include "intel_drv.h" | ||
| 35 | #include "drm_edid.h" | 34 | #include "drm_edid.h" |
| 35 | #include "intel_drv.h" | ||
| 36 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
| 37 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
| 38 | #include "intel_sdvo_regs.h" | 38 | #include "intel_sdvo_regs.h" |
| @@ -47,9 +47,10 @@ | |||
| 47 | 47 | ||
| 48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) | 48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) |
| 49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) | 49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) |
| 50 | #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) | ||
| 50 | 51 | ||
| 51 | 52 | ||
| 52 | static char *tv_format_names[] = { | 53 | static const char *tv_format_names[] = { |
| 53 | "NTSC_M" , "NTSC_J" , "NTSC_443", | 54 | "NTSC_M" , "NTSC_J" , "NTSC_443", |
| 54 | "PAL_B" , "PAL_D" , "PAL_G" , | 55 | "PAL_B" , "PAL_D" , "PAL_G" , |
| 55 | "PAL_H" , "PAL_I" , "PAL_M" , | 56 | "PAL_H" , "PAL_I" , "PAL_M" , |
| @@ -61,7 +62,9 @@ static char *tv_format_names[] = { | |||
| 61 | 62 | ||
| 62 | #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) | 63 | #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) |
| 63 | 64 | ||
| 64 | struct intel_sdvo_priv { | 65 | struct intel_sdvo { |
| 66 | struct intel_encoder base; | ||
| 67 | |||
| 65 | u8 slave_addr; | 68 | u8 slave_addr; |
| 66 | 69 | ||
| 67 | /* Register for the SDVO device: SDVOB or SDVOC */ | 70 | /* Register for the SDVO device: SDVOB or SDVOC */ |
| @@ -95,7 +98,7 @@ struct intel_sdvo_priv { | |||
| 95 | bool is_tv; | 98 | bool is_tv; |
| 96 | 99 | ||
| 97 | /* This is for current tv format name */ | 100 | /* This is for current tv format name */ |
| 98 | char *tv_format_name; | 101 | int tv_format_index; |
| 99 | 102 | ||
| 100 | /** | 103 | /** |
| 101 | * This is set if we treat the device as HDMI, instead of DVI. | 104 | * This is set if we treat the device as HDMI, instead of DVI. |
| @@ -132,37 +135,40 @@ struct intel_sdvo_priv { | |||
| 132 | }; | 135 | }; |
| 133 | 136 | ||
| 134 | struct intel_sdvo_connector { | 137 | struct intel_sdvo_connector { |
| 138 | struct intel_connector base; | ||
| 139 | |||
| 135 | /* Mark the type of connector */ | 140 | /* Mark the type of connector */ |
| 136 | uint16_t output_flag; | 141 | uint16_t output_flag; |
| 137 | 142 | ||
| 138 | /* This contains all current supported TV format */ | 143 | /* This contains all current supported TV format */ |
| 139 | char *tv_format_supported[TV_FORMAT_NUM]; | 144 | u8 tv_format_supported[TV_FORMAT_NUM]; |
| 140 | int format_supported_num; | 145 | int format_supported_num; |
| 141 | struct drm_property *tv_format_property; | 146 | struct drm_property *tv_format; |
| 142 | struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; | ||
| 143 | |||
| 144 | /** | ||
| 145 | * Returned SDTV resolutions allowed for the current format, if the | ||
| 146 | * device reported it. | ||
| 147 | */ | ||
| 148 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; | ||
| 149 | 147 | ||
| 150 | /* add the property for the SDVO-TV */ | 148 | /* add the property for the SDVO-TV */ |
| 151 | struct drm_property *left_property; | 149 | struct drm_property *left; |
| 152 | struct drm_property *right_property; | 150 | struct drm_property *right; |
| 153 | struct drm_property *top_property; | 151 | struct drm_property *top; |
| 154 | struct drm_property *bottom_property; | 152 | struct drm_property *bottom; |
| 155 | struct drm_property *hpos_property; | 153 | struct drm_property *hpos; |
| 156 | struct drm_property *vpos_property; | 154 | struct drm_property *vpos; |
| 155 | struct drm_property *contrast; | ||
| 156 | struct drm_property *saturation; | ||
| 157 | struct drm_property *hue; | ||
| 158 | struct drm_property *sharpness; | ||
| 159 | struct drm_property *flicker_filter; | ||
| 160 | struct drm_property *flicker_filter_adaptive; | ||
| 161 | struct drm_property *flicker_filter_2d; | ||
| 162 | struct drm_property *tv_chroma_filter; | ||
| 163 | struct drm_property *tv_luma_filter; | ||
| 164 | struct drm_property *dot_crawl; | ||
| 157 | 165 | ||
| 158 | /* add the property for the SDVO-TV/LVDS */ | 166 | /* add the property for the SDVO-TV/LVDS */ |
| 159 | struct drm_property *brightness_property; | 167 | struct drm_property *brightness; |
| 160 | struct drm_property *contrast_property; | ||
| 161 | struct drm_property *saturation_property; | ||
| 162 | struct drm_property *hue_property; | ||
| 163 | 168 | ||
| 164 | /* Add variable to record current setting for the above property */ | 169 | /* Add variable to record current setting for the above property */ |
| 165 | u32 left_margin, right_margin, top_margin, bottom_margin; | 170 | u32 left_margin, right_margin, top_margin, bottom_margin; |
| 171 | |||
| 166 | /* this is to get the range of margin.*/ | 172 | /* this is to get the range of margin.*/ |
| 167 | u32 max_hscan, max_vscan; | 173 | u32 max_hscan, max_vscan; |
| 168 | u32 max_hpos, cur_hpos; | 174 | u32 max_hpos, cur_hpos; |
| @@ -171,36 +177,54 @@ struct intel_sdvo_connector { | |||
| 171 | u32 cur_contrast, max_contrast; | 177 | u32 cur_contrast, max_contrast; |
| 172 | u32 cur_saturation, max_saturation; | 178 | u32 cur_saturation, max_saturation; |
| 173 | u32 cur_hue, max_hue; | 179 | u32 cur_hue, max_hue; |
| 180 | u32 cur_sharpness, max_sharpness; | ||
| 181 | u32 cur_flicker_filter, max_flicker_filter; | ||
| 182 | u32 cur_flicker_filter_adaptive, max_flicker_filter_adaptive; | ||
| 183 | u32 cur_flicker_filter_2d, max_flicker_filter_2d; | ||
| 184 | u32 cur_tv_chroma_filter, max_tv_chroma_filter; | ||
| 185 | u32 cur_tv_luma_filter, max_tv_luma_filter; | ||
| 186 | u32 cur_dot_crawl, max_dot_crawl; | ||
| 174 | }; | 187 | }; |
| 175 | 188 | ||
| 189 | static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder) | ||
| 190 | { | ||
| 191 | return container_of(enc_to_intel_encoder(encoder), struct intel_sdvo, base); | ||
| 192 | } | ||
| 193 | |||
| 194 | static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) | ||
| 195 | { | ||
| 196 | return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base); | ||
| 197 | } | ||
| 198 | |||
| 176 | static bool | 199 | static bool |
| 177 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, | 200 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags); |
| 178 | uint16_t flags); | 201 | static bool |
| 179 | static void | 202 | intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
| 180 | intel_sdvo_tv_create_property(struct drm_connector *connector, int type); | 203 | struct intel_sdvo_connector *intel_sdvo_connector, |
| 181 | static void | 204 | int type); |
| 182 | intel_sdvo_create_enhance_property(struct drm_connector *connector); | 205 | static bool |
| 206 | intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, | ||
| 207 | struct intel_sdvo_connector *intel_sdvo_connector); | ||
| 183 | 208 | ||
| 184 | /** | 209 | /** |
| 185 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 210 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
| 186 | * SDVOB and SDVOC to work around apparent hardware issues (according to | 211 | * SDVOB and SDVOC to work around apparent hardware issues (according to |
| 187 | * comments in the BIOS). | 212 | * comments in the BIOS). |
| 188 | */ | 213 | */ |
| 189 | static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) | 214 | static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) |
| 190 | { | 215 | { |
| 191 | struct drm_device *dev = intel_encoder->enc.dev; | 216 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
| 192 | struct drm_i915_private *dev_priv = dev->dev_private; | 217 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 193 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 194 | u32 bval = val, cval = val; | 218 | u32 bval = val, cval = val; |
| 195 | int i; | 219 | int i; |
| 196 | 220 | ||
| 197 | if (sdvo_priv->sdvo_reg == PCH_SDVOB) { | 221 | if (intel_sdvo->sdvo_reg == PCH_SDVOB) { |
| 198 | I915_WRITE(sdvo_priv->sdvo_reg, val); | 222 | I915_WRITE(intel_sdvo->sdvo_reg, val); |
| 199 | I915_READ(sdvo_priv->sdvo_reg); | 223 | I915_READ(intel_sdvo->sdvo_reg); |
| 200 | return; | 224 | return; |
| 201 | } | 225 | } |
| 202 | 226 | ||
| 203 | if (sdvo_priv->sdvo_reg == SDVOB) { | 227 | if (intel_sdvo->sdvo_reg == SDVOB) { |
| 204 | cval = I915_READ(SDVOC); | 228 | cval = I915_READ(SDVOC); |
| 205 | } else { | 229 | } else { |
| 206 | bval = I915_READ(SDVOB); | 230 | bval = I915_READ(SDVOB); |
| @@ -219,33 +243,27 @@ static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) | |||
| 219 | } | 243 | } |
| 220 | } | 244 | } |
| 221 | 245 | ||
| 222 | static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, | 246 | static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) |
| 223 | u8 *ch) | ||
| 224 | { | 247 | { |
| 225 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 248 | u8 out_buf[2] = { addr, 0 }; |
| 226 | u8 out_buf[2]; | ||
| 227 | u8 buf[2]; | 249 | u8 buf[2]; |
| 228 | int ret; | ||
| 229 | |||
| 230 | struct i2c_msg msgs[] = { | 250 | struct i2c_msg msgs[] = { |
| 231 | { | 251 | { |
| 232 | .addr = sdvo_priv->slave_addr >> 1, | 252 | .addr = intel_sdvo->slave_addr >> 1, |
| 233 | .flags = 0, | 253 | .flags = 0, |
| 234 | .len = 1, | 254 | .len = 1, |
| 235 | .buf = out_buf, | 255 | .buf = out_buf, |
| 236 | }, | 256 | }, |
| 237 | { | 257 | { |
| 238 | .addr = sdvo_priv->slave_addr >> 1, | 258 | .addr = intel_sdvo->slave_addr >> 1, |
| 239 | .flags = I2C_M_RD, | 259 | .flags = I2C_M_RD, |
| 240 | .len = 1, | 260 | .len = 1, |
| 241 | .buf = buf, | 261 | .buf = buf, |
| 242 | } | 262 | } |
| 243 | }; | 263 | }; |
| 264 | int ret; | ||
| 244 | 265 | ||
| 245 | out_buf[0] = addr; | 266 | if ((ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 2)) == 2) |
| 246 | out_buf[1] = 0; | ||
| 247 | |||
| 248 | if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2) | ||
| 249 | { | 267 | { |
| 250 | *ch = buf[0]; | 268 | *ch = buf[0]; |
| 251 | return true; | 269 | return true; |
| @@ -255,35 +273,26 @@ static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, | |||
| 255 | return false; | 273 | return false; |
| 256 | } | 274 | } |
| 257 | 275 | ||
| 258 | static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr, | 276 | static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, u8 ch) |
| 259 | u8 ch) | ||
| 260 | { | 277 | { |
| 261 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 278 | u8 out_buf[2] = { addr, ch }; |
| 262 | u8 out_buf[2]; | ||
| 263 | struct i2c_msg msgs[] = { | 279 | struct i2c_msg msgs[] = { |
| 264 | { | 280 | { |
| 265 | .addr = sdvo_priv->slave_addr >> 1, | 281 | .addr = intel_sdvo->slave_addr >> 1, |
| 266 | .flags = 0, | 282 | .flags = 0, |
| 267 | .len = 2, | 283 | .len = 2, |
| 268 | .buf = out_buf, | 284 | .buf = out_buf, |
| 269 | } | 285 | } |
| 270 | }; | 286 | }; |
| 271 | 287 | ||
| 272 | out_buf[0] = addr; | 288 | return i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 1) == 1; |
| 273 | out_buf[1] = ch; | ||
| 274 | |||
| 275 | if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1) | ||
| 276 | { | ||
| 277 | return true; | ||
| 278 | } | ||
| 279 | return false; | ||
| 280 | } | 289 | } |
| 281 | 290 | ||
| 282 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} | 291 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} |
| 283 | /** Mapping of command numbers to names, for debug output */ | 292 | /** Mapping of command numbers to names, for debug output */ |
| 284 | static const struct _sdvo_cmd_name { | 293 | static const struct _sdvo_cmd_name { |
| 285 | u8 cmd; | 294 | u8 cmd; |
| 286 | char *name; | 295 | const char *name; |
| 287 | } sdvo_cmd_names[] = { | 296 | } sdvo_cmd_names[] = { |
| 288 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), | 297 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), |
| 289 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), | 298 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), |
| @@ -328,13 +337,14 @@ static const struct _sdvo_cmd_name { | |||
| 328 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), | 337 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), |
| 329 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), | 338 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), |
| 330 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), | 339 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), |
| 340 | |||
| 331 | /* Add the op code for SDVO enhancements */ | 341 | /* Add the op code for SDVO enhancements */ |
| 332 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_H), | 342 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS), |
| 333 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_H), | 343 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS), |
| 334 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_H), | 344 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS), |
| 335 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_V), | 345 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS), |
| 336 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_V), | 346 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS), |
| 337 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_V), | 347 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS), |
| 338 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), | 348 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), |
| 339 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), | 349 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), |
| 340 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), | 350 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), |
| @@ -353,6 +363,27 @@ static const struct _sdvo_cmd_name { | |||
| 353 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), | 363 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), |
| 354 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), | 364 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), |
| 355 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), | 365 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), |
| 366 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER), | ||
| 367 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER), | ||
| 368 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER), | ||
| 369 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE), | ||
| 370 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE), | ||
| 371 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE), | ||
| 372 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D), | ||
| 373 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D), | ||
| 374 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D), | ||
| 375 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS), | ||
| 376 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS), | ||
| 377 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS), | ||
| 378 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL), | ||
| 379 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL), | ||
| 380 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER), | ||
| 381 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER), | ||
| 382 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER), | ||
| 383 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER), | ||
| 384 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER), | ||
| 385 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER), | ||
| 386 | |||
| 356 | /* HDMI op code */ | 387 | /* HDMI op code */ |
| 357 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), | 388 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), |
| 358 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), | 389 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), |
| @@ -377,17 +408,15 @@ static const struct _sdvo_cmd_name { | |||
| 377 | }; | 408 | }; |
| 378 | 409 | ||
| 379 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) | 410 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) |
| 380 | #define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->sdvo_reg) ? "SDVOB" : "SDVOC") | 411 | #define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC") |
| 381 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) | ||
| 382 | 412 | ||
| 383 | static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | 413 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, |
| 384 | void *args, int args_len) | 414 | const void *args, int args_len) |
| 385 | { | 415 | { |
| 386 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 387 | int i; | 416 | int i; |
| 388 | 417 | ||
| 389 | DRM_DEBUG_KMS("%s: W: %02X ", | 418 | DRM_DEBUG_KMS("%s: W: %02X ", |
| 390 | SDVO_NAME(sdvo_priv), cmd); | 419 | SDVO_NAME(intel_sdvo), cmd); |
| 391 | for (i = 0; i < args_len; i++) | 420 | for (i = 0; i < args_len; i++) |
| 392 | DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); | 421 | DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); |
| 393 | for (; i < 8; i++) | 422 | for (; i < 8; i++) |
| @@ -403,19 +432,20 @@ static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | |||
| 403 | DRM_LOG_KMS("\n"); | 432 | DRM_LOG_KMS("\n"); |
| 404 | } | 433 | } |
| 405 | 434 | ||
| 406 | static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd, | 435 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, |
| 407 | void *args, int args_len) | 436 | const void *args, int args_len) |
| 408 | { | 437 | { |
| 409 | int i; | 438 | int i; |
| 410 | 439 | ||
| 411 | intel_sdvo_debug_write(intel_encoder, cmd, args, args_len); | 440 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
| 412 | 441 | ||
| 413 | for (i = 0; i < args_len; i++) { | 442 | for (i = 0; i < args_len; i++) { |
| 414 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i, | 443 | if (!intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0 - i, |
| 415 | ((u8*)args)[i]); | 444 | ((u8*)args)[i])) |
| 445 | return false; | ||
| 416 | } | 446 | } |
| 417 | 447 | ||
| 418 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd); | 448 | return intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_OPCODE, cmd); |
| 419 | } | 449 | } |
| 420 | 450 | ||
| 421 | static const char *cmd_status_names[] = { | 451 | static const char *cmd_status_names[] = { |
| @@ -428,14 +458,13 @@ static const char *cmd_status_names[] = { | |||
| 428 | "Scaling not supported" | 458 | "Scaling not supported" |
| 429 | }; | 459 | }; |
| 430 | 460 | ||
| 431 | static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, | 461 | static void intel_sdvo_debug_response(struct intel_sdvo *intel_sdvo, |
| 432 | void *response, int response_len, | 462 | void *response, int response_len, |
| 433 | u8 status) | 463 | u8 status) |
| 434 | { | 464 | { |
| 435 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 436 | int i; | 465 | int i; |
| 437 | 466 | ||
| 438 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv)); | 467 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo)); |
| 439 | for (i = 0; i < response_len; i++) | 468 | for (i = 0; i < response_len; i++) |
| 440 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); | 469 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); |
| 441 | for (; i < 8; i++) | 470 | for (; i < 8; i++) |
| @@ -447,8 +476,8 @@ static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, | |||
| 447 | DRM_LOG_KMS("\n"); | 476 | DRM_LOG_KMS("\n"); |
| 448 | } | 477 | } |
| 449 | 478 | ||
| 450 | static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, | 479 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, |
| 451 | void *response, int response_len) | 480 | void *response, int response_len) |
| 452 | { | 481 | { |
| 453 | int i; | 482 | int i; |
| 454 | u8 status; | 483 | u8 status; |
| @@ -457,24 +486,26 @@ static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, | |||
| 457 | while (retry--) { | 486 | while (retry--) { |
| 458 | /* Read the command response */ | 487 | /* Read the command response */ |
| 459 | for (i = 0; i < response_len; i++) { | 488 | for (i = 0; i < response_len; i++) { |
| 460 | intel_sdvo_read_byte(intel_encoder, | 489 | if (!intel_sdvo_read_byte(intel_sdvo, |
| 461 | SDVO_I2C_RETURN_0 + i, | 490 | SDVO_I2C_RETURN_0 + i, |
| 462 | &((u8 *)response)[i]); | 491 | &((u8 *)response)[i])) |
| 492 | return false; | ||
| 463 | } | 493 | } |
| 464 | 494 | ||
| 465 | /* read the return status */ | 495 | /* read the return status */ |
| 466 | intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS, | 496 | if (!intel_sdvo_read_byte(intel_sdvo, SDVO_I2C_CMD_STATUS, |
| 467 | &status); | 497 | &status)) |
| 498 | return false; | ||
| 468 | 499 | ||
| 469 | intel_sdvo_debug_response(intel_encoder, response, response_len, | 500 | intel_sdvo_debug_response(intel_sdvo, response, response_len, |
| 470 | status); | 501 | status); |
| 471 | if (status != SDVO_CMD_STATUS_PENDING) | 502 | if (status != SDVO_CMD_STATUS_PENDING) |
| 472 | return status; | 503 | break; |
| 473 | 504 | ||
| 474 | mdelay(50); | 505 | mdelay(50); |
| 475 | } | 506 | } |
| 476 | 507 | ||
| 477 | return status; | 508 | return status == SDVO_CMD_STATUS_SUCCESS; |
| 478 | } | 509 | } |
| 479 | 510 | ||
| 480 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | 511 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) |
| @@ -494,37 +525,36 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | |||
| 494 | * another I2C transaction after issuing the DDC bus switch, it will be | 525 | * another I2C transaction after issuing the DDC bus switch, it will be |
| 495 | * switched to the internal SDVO register. | 526 | * switched to the internal SDVO register. |
| 496 | */ | 527 | */ |
| 497 | static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder, | 528 | static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, |
| 498 | u8 target) | 529 | u8 target) |
| 499 | { | 530 | { |
| 500 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 501 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; | 531 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; |
| 502 | struct i2c_msg msgs[] = { | 532 | struct i2c_msg msgs[] = { |
| 503 | { | 533 | { |
| 504 | .addr = sdvo_priv->slave_addr >> 1, | 534 | .addr = intel_sdvo->slave_addr >> 1, |
| 505 | .flags = 0, | 535 | .flags = 0, |
| 506 | .len = 2, | 536 | .len = 2, |
| 507 | .buf = out_buf, | 537 | .buf = out_buf, |
| 508 | }, | 538 | }, |
| 509 | /* the following two are to read the response */ | 539 | /* the following two are to read the response */ |
| 510 | { | 540 | { |
| 511 | .addr = sdvo_priv->slave_addr >> 1, | 541 | .addr = intel_sdvo->slave_addr >> 1, |
| 512 | .flags = 0, | 542 | .flags = 0, |
| 513 | .len = 1, | 543 | .len = 1, |
| 514 | .buf = cmd_buf, | 544 | .buf = cmd_buf, |
| 515 | }, | 545 | }, |
| 516 | { | 546 | { |
| 517 | .addr = sdvo_priv->slave_addr >> 1, | 547 | .addr = intel_sdvo->slave_addr >> 1, |
| 518 | .flags = I2C_M_RD, | 548 | .flags = I2C_M_RD, |
| 519 | .len = 1, | 549 | .len = 1, |
| 520 | .buf = ret_value, | 550 | .buf = ret_value, |
| 521 | }, | 551 | }, |
| 522 | }; | 552 | }; |
| 523 | 553 | ||
| 524 | intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH, | 554 | intel_sdvo_debug_write(intel_sdvo, SDVO_CMD_SET_CONTROL_BUS_SWITCH, |
| 525 | &target, 1); | 555 | &target, 1); |
| 526 | /* write the DDC switch command argument */ | 556 | /* write the DDC switch command argument */ |
| 527 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target); | 557 | intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0, target); |
| 528 | 558 | ||
| 529 | out_buf[0] = SDVO_I2C_OPCODE; | 559 | out_buf[0] = SDVO_I2C_OPCODE; |
| 530 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; | 560 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; |
| @@ -533,7 +563,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encode | |||
| 533 | ret_value[0] = 0; | 563 | ret_value[0] = 0; |
| 534 | ret_value[1] = 0; | 564 | ret_value[1] = 0; |
| 535 | 565 | ||
| 536 | ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3); | 566 | ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 3); |
| 537 | if (ret != 3) { | 567 | if (ret != 3) { |
| 538 | /* failure in I2C transfer */ | 568 | /* failure in I2C transfer */ |
| 539 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | 569 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); |
| @@ -547,23 +577,29 @@ static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encode | |||
| 547 | return; | 577 | return; |
| 548 | } | 578 | } |
| 549 | 579 | ||
| 550 | static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1) | 580 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) |
| 551 | { | 581 | { |
| 552 | struct intel_sdvo_set_target_input_args targets = {0}; | 582 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len)) |
| 553 | u8 status; | 583 | return false; |
| 554 | |||
| 555 | if (target_0 && target_1) | ||
| 556 | return SDVO_CMD_STATUS_NOTSUPP; | ||
| 557 | 584 | ||
| 558 | if (target_1) | 585 | return intel_sdvo_read_response(intel_sdvo, NULL, 0); |
| 559 | targets.target_1 = 1; | 586 | } |
| 560 | 587 | ||
| 561 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets, | 588 | static bool |
| 562 | sizeof(targets)); | 589 | intel_sdvo_get_value(struct intel_sdvo *intel_sdvo, u8 cmd, void *value, int len) |
| 590 | { | ||
| 591 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, NULL, 0)) | ||
| 592 | return false; | ||
| 563 | 593 | ||
| 564 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 594 | return intel_sdvo_read_response(intel_sdvo, value, len); |
| 595 | } | ||
| 565 | 596 | ||
| 566 | return (status == SDVO_CMD_STATUS_SUCCESS); | 597 | static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo) |
| 598 | { | ||
| 599 | struct intel_sdvo_set_target_input_args targets = {0}; | ||
| 600 | return intel_sdvo_set_value(intel_sdvo, | ||
| 601 | SDVO_CMD_SET_TARGET_INPUT, | ||
| 602 | &targets, sizeof(targets)); | ||
| 567 | } | 603 | } |
| 568 | 604 | ||
| 569 | /** | 605 | /** |
| @@ -572,14 +608,12 @@ static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, boo | |||
| 572 | * This function is making an assumption about the layout of the response, | 608 | * This function is making an assumption about the layout of the response, |
| 573 | * which should be checked against the docs. | 609 | * which should be checked against the docs. |
| 574 | */ | 610 | */ |
| 575 | static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2) | 611 | static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2) |
| 576 | { | 612 | { |
| 577 | struct intel_sdvo_get_trained_inputs_response response; | 613 | struct intel_sdvo_get_trained_inputs_response response; |
| 578 | u8 status; | ||
| 579 | 614 | ||
| 580 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); | 615 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS, |
| 581 | status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response)); | 616 | &response, sizeof(response))) |
| 582 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 583 | return false; | 617 | return false; |
| 584 | 618 | ||
| 585 | *input_1 = response.input0_trained; | 619 | *input_1 = response.input0_trained; |
| @@ -587,21 +621,18 @@ static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, b | |||
| 587 | return true; | 621 | return true; |
| 588 | } | 622 | } |
| 589 | 623 | ||
| 590 | static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, | 624 | static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo, |
| 591 | u16 outputs) | 625 | u16 outputs) |
| 592 | { | 626 | { |
| 593 | u8 status; | 627 | return intel_sdvo_set_value(intel_sdvo, |
| 594 | 628 | SDVO_CMD_SET_ACTIVE_OUTPUTS, | |
| 595 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, | 629 | &outputs, sizeof(outputs)); |
| 596 | sizeof(outputs)); | ||
| 597 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 598 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
| 599 | } | 630 | } |
| 600 | 631 | ||
| 601 | static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder, | 632 | static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, |
| 602 | int mode) | 633 | int mode) |
| 603 | { | 634 | { |
| 604 | u8 status, state = SDVO_ENCODER_STATE_ON; | 635 | u8 state = SDVO_ENCODER_STATE_ON; |
| 605 | 636 | ||
| 606 | switch (mode) { | 637 | switch (mode) { |
| 607 | case DRM_MODE_DPMS_ON: | 638 | case DRM_MODE_DPMS_ON: |
| @@ -618,88 +649,63 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encod | |||
| 618 | break; | 649 | break; |
| 619 | } | 650 | } |
| 620 | 651 | ||
| 621 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, | 652 | return intel_sdvo_set_value(intel_sdvo, |
| 622 | sizeof(state)); | 653 | SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); |
| 623 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 624 | |||
| 625 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
| 626 | } | 654 | } |
| 627 | 655 | ||
| 628 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder, | 656 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo, |
| 629 | int *clock_min, | 657 | int *clock_min, |
| 630 | int *clock_max) | 658 | int *clock_max) |
| 631 | { | 659 | { |
| 632 | struct intel_sdvo_pixel_clock_range clocks; | 660 | struct intel_sdvo_pixel_clock_range clocks; |
| 633 | u8 status; | ||
| 634 | |||
| 635 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | ||
| 636 | NULL, 0); | ||
| 637 | |||
| 638 | status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks)); | ||
| 639 | 661 | ||
| 640 | if (status != SDVO_CMD_STATUS_SUCCESS) | 662 | if (!intel_sdvo_get_value(intel_sdvo, |
| 663 | SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | ||
| 664 | &clocks, sizeof(clocks))) | ||
| 641 | return false; | 665 | return false; |
| 642 | 666 | ||
| 643 | /* Convert the values from units of 10 kHz to kHz. */ | 667 | /* Convert the values from units of 10 kHz to kHz. */ |
| 644 | *clock_min = clocks.min * 10; | 668 | *clock_min = clocks.min * 10; |
| 645 | *clock_max = clocks.max * 10; | 669 | *clock_max = clocks.max * 10; |
| 646 | |||
| 647 | return true; | 670 | return true; |
| 648 | } | 671 | } |
| 649 | 672 | ||
| 650 | static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder, | 673 | static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo, |
| 651 | u16 outputs) | 674 | u16 outputs) |
| 652 | { | 675 | { |
| 653 | u8 status; | 676 | return intel_sdvo_set_value(intel_sdvo, |
| 654 | 677 | SDVO_CMD_SET_TARGET_OUTPUT, | |
| 655 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, | 678 | &outputs, sizeof(outputs)); |
| 656 | sizeof(outputs)); | ||
| 657 | |||
| 658 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 659 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
| 660 | } | 679 | } |
| 661 | 680 | ||
| 662 | static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, | 681 | static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, |
| 663 | struct intel_sdvo_dtd *dtd) | 682 | struct intel_sdvo_dtd *dtd) |
| 664 | { | 683 | { |
| 665 | u8 status; | 684 | return intel_sdvo_set_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && |
| 666 | 685 | intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | |
| 667 | intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1)); | ||
| 668 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 669 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 670 | return false; | ||
| 671 | |||
| 672 | intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | ||
| 673 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 674 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 675 | return false; | ||
| 676 | |||
| 677 | return true; | ||
| 678 | } | 686 | } |
| 679 | 687 | ||
| 680 | static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder, | 688 | static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, |
| 681 | struct intel_sdvo_dtd *dtd) | 689 | struct intel_sdvo_dtd *dtd) |
| 682 | { | 690 | { |
| 683 | return intel_sdvo_set_timing(intel_encoder, | 691 | return intel_sdvo_set_timing(intel_sdvo, |
| 684 | SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); | 692 | SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); |
| 685 | } | 693 | } |
| 686 | 694 | ||
| 687 | static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder, | 695 | static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo, |
| 688 | struct intel_sdvo_dtd *dtd) | 696 | struct intel_sdvo_dtd *dtd) |
| 689 | { | 697 | { |
| 690 | return intel_sdvo_set_timing(intel_encoder, | 698 | return intel_sdvo_set_timing(intel_sdvo, |
| 691 | SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); | 699 | SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); |
| 692 | } | 700 | } |
| 693 | 701 | ||
| 694 | static bool | 702 | static bool |
| 695 | intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, | 703 | intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, |
| 696 | uint16_t clock, | 704 | uint16_t clock, |
| 697 | uint16_t width, | 705 | uint16_t width, |
| 698 | uint16_t height) | 706 | uint16_t height) |
| 699 | { | 707 | { |
| 700 | struct intel_sdvo_preferred_input_timing_args args; | 708 | struct intel_sdvo_preferred_input_timing_args args; |
| 701 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 702 | uint8_t status; | ||
| 703 | 709 | ||
| 704 | memset(&args, 0, sizeof(args)); | 710 | memset(&args, 0, sizeof(args)); |
| 705 | args.clock = clock; | 711 | args.clock = clock; |
| @@ -707,59 +713,32 @@ intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, | |||
| 707 | args.height = height; | 713 | args.height = height; |
| 708 | args.interlace = 0; | 714 | args.interlace = 0; |
| 709 | 715 | ||
| 710 | if (sdvo_priv->is_lvds && | 716 | if (intel_sdvo->is_lvds && |
| 711 | (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width || | 717 | (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width || |
| 712 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | 718 | intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) |
| 713 | args.scaled = 1; | 719 | args.scaled = 1; |
| 714 | 720 | ||
| 715 | intel_sdvo_write_cmd(intel_encoder, | 721 | return intel_sdvo_set_value(intel_sdvo, |
| 716 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 722 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
| 717 | &args, sizeof(args)); | 723 | &args, sizeof(args)); |
| 718 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 719 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 720 | return false; | ||
| 721 | |||
| 722 | return true; | ||
| 723 | } | 724 | } |
| 724 | 725 | ||
| 725 | static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder, | 726 | static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo, |
| 726 | struct intel_sdvo_dtd *dtd) | 727 | struct intel_sdvo_dtd *dtd) |
| 727 | { | 728 | { |
| 728 | bool status; | 729 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, |
| 729 | 730 | &dtd->part1, sizeof(dtd->part1)) && | |
| 730 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, | 731 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, |
| 731 | NULL, 0); | 732 | &dtd->part2, sizeof(dtd->part2)); |
| 732 | |||
| 733 | status = intel_sdvo_read_response(intel_encoder, &dtd->part1, | ||
| 734 | sizeof(dtd->part1)); | ||
| 735 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 736 | return false; | ||
| 737 | |||
| 738 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, | ||
| 739 | NULL, 0); | ||
| 740 | |||
| 741 | status = intel_sdvo_read_response(intel_encoder, &dtd->part2, | ||
| 742 | sizeof(dtd->part2)); | ||
| 743 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 744 | return false; | ||
| 745 | |||
| 746 | return false; | ||
| 747 | } | 733 | } |
| 748 | 734 | ||
| 749 | static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) | 735 | static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val) |
| 750 | { | 736 | { |
| 751 | u8 status; | 737 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); |
| 752 | |||
| 753 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); | ||
| 754 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 755 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 756 | return false; | ||
| 757 | |||
| 758 | return true; | ||
| 759 | } | 738 | } |
| 760 | 739 | ||
| 761 | static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | 740 | static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, |
| 762 | struct drm_display_mode *mode) | 741 | const struct drm_display_mode *mode) |
| 763 | { | 742 | { |
| 764 | uint16_t width, height; | 743 | uint16_t width, height; |
| 765 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; | 744 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; |
| @@ -808,7 +787,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
| 808 | } | 787 | } |
| 809 | 788 | ||
| 810 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | 789 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, |
| 811 | struct intel_sdvo_dtd *dtd) | 790 | const struct intel_sdvo_dtd *dtd) |
| 812 | { | 791 | { |
| 813 | mode->hdisplay = dtd->part1.h_active; | 792 | mode->hdisplay = dtd->part1.h_active; |
| 814 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; | 793 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; |
| @@ -840,45 +819,33 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | |||
| 840 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | 819 | mode->flags |= DRM_MODE_FLAG_PVSYNC; |
| 841 | } | 820 | } |
| 842 | 821 | ||
| 843 | static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder, | 822 | static bool intel_sdvo_get_supp_encode(struct intel_sdvo *intel_sdvo, |
| 844 | struct intel_sdvo_encode *encode) | 823 | struct intel_sdvo_encode *encode) |
| 845 | { | 824 | { |
| 846 | uint8_t status; | 825 | if (intel_sdvo_get_value(intel_sdvo, |
| 847 | 826 | SDVO_CMD_GET_SUPP_ENCODE, | |
| 848 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); | 827 | encode, sizeof(*encode))) |
| 849 | status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode)); | 828 | return true; |
| 850 | if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ | ||
| 851 | memset(encode, 0, sizeof(*encode)); | ||
| 852 | return false; | ||
| 853 | } | ||
| 854 | 829 | ||
| 855 | return true; | 830 | /* non-support means DVI */ |
| 831 | memset(encode, 0, sizeof(*encode)); | ||
| 832 | return false; | ||
| 856 | } | 833 | } |
| 857 | 834 | ||
| 858 | static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder, | 835 | static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo, |
| 859 | uint8_t mode) | 836 | uint8_t mode) |
| 860 | { | 837 | { |
| 861 | uint8_t status; | 838 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1); |
| 862 | |||
| 863 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1); | ||
| 864 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 865 | |||
| 866 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
| 867 | } | 839 | } |
| 868 | 840 | ||
| 869 | static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder, | 841 | static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo, |
| 870 | uint8_t mode) | 842 | uint8_t mode) |
| 871 | { | 843 | { |
| 872 | uint8_t status; | 844 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1); |
| 873 | |||
| 874 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1); | ||
| 875 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 876 | |||
| 877 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
| 878 | } | 845 | } |
| 879 | 846 | ||
| 880 | #if 0 | 847 | #if 0 |
| 881 | static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | 848 | static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) |
| 882 | { | 849 | { |
| 883 | int i, j; | 850 | int i, j; |
| 884 | uint8_t set_buf_index[2]; | 851 | uint8_t set_buf_index[2]; |
| @@ -887,8 +854,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | |||
| 887 | uint8_t buf[48]; | 854 | uint8_t buf[48]; |
| 888 | uint8_t *pos; | 855 | uint8_t *pos; |
| 889 | 856 | ||
| 890 | intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); | 857 | intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1); |
| 891 | intel_sdvo_read_response(encoder, &av_split, 1); | ||
| 892 | 858 | ||
| 893 | for (i = 0; i <= av_split; i++) { | 859 | for (i = 0; i <= av_split; i++) { |
| 894 | set_buf_index[0] = i; set_buf_index[1] = 0; | 860 | set_buf_index[0] = i; set_buf_index[1] = 0; |
| @@ -908,7 +874,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | |||
| 908 | } | 874 | } |
| 909 | #endif | 875 | #endif |
| 910 | 876 | ||
| 911 | static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, | 877 | static bool intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo, |
| 912 | int index, | 878 | int index, |
| 913 | uint8_t *data, int8_t size, uint8_t tx_rate) | 879 | uint8_t *data, int8_t size, uint8_t tx_rate) |
| 914 | { | 880 | { |
| @@ -917,15 +883,18 @@ static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, | |||
| 917 | set_buf_index[0] = index; | 883 | set_buf_index[0] = index; |
| 918 | set_buf_index[1] = 0; | 884 | set_buf_index[1] = 0; |
| 919 | 885 | ||
| 920 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX, | 886 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX, |
| 921 | set_buf_index, 2); | 887 | set_buf_index, 2)) |
| 888 | return false; | ||
| 922 | 889 | ||
| 923 | for (; size > 0; size -= 8) { | 890 | for (; size > 0; size -= 8) { |
| 924 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8); | 891 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, data, 8)) |
| 892 | return false; | ||
| 893 | |||
| 925 | data += 8; | 894 | data += 8; |
| 926 | } | 895 | } |
| 927 | 896 | ||
| 928 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); | 897 | return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); |
| 929 | } | 898 | } |
| 930 | 899 | ||
| 931 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) | 900 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) |
| @@ -1000,7 +969,7 @@ struct dip_infoframe { | |||
| 1000 | } __attribute__ ((packed)) u; | 969 | } __attribute__ ((packed)) u; |
| 1001 | } __attribute__((packed)); | 970 | } __attribute__((packed)); |
| 1002 | 971 | ||
| 1003 | static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, | 972 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, |
| 1004 | struct drm_display_mode * mode) | 973 | struct drm_display_mode * mode) |
| 1005 | { | 974 | { |
| 1006 | struct dip_infoframe avi_if = { | 975 | struct dip_infoframe avi_if = { |
| @@ -1011,133 +980,107 @@ static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, | |||
| 1011 | 980 | ||
| 1012 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, | 981 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, |
| 1013 | 4 + avi_if.len); | 982 | 4 + avi_if.len); |
| 1014 | intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if, | 983 | return intel_sdvo_set_hdmi_buf(intel_sdvo, 1, (uint8_t *)&avi_if, |
| 1015 | 4 + avi_if.len, | 984 | 4 + avi_if.len, |
| 1016 | SDVO_HBUF_TX_VSYNC); | 985 | SDVO_HBUF_TX_VSYNC); |
| 1017 | } | 986 | } |
| 1018 | 987 | ||
| 1019 | static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder) | 988 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
| 1020 | { | 989 | { |
| 1021 | |||
| 1022 | struct intel_sdvo_tv_format format; | 990 | struct intel_sdvo_tv_format format; |
| 1023 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 991 | uint32_t format_map; |
| 1024 | uint32_t format_map, i; | ||
| 1025 | uint8_t status; | ||
| 1026 | 992 | ||
| 1027 | for (i = 0; i < TV_FORMAT_NUM; i++) | 993 | format_map = 1 << intel_sdvo->tv_format_index; |
| 1028 | if (tv_format_names[i] == sdvo_priv->tv_format_name) | ||
| 1029 | break; | ||
| 1030 | |||
| 1031 | format_map = 1 << i; | ||
| 1032 | memset(&format, 0, sizeof(format)); | 994 | memset(&format, 0, sizeof(format)); |
| 1033 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? | 995 | memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map))); |
| 1034 | sizeof(format) : sizeof(format_map)); | ||
| 1035 | |||
| 1036 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format, | ||
| 1037 | sizeof(format)); | ||
| 1038 | 996 | ||
| 1039 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 997 | BUILD_BUG_ON(sizeof(format) != 6); |
| 1040 | if (status != SDVO_CMD_STATUS_SUCCESS) | 998 | return intel_sdvo_set_value(intel_sdvo, |
| 1041 | DRM_DEBUG_KMS("%s: Failed to set TV format\n", | 999 | SDVO_CMD_SET_TV_FORMAT, |
| 1042 | SDVO_NAME(sdvo_priv)); | 1000 | &format, sizeof(format)); |
| 1043 | } | 1001 | } |
| 1044 | 1002 | ||
| 1045 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | 1003 | static bool |
| 1046 | struct drm_display_mode *mode, | 1004 | intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, |
| 1047 | struct drm_display_mode *adjusted_mode) | 1005 | struct drm_display_mode *mode) |
| 1048 | { | 1006 | { |
| 1049 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1007 | struct intel_sdvo_dtd output_dtd; |
| 1050 | struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv; | ||
| 1051 | 1008 | ||
| 1052 | if (dev_priv->is_tv) { | 1009 | if (!intel_sdvo_set_target_output(intel_sdvo, |
| 1053 | struct intel_sdvo_dtd output_dtd; | 1010 | intel_sdvo->attached_output)) |
| 1054 | bool success; | 1011 | return false; |
| 1055 | 1012 | ||
| 1056 | /* We need to construct preferred input timings based on our | 1013 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
| 1057 | * output timings. To do that, we have to set the output | 1014 | if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) |
| 1058 | * timings, even though this isn't really the right place in | 1015 | return false; |
| 1059 | * the sequence to do it. Oh well. | ||
| 1060 | */ | ||
| 1061 | 1016 | ||
| 1017 | return true; | ||
| 1018 | } | ||
| 1062 | 1019 | ||
| 1063 | /* Set output timings */ | 1020 | static bool |
| 1064 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1021 | intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, |
| 1065 | intel_sdvo_set_target_output(intel_encoder, | 1022 | struct drm_display_mode *mode, |
| 1066 | dev_priv->attached_output); | 1023 | struct drm_display_mode *adjusted_mode) |
| 1067 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | 1024 | { |
| 1025 | struct intel_sdvo_dtd input_dtd; | ||
| 1068 | 1026 | ||
| 1069 | /* Set the input timing to the screen. Assume always input 0. */ | 1027 | /* Reset the input timing to the screen. Assume always input 0. */ |
| 1070 | intel_sdvo_set_target_input(intel_encoder, true, false); | 1028 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 1029 | return false; | ||
| 1071 | 1030 | ||
| 1031 | if (!intel_sdvo_create_preferred_input_timing(intel_sdvo, | ||
| 1032 | mode->clock / 10, | ||
| 1033 | mode->hdisplay, | ||
| 1034 | mode->vdisplay)) | ||
| 1035 | return false; | ||
| 1072 | 1036 | ||
| 1073 | success = intel_sdvo_create_preferred_input_timing(intel_encoder, | 1037 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, |
| 1074 | mode->clock / 10, | 1038 | &input_dtd)) |
| 1075 | mode->hdisplay, | 1039 | return false; |
| 1076 | mode->vdisplay); | ||
| 1077 | if (success) { | ||
| 1078 | struct intel_sdvo_dtd input_dtd; | ||
| 1079 | 1040 | ||
| 1080 | intel_sdvo_get_preferred_input_timing(intel_encoder, | 1041 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
| 1081 | &input_dtd); | 1042 | intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags; |
| 1082 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
| 1083 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
| 1084 | 1043 | ||
| 1085 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1044 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
| 1045 | mode->clock = adjusted_mode->clock; | ||
| 1046 | return true; | ||
| 1047 | } | ||
| 1086 | 1048 | ||
| 1087 | mode->clock = adjusted_mode->clock; | 1049 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
| 1050 | struct drm_display_mode *mode, | ||
| 1051 | struct drm_display_mode *adjusted_mode) | ||
| 1052 | { | ||
| 1053 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
| 1088 | 1054 | ||
| 1089 | adjusted_mode->clock *= | 1055 | /* We need to construct preferred input timings based on our |
| 1090 | intel_sdvo_get_pixel_multiplier(mode); | 1056 | * output timings. To do that, we have to set the output |
| 1091 | } else { | 1057 | * timings, even though this isn't really the right place in |
| 1058 | * the sequence to do it. Oh well. | ||
| 1059 | */ | ||
| 1060 | if (intel_sdvo->is_tv) { | ||
| 1061 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) | ||
| 1092 | return false; | 1062 | return false; |
| 1093 | } | ||
| 1094 | } else if (dev_priv->is_lvds) { | ||
| 1095 | struct intel_sdvo_dtd output_dtd; | ||
| 1096 | bool success; | ||
| 1097 | |||
| 1098 | drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0); | ||
| 1099 | /* Set output timings */ | ||
| 1100 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
| 1101 | dev_priv->sdvo_lvds_fixed_mode); | ||
| 1102 | |||
| 1103 | intel_sdvo_set_target_output(intel_encoder, | ||
| 1104 | dev_priv->attached_output); | ||
| 1105 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | ||
| 1106 | |||
| 1107 | /* Set the input timing to the screen. Assume always input 0. */ | ||
| 1108 | intel_sdvo_set_target_input(intel_encoder, true, false); | ||
| 1109 | |||
| 1110 | |||
| 1111 | success = intel_sdvo_create_preferred_input_timing( | ||
| 1112 | intel_encoder, | ||
| 1113 | mode->clock / 10, | ||
| 1114 | mode->hdisplay, | ||
| 1115 | mode->vdisplay); | ||
| 1116 | |||
| 1117 | if (success) { | ||
| 1118 | struct intel_sdvo_dtd input_dtd; | ||
| 1119 | 1063 | ||
| 1120 | intel_sdvo_get_preferred_input_timing(intel_encoder, | 1064 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
| 1121 | &input_dtd); | 1065 | mode, |
| 1122 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 1066 | adjusted_mode); |
| 1123 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | 1067 | } else if (intel_sdvo->is_lvds) { |
| 1068 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); | ||
| 1124 | 1069 | ||
| 1125 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1070 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
| 1126 | 1071 | intel_sdvo->sdvo_lvds_fixed_mode)) | |
| 1127 | mode->clock = adjusted_mode->clock; | ||
| 1128 | |||
| 1129 | adjusted_mode->clock *= | ||
| 1130 | intel_sdvo_get_pixel_multiplier(mode); | ||
| 1131 | } else { | ||
| 1132 | return false; | 1072 | return false; |
| 1133 | } | ||
| 1134 | 1073 | ||
| 1135 | } else { | 1074 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
| 1136 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1075 | mode, |
| 1137 | * SDVO device will be told of the multiplier during mode_set. | 1076 | adjusted_mode); |
| 1138 | */ | ||
| 1139 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
| 1140 | } | 1077 | } |
| 1078 | |||
| 1079 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
| 1080 | * SDVO device will be told of the multiplier during mode_set. | ||
| 1081 | */ | ||
| 1082 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
| 1083 | |||
| 1141 | return true; | 1084 | return true; |
| 1142 | } | 1085 | } |
| 1143 | 1086 | ||
| @@ -1149,13 +1092,11 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1149 | struct drm_i915_private *dev_priv = dev->dev_private; | 1092 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1150 | struct drm_crtc *crtc = encoder->crtc; | 1093 | struct drm_crtc *crtc = encoder->crtc; |
| 1151 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1094 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 1152 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1095 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1153 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1154 | u32 sdvox = 0; | 1096 | u32 sdvox = 0; |
| 1155 | int sdvo_pixel_multiply; | 1097 | int sdvo_pixel_multiply, rate; |
| 1156 | struct intel_sdvo_in_out_map in_out; | 1098 | struct intel_sdvo_in_out_map in_out; |
| 1157 | struct intel_sdvo_dtd input_dtd; | 1099 | struct intel_sdvo_dtd input_dtd; |
| 1158 | u8 status; | ||
| 1159 | 1100 | ||
| 1160 | if (!mode) | 1101 | if (!mode) |
| 1161 | return; | 1102 | return; |
| @@ -1166,41 +1107,46 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1166 | * channel on the motherboard. In a two-input device, the first input | 1107 | * channel on the motherboard. In a two-input device, the first input |
| 1167 | * will be SDVOB and the second SDVOC. | 1108 | * will be SDVOB and the second SDVOC. |
| 1168 | */ | 1109 | */ |
| 1169 | in_out.in0 = sdvo_priv->attached_output; | 1110 | in_out.in0 = intel_sdvo->attached_output; |
| 1170 | in_out.in1 = 0; | 1111 | in_out.in1 = 0; |
| 1171 | 1112 | ||
| 1172 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, | 1113 | intel_sdvo_set_value(intel_sdvo, |
| 1114 | SDVO_CMD_SET_IN_OUT_MAP, | ||
| 1173 | &in_out, sizeof(in_out)); | 1115 | &in_out, sizeof(in_out)); |
| 1174 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 1175 | 1116 | ||
| 1176 | if (sdvo_priv->is_hdmi) { | 1117 | if (intel_sdvo->is_hdmi) { |
| 1177 | intel_sdvo_set_avi_infoframe(intel_encoder, mode); | 1118 | if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) |
| 1119 | return; | ||
| 1120 | |||
| 1178 | sdvox |= SDVO_AUDIO_ENABLE; | 1121 | sdvox |= SDVO_AUDIO_ENABLE; |
| 1179 | } | 1122 | } |
| 1180 | 1123 | ||
| 1181 | /* We have tried to get input timing in mode_fixup, and filled into | 1124 | /* We have tried to get input timing in mode_fixup, and filled into |
| 1182 | adjusted_mode */ | 1125 | adjusted_mode */ |
| 1183 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 1126 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
| 1184 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1127 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) |
| 1185 | input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags; | 1128 | input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags; |
| 1186 | } else | ||
| 1187 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | ||
| 1188 | 1129 | ||
| 1189 | /* If it's a TV, we already set the output timing in mode_fixup. | 1130 | /* If it's a TV, we already set the output timing in mode_fixup. |
| 1190 | * Otherwise, the output timing is equal to the input timing. | 1131 | * Otherwise, the output timing is equal to the input timing. |
| 1191 | */ | 1132 | */ |
| 1192 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { | 1133 | if (!intel_sdvo->is_tv && !intel_sdvo->is_lvds) { |
| 1193 | /* Set the output timing to the screen */ | 1134 | /* Set the output timing to the screen */ |
| 1194 | intel_sdvo_set_target_output(intel_encoder, | 1135 | if (!intel_sdvo_set_target_output(intel_sdvo, |
| 1195 | sdvo_priv->attached_output); | 1136 | intel_sdvo->attached_output)) |
| 1196 | intel_sdvo_set_output_timing(intel_encoder, &input_dtd); | 1137 | return; |
| 1138 | |||
| 1139 | (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); | ||
| 1197 | } | 1140 | } |
| 1198 | 1141 | ||
| 1199 | /* Set the input timing to the screen. Assume always input 0. */ | 1142 | /* Set the input timing to the screen. Assume always input 0. */ |
| 1200 | intel_sdvo_set_target_input(intel_encoder, true, false); | 1143 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 1144 | return; | ||
| 1201 | 1145 | ||
| 1202 | if (sdvo_priv->is_tv) | 1146 | if (intel_sdvo->is_tv) { |
| 1203 | intel_sdvo_set_tv_format(intel_encoder); | 1147 | if (!intel_sdvo_set_tv_format(intel_sdvo)) |
| 1148 | return; | ||
| 1149 | } | ||
| 1204 | 1150 | ||
| 1205 | /* We would like to use intel_sdvo_create_preferred_input_timing() to | 1151 | /* We would like to use intel_sdvo_create_preferred_input_timing() to |
| 1206 | * provide the device with a timing it can support, if it supports that | 1152 | * provide the device with a timing it can support, if it supports that |
| @@ -1217,23 +1163,17 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1217 | intel_sdvo_set_input_timing(encoder, &input_dtd); | 1163 | intel_sdvo_set_input_timing(encoder, &input_dtd); |
| 1218 | } | 1164 | } |
| 1219 | #else | 1165 | #else |
| 1220 | intel_sdvo_set_input_timing(intel_encoder, &input_dtd); | 1166 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); |
| 1221 | #endif | 1167 | #endif |
| 1222 | 1168 | ||
| 1223 | switch (intel_sdvo_get_pixel_multiplier(mode)) { | 1169 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); |
| 1224 | case 1: | 1170 | switch (sdvo_pixel_multiply) { |
| 1225 | intel_sdvo_set_clock_rate_mult(intel_encoder, | 1171 | case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; |
| 1226 | SDVO_CLOCK_RATE_MULT_1X); | 1172 | case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; |
| 1227 | break; | 1173 | case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; |
| 1228 | case 2: | ||
| 1229 | intel_sdvo_set_clock_rate_mult(intel_encoder, | ||
| 1230 | SDVO_CLOCK_RATE_MULT_2X); | ||
| 1231 | break; | ||
| 1232 | case 4: | ||
| 1233 | intel_sdvo_set_clock_rate_mult(intel_encoder, | ||
| 1234 | SDVO_CLOCK_RATE_MULT_4X); | ||
| 1235 | break; | ||
| 1236 | } | 1174 | } |
| 1175 | if (!intel_sdvo_set_clock_rate_mult(intel_sdvo, rate)) | ||
| 1176 | return; | ||
| 1237 | 1177 | ||
| 1238 | /* Set the SDVO control regs. */ | 1178 | /* Set the SDVO control regs. */ |
| 1239 | if (IS_I965G(dev)) { | 1179 | if (IS_I965G(dev)) { |
| @@ -1243,8 +1183,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1243 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 1183 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
| 1244 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | 1184 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; |
| 1245 | } else { | 1185 | } else { |
| 1246 | sdvox |= I915_READ(sdvo_priv->sdvo_reg); | 1186 | sdvox |= I915_READ(intel_sdvo->sdvo_reg); |
| 1247 | switch (sdvo_priv->sdvo_reg) { | 1187 | switch (intel_sdvo->sdvo_reg) { |
| 1248 | case SDVOB: | 1188 | case SDVOB: |
| 1249 | sdvox &= SDVOB_PRESERVE_MASK; | 1189 | sdvox &= SDVOB_PRESERVE_MASK; |
| 1250 | break; | 1190 | break; |
| @@ -1257,7 +1197,6 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1257 | if (intel_crtc->pipe == 1) | 1197 | if (intel_crtc->pipe == 1) |
| 1258 | sdvox |= SDVO_PIPE_B_SELECT; | 1198 | sdvox |= SDVO_PIPE_B_SELECT; |
| 1259 | 1199 | ||
| 1260 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); | ||
| 1261 | if (IS_I965G(dev)) { | 1200 | if (IS_I965G(dev)) { |
| 1262 | /* done in crtc_mode_set as the dpll_md reg must be written early */ | 1201 | /* done in crtc_mode_set as the dpll_md reg must be written early */ |
| 1263 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { | 1202 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { |
| @@ -1266,28 +1205,28 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1266 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1205 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
| 1267 | } | 1206 | } |
| 1268 | 1207 | ||
| 1269 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | 1208 | if (intel_sdvo->sdvo_flags & SDVO_NEED_TO_STALL) |
| 1270 | sdvox |= SDVO_STALL_SELECT; | 1209 | sdvox |= SDVO_STALL_SELECT; |
| 1271 | intel_sdvo_write_sdvox(intel_encoder, sdvox); | 1210 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); |
| 1272 | } | 1211 | } |
| 1273 | 1212 | ||
| 1274 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | 1213 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) |
| 1275 | { | 1214 | { |
| 1276 | struct drm_device *dev = encoder->dev; | 1215 | struct drm_device *dev = encoder->dev; |
| 1277 | struct drm_i915_private *dev_priv = dev->dev_private; | 1216 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1278 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1217 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1279 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1218 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
| 1280 | u32 temp; | 1219 | u32 temp; |
| 1281 | 1220 | ||
| 1282 | if (mode != DRM_MODE_DPMS_ON) { | 1221 | if (mode != DRM_MODE_DPMS_ON) { |
| 1283 | intel_sdvo_set_active_outputs(intel_encoder, 0); | 1222 | intel_sdvo_set_active_outputs(intel_sdvo, 0); |
| 1284 | if (0) | 1223 | if (0) |
| 1285 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); | 1224 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
| 1286 | 1225 | ||
| 1287 | if (mode == DRM_MODE_DPMS_OFF) { | 1226 | if (mode == DRM_MODE_DPMS_OFF) { |
| 1288 | temp = I915_READ(sdvo_priv->sdvo_reg); | 1227 | temp = I915_READ(intel_sdvo->sdvo_reg); |
| 1289 | if ((temp & SDVO_ENABLE) != 0) { | 1228 | if ((temp & SDVO_ENABLE) != 0) { |
| 1290 | intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE); | 1229 | intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE); |
| 1291 | } | 1230 | } |
| 1292 | } | 1231 | } |
| 1293 | } else { | 1232 | } else { |
| @@ -1295,28 +1234,25 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
| 1295 | int i; | 1234 | int i; |
| 1296 | u8 status; | 1235 | u8 status; |
| 1297 | 1236 | ||
| 1298 | temp = I915_READ(sdvo_priv->sdvo_reg); | 1237 | temp = I915_READ(intel_sdvo->sdvo_reg); |
| 1299 | if ((temp & SDVO_ENABLE) == 0) | 1238 | if ((temp & SDVO_ENABLE) == 0) |
| 1300 | intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE); | 1239 | intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE); |
| 1301 | for (i = 0; i < 2; i++) | 1240 | for (i = 0; i < 2; i++) |
| 1302 | intel_wait_for_vblank(dev); | 1241 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1303 | |||
| 1304 | status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, | ||
| 1305 | &input2); | ||
| 1306 | |||
| 1307 | 1242 | ||
| 1243 | status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); | ||
| 1308 | /* Warn if the device reported failure to sync. | 1244 | /* Warn if the device reported failure to sync. |
| 1309 | * A lot of SDVO devices fail to notify of sync, but it's | 1245 | * A lot of SDVO devices fail to notify of sync, but it's |
| 1310 | * a given it the status is a success, we succeeded. | 1246 | * a given it the status is a success, we succeeded. |
| 1311 | */ | 1247 | */ |
| 1312 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { | 1248 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { |
| 1313 | DRM_DEBUG_KMS("First %s output reported failure to " | 1249 | DRM_DEBUG_KMS("First %s output reported failure to " |
| 1314 | "sync\n", SDVO_NAME(sdvo_priv)); | 1250 | "sync\n", SDVO_NAME(intel_sdvo)); |
| 1315 | } | 1251 | } |
| 1316 | 1252 | ||
| 1317 | if (0) | 1253 | if (0) |
| 1318 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); | 1254 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
| 1319 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->attached_output); | 1255 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); |
| 1320 | } | 1256 | } |
| 1321 | return; | 1257 | return; |
| 1322 | } | 1258 | } |
| @@ -1325,42 +1261,31 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
| 1325 | struct drm_display_mode *mode) | 1261 | struct drm_display_mode *mode) |
| 1326 | { | 1262 | { |
| 1327 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1263 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1328 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1264 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1329 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1330 | 1265 | ||
| 1331 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 1266 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
| 1332 | return MODE_NO_DBLESCAN; | 1267 | return MODE_NO_DBLESCAN; |
| 1333 | 1268 | ||
| 1334 | if (sdvo_priv->pixel_clock_min > mode->clock) | 1269 | if (intel_sdvo->pixel_clock_min > mode->clock) |
| 1335 | return MODE_CLOCK_LOW; | 1270 | return MODE_CLOCK_LOW; |
| 1336 | 1271 | ||
| 1337 | if (sdvo_priv->pixel_clock_max < mode->clock) | 1272 | if (intel_sdvo->pixel_clock_max < mode->clock) |
| 1338 | return MODE_CLOCK_HIGH; | 1273 | return MODE_CLOCK_HIGH; |
| 1339 | 1274 | ||
| 1340 | if (sdvo_priv->is_lvds == true) { | 1275 | if (intel_sdvo->is_lvds) { |
| 1341 | if (sdvo_priv->sdvo_lvds_fixed_mode == NULL) | 1276 | if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay) |
| 1342 | return MODE_PANEL; | ||
| 1343 | |||
| 1344 | if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay) | ||
| 1345 | return MODE_PANEL; | 1277 | return MODE_PANEL; |
| 1346 | 1278 | ||
| 1347 | if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay) | 1279 | if (mode->vdisplay > intel_sdvo->sdvo_lvds_fixed_mode->vdisplay) |
| 1348 | return MODE_PANEL; | 1280 | return MODE_PANEL; |
| 1349 | } | 1281 | } |
| 1350 | 1282 | ||
| 1351 | return MODE_OK; | 1283 | return MODE_OK; |
| 1352 | } | 1284 | } |
| 1353 | 1285 | ||
| 1354 | static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps) | 1286 | static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps) |
| 1355 | { | 1287 | { |
| 1356 | u8 status; | 1288 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DEVICE_CAPS, caps, sizeof(*caps)); |
| 1357 | |||
| 1358 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); | ||
| 1359 | status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps)); | ||
| 1360 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 1361 | return false; | ||
| 1362 | |||
| 1363 | return true; | ||
| 1364 | } | 1289 | } |
| 1365 | 1290 | ||
| 1366 | /* No use! */ | 1291 | /* No use! */ |
| @@ -1368,12 +1293,12 @@ static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, str | |||
| 1368 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) | 1293 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) |
| 1369 | { | 1294 | { |
| 1370 | struct drm_connector *connector = NULL; | 1295 | struct drm_connector *connector = NULL; |
| 1371 | struct intel_encoder *iout = NULL; | 1296 | struct intel_sdvo *iout = NULL; |
| 1372 | struct intel_sdvo_priv *sdvo; | 1297 | struct intel_sdvo *sdvo; |
| 1373 | 1298 | ||
| 1374 | /* find the sdvo connector */ | 1299 | /* find the sdvo connector */ |
| 1375 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1300 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 1376 | iout = to_intel_encoder(connector); | 1301 | iout = to_intel_sdvo(connector); |
| 1377 | 1302 | ||
| 1378 | if (iout->type != INTEL_OUTPUT_SDVO) | 1303 | if (iout->type != INTEL_OUTPUT_SDVO) |
| 1379 | continue; | 1304 | continue; |
| @@ -1395,75 +1320,69 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) | |||
| 1395 | { | 1320 | { |
| 1396 | u8 response[2]; | 1321 | u8 response[2]; |
| 1397 | u8 status; | 1322 | u8 status; |
| 1398 | struct intel_encoder *intel_encoder; | 1323 | struct intel_sdvo *intel_sdvo; |
| 1399 | DRM_DEBUG_KMS("\n"); | 1324 | DRM_DEBUG_KMS("\n"); |
| 1400 | 1325 | ||
| 1401 | if (!connector) | 1326 | if (!connector) |
| 1402 | return 0; | 1327 | return 0; |
| 1403 | 1328 | ||
| 1404 | intel_encoder = to_intel_encoder(connector); | 1329 | intel_sdvo = to_intel_sdvo(connector); |
| 1405 | |||
| 1406 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | ||
| 1407 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | ||
| 1408 | 1330 | ||
| 1409 | if (response[0] !=0) | 1331 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, |
| 1410 | return 1; | 1332 | &response, 2) && response[0]; |
| 1411 | |||
| 1412 | return 0; | ||
| 1413 | } | 1333 | } |
| 1414 | 1334 | ||
| 1415 | void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | 1335 | void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) |
| 1416 | { | 1336 | { |
| 1417 | u8 response[2]; | 1337 | u8 response[2]; |
| 1418 | u8 status; | 1338 | u8 status; |
| 1419 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1339 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(connector); |
| 1420 | 1340 | ||
| 1421 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1341 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
| 1422 | intel_sdvo_read_response(intel_encoder, &response, 2); | 1342 | intel_sdvo_read_response(intel_sdvo, &response, 2); |
| 1423 | 1343 | ||
| 1424 | if (on) { | 1344 | if (on) { |
| 1425 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | 1345 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); |
| 1426 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | 1346 | status = intel_sdvo_read_response(intel_sdvo, &response, 2); |
| 1427 | 1347 | ||
| 1428 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); | 1348 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
| 1429 | } else { | 1349 | } else { |
| 1430 | response[0] = 0; | 1350 | response[0] = 0; |
| 1431 | response[1] = 0; | 1351 | response[1] = 0; |
| 1432 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); | 1352 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
| 1433 | } | 1353 | } |
| 1434 | 1354 | ||
| 1435 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1355 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
| 1436 | intel_sdvo_read_response(intel_encoder, &response, 2); | 1356 | intel_sdvo_read_response(intel_sdvo, &response, 2); |
| 1437 | } | 1357 | } |
| 1438 | #endif | 1358 | #endif |
| 1439 | 1359 | ||
| 1440 | static bool | 1360 | static bool |
| 1441 | intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) | 1361 | intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo) |
| 1442 | { | 1362 | { |
| 1443 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1444 | int caps = 0; | 1363 | int caps = 0; |
| 1445 | 1364 | ||
| 1446 | if (sdvo_priv->caps.output_flags & | 1365 | if (intel_sdvo->caps.output_flags & |
| 1447 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1366 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) |
| 1448 | caps++; | 1367 | caps++; |
| 1449 | if (sdvo_priv->caps.output_flags & | 1368 | if (intel_sdvo->caps.output_flags & |
| 1450 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) | 1369 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) |
| 1451 | caps++; | 1370 | caps++; |
| 1452 | if (sdvo_priv->caps.output_flags & | 1371 | if (intel_sdvo->caps.output_flags & |
| 1453 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) | 1372 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) |
| 1454 | caps++; | 1373 | caps++; |
| 1455 | if (sdvo_priv->caps.output_flags & | 1374 | if (intel_sdvo->caps.output_flags & |
| 1456 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) | 1375 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) |
| 1457 | caps++; | 1376 | caps++; |
| 1458 | if (sdvo_priv->caps.output_flags & | 1377 | if (intel_sdvo->caps.output_flags & |
| 1459 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) | 1378 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) |
| 1460 | caps++; | 1379 | caps++; |
| 1461 | 1380 | ||
| 1462 | if (sdvo_priv->caps.output_flags & | 1381 | if (intel_sdvo->caps.output_flags & |
| 1463 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) | 1382 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) |
| 1464 | caps++; | 1383 | caps++; |
| 1465 | 1384 | ||
| 1466 | if (sdvo_priv->caps.output_flags & | 1385 | if (intel_sdvo->caps.output_flags & |
| 1467 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) | 1386 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) |
| 1468 | caps++; | 1387 | caps++; |
| 1469 | 1388 | ||
| @@ -1475,11 +1394,11 @@ intel_find_analog_connector(struct drm_device *dev) | |||
| 1475 | { | 1394 | { |
| 1476 | struct drm_connector *connector; | 1395 | struct drm_connector *connector; |
| 1477 | struct drm_encoder *encoder; | 1396 | struct drm_encoder *encoder; |
| 1478 | struct intel_encoder *intel_encoder; | 1397 | struct intel_sdvo *intel_sdvo; |
| 1479 | 1398 | ||
| 1480 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1399 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 1481 | intel_encoder = enc_to_intel_encoder(encoder); | 1400 | intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1482 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { | 1401 | if (intel_sdvo->base.type == INTEL_OUTPUT_ANALOG) { |
| 1483 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1402 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 1484 | if (encoder == intel_attached_encoder(connector)) | 1403 | if (encoder == intel_attached_encoder(connector)) |
| 1485 | return connector; | 1404 | return connector; |
| @@ -1493,12 +1412,12 @@ static int | |||
| 1493 | intel_analog_is_connected(struct drm_device *dev) | 1412 | intel_analog_is_connected(struct drm_device *dev) |
| 1494 | { | 1413 | { |
| 1495 | struct drm_connector *analog_connector; | 1414 | struct drm_connector *analog_connector; |
| 1496 | analog_connector = intel_find_analog_connector(dev); | ||
| 1497 | 1415 | ||
| 1416 | analog_connector = intel_find_analog_connector(dev); | ||
| 1498 | if (!analog_connector) | 1417 | if (!analog_connector) |
| 1499 | return false; | 1418 | return false; |
| 1500 | 1419 | ||
| 1501 | if (analog_connector->funcs->detect(analog_connector) == | 1420 | if (analog_connector->funcs->detect(analog_connector, false) == |
| 1502 | connector_status_disconnected) | 1421 | connector_status_disconnected) |
| 1503 | return false; | 1422 | return false; |
| 1504 | 1423 | ||
| @@ -1509,54 +1428,52 @@ enum drm_connector_status | |||
| 1509 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | 1428 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) |
| 1510 | { | 1429 | { |
| 1511 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1430 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1512 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1431 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1513 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1432 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1514 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
| 1515 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 1516 | enum drm_connector_status status = connector_status_connected; | 1433 | enum drm_connector_status status = connector_status_connected; |
| 1517 | struct edid *edid = NULL; | 1434 | struct edid *edid = NULL; |
| 1518 | 1435 | ||
| 1519 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); | 1436 | edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); |
| 1520 | 1437 | ||
| 1521 | /* This is only applied to SDVO cards with multiple outputs */ | 1438 | /* This is only applied to SDVO cards with multiple outputs */ |
| 1522 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { | 1439 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) { |
| 1523 | uint8_t saved_ddc, temp_ddc; | 1440 | uint8_t saved_ddc, temp_ddc; |
| 1524 | saved_ddc = sdvo_priv->ddc_bus; | 1441 | saved_ddc = intel_sdvo->ddc_bus; |
| 1525 | temp_ddc = sdvo_priv->ddc_bus >> 1; | 1442 | temp_ddc = intel_sdvo->ddc_bus >> 1; |
| 1526 | /* | 1443 | /* |
| 1527 | * Don't use the 1 as the argument of DDC bus switch to get | 1444 | * Don't use the 1 as the argument of DDC bus switch to get |
| 1528 | * the EDID. It is used for SDVO SPD ROM. | 1445 | * the EDID. It is used for SDVO SPD ROM. |
| 1529 | */ | 1446 | */ |
| 1530 | while(temp_ddc > 1) { | 1447 | while(temp_ddc > 1) { |
| 1531 | sdvo_priv->ddc_bus = temp_ddc; | 1448 | intel_sdvo->ddc_bus = temp_ddc; |
| 1532 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); | 1449 | edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); |
| 1533 | if (edid) { | 1450 | if (edid) { |
| 1534 | /* | 1451 | /* |
| 1535 | * When we can get the EDID, maybe it is the | 1452 | * When we can get the EDID, maybe it is the |
| 1536 | * correct DDC bus. Update it. | 1453 | * correct DDC bus. Update it. |
| 1537 | */ | 1454 | */ |
| 1538 | sdvo_priv->ddc_bus = temp_ddc; | 1455 | intel_sdvo->ddc_bus = temp_ddc; |
| 1539 | break; | 1456 | break; |
| 1540 | } | 1457 | } |
| 1541 | temp_ddc >>= 1; | 1458 | temp_ddc >>= 1; |
| 1542 | } | 1459 | } |
| 1543 | if (edid == NULL) | 1460 | if (edid == NULL) |
| 1544 | sdvo_priv->ddc_bus = saved_ddc; | 1461 | intel_sdvo->ddc_bus = saved_ddc; |
| 1545 | } | 1462 | } |
| 1546 | /* when there is no edid and no monitor is connected with VGA | 1463 | /* when there is no edid and no monitor is connected with VGA |
| 1547 | * port, try to use the CRT ddc to read the EDID for DVI-connector | 1464 | * port, try to use the CRT ddc to read the EDID for DVI-connector |
| 1548 | */ | 1465 | */ |
| 1549 | if (edid == NULL && sdvo_priv->analog_ddc_bus && | 1466 | if (edid == NULL && intel_sdvo->analog_ddc_bus && |
| 1550 | !intel_analog_is_connected(connector->dev)) | 1467 | !intel_analog_is_connected(connector->dev)) |
| 1551 | edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus); | 1468 | edid = drm_get_edid(connector, intel_sdvo->analog_ddc_bus); |
| 1552 | 1469 | ||
| 1553 | if (edid != NULL) { | 1470 | if (edid != NULL) { |
| 1554 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); | 1471 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); |
| 1555 | bool need_digital = !!(sdvo_connector->output_flag & SDVO_TMDS_MASK); | 1472 | bool need_digital = !!(intel_sdvo_connector->output_flag & SDVO_TMDS_MASK); |
| 1556 | 1473 | ||
| 1557 | /* DDC bus is shared, match EDID to connector type */ | 1474 | /* DDC bus is shared, match EDID to connector type */ |
| 1558 | if (is_digital && need_digital) | 1475 | if (is_digital && need_digital) |
| 1559 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1476 | intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid); |
| 1560 | else if (is_digital != need_digital) | 1477 | else if (is_digital != need_digital) |
| 1561 | status = connector_status_disconnected; | 1478 | status = connector_status_disconnected; |
| 1562 | 1479 | ||
| @@ -1569,36 +1486,33 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
| 1569 | return status; | 1486 | return status; |
| 1570 | } | 1487 | } |
| 1571 | 1488 | ||
| 1572 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1489 | static enum drm_connector_status |
| 1490 | intel_sdvo_detect(struct drm_connector *connector, bool force) | ||
| 1573 | { | 1491 | { |
| 1574 | uint16_t response; | 1492 | uint16_t response; |
| 1575 | u8 status; | ||
| 1576 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1493 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1577 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1494 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1578 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1495 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1579 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1580 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 1581 | enum drm_connector_status ret; | 1496 | enum drm_connector_status ret; |
| 1582 | 1497 | ||
| 1583 | intel_sdvo_write_cmd(intel_encoder, | 1498 | if (!intel_sdvo_write_cmd(intel_sdvo, |
| 1584 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1499 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) |
| 1585 | if (sdvo_priv->is_tv) { | 1500 | return connector_status_unknown; |
| 1501 | if (intel_sdvo->is_tv) { | ||
| 1586 | /* add 30ms delay when the output type is SDVO-TV */ | 1502 | /* add 30ms delay when the output type is SDVO-TV */ |
| 1587 | mdelay(30); | 1503 | mdelay(30); |
| 1588 | } | 1504 | } |
| 1589 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | 1505 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
| 1506 | return connector_status_unknown; | ||
| 1590 | 1507 | ||
| 1591 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); | 1508 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); |
| 1592 | 1509 | ||
| 1593 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 1594 | return connector_status_unknown; | ||
| 1595 | |||
| 1596 | if (response == 0) | 1510 | if (response == 0) |
| 1597 | return connector_status_disconnected; | 1511 | return connector_status_disconnected; |
| 1598 | 1512 | ||
| 1599 | sdvo_priv->attached_output = response; | 1513 | intel_sdvo->attached_output = response; |
| 1600 | 1514 | ||
| 1601 | if ((sdvo_connector->output_flag & response) == 0) | 1515 | if ((intel_sdvo_connector->output_flag & response) == 0) |
| 1602 | ret = connector_status_disconnected; | 1516 | ret = connector_status_disconnected; |
| 1603 | else if (response & SDVO_TMDS_MASK) | 1517 | else if (response & SDVO_TMDS_MASK) |
| 1604 | ret = intel_sdvo_hdmi_sink_detect(connector); | 1518 | ret = intel_sdvo_hdmi_sink_detect(connector); |
| @@ -1607,16 +1521,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
| 1607 | 1521 | ||
| 1608 | /* May update encoder flag for like clock for SDVO TV, etc.*/ | 1522 | /* May update encoder flag for like clock for SDVO TV, etc.*/ |
| 1609 | if (ret == connector_status_connected) { | 1523 | if (ret == connector_status_connected) { |
| 1610 | sdvo_priv->is_tv = false; | 1524 | intel_sdvo->is_tv = false; |
| 1611 | sdvo_priv->is_lvds = false; | 1525 | intel_sdvo->is_lvds = false; |
| 1612 | intel_encoder->needs_tv_clock = false; | 1526 | intel_sdvo->base.needs_tv_clock = false; |
| 1613 | 1527 | ||
| 1614 | if (response & SDVO_TV_MASK) { | 1528 | if (response & SDVO_TV_MASK) { |
| 1615 | sdvo_priv->is_tv = true; | 1529 | intel_sdvo->is_tv = true; |
| 1616 | intel_encoder->needs_tv_clock = true; | 1530 | intel_sdvo->base.needs_tv_clock = true; |
| 1617 | } | 1531 | } |
| 1618 | if (response & SDVO_LVDS_MASK) | 1532 | if (response & SDVO_LVDS_MASK) |
| 1619 | sdvo_priv->is_lvds = true; | 1533 | intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL; |
| 1620 | } | 1534 | } |
| 1621 | 1535 | ||
| 1622 | return ret; | 1536 | return ret; |
| @@ -1625,12 +1539,11 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
| 1625 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1539 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
| 1626 | { | 1540 | { |
| 1627 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1541 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1628 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1542 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1629 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1630 | int num_modes; | 1543 | int num_modes; |
| 1631 | 1544 | ||
| 1632 | /* set the bus switch and get the modes */ | 1545 | /* set the bus switch and get the modes */ |
| 1633 | num_modes = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1546 | num_modes = intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); |
| 1634 | 1547 | ||
| 1635 | /* | 1548 | /* |
| 1636 | * Mac mini hack. On this device, the DVI-I connector shares one DDC | 1549 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
| @@ -1639,11 +1552,11 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
| 1639 | * which case we'll look there for the digital DDC data. | 1552 | * which case we'll look there for the digital DDC data. |
| 1640 | */ | 1553 | */ |
| 1641 | if (num_modes == 0 && | 1554 | if (num_modes == 0 && |
| 1642 | sdvo_priv->analog_ddc_bus && | 1555 | intel_sdvo->analog_ddc_bus && |
| 1643 | !intel_analog_is_connected(connector->dev)) { | 1556 | !intel_analog_is_connected(connector->dev)) { |
| 1644 | /* Switch to the analog ddc bus and try that | 1557 | /* Switch to the analog ddc bus and try that |
| 1645 | */ | 1558 | */ |
| 1646 | (void) intel_ddc_get_modes(connector, sdvo_priv->analog_ddc_bus); | 1559 | (void) intel_ddc_get_modes(connector, intel_sdvo->analog_ddc_bus); |
| 1647 | } | 1560 | } |
| 1648 | } | 1561 | } |
| 1649 | 1562 | ||
| @@ -1715,52 +1628,43 @@ struct drm_display_mode sdvo_tv_modes[] = { | |||
| 1715 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | 1628 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) |
| 1716 | { | 1629 | { |
| 1717 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1630 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1718 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1631 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1719 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1720 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1632 | struct intel_sdvo_sdtv_resolution_request tv_res; |
| 1721 | uint32_t reply = 0, format_map = 0; | 1633 | uint32_t reply = 0, format_map = 0; |
| 1722 | int i; | 1634 | int i; |
| 1723 | uint8_t status; | ||
| 1724 | |||
| 1725 | 1635 | ||
| 1726 | /* Read the list of supported input resolutions for the selected TV | 1636 | /* Read the list of supported input resolutions for the selected TV |
| 1727 | * format. | 1637 | * format. |
| 1728 | */ | 1638 | */ |
| 1729 | for (i = 0; i < TV_FORMAT_NUM; i++) | 1639 | format_map = 1 << intel_sdvo->tv_format_index; |
| 1730 | if (tv_format_names[i] == sdvo_priv->tv_format_name) | ||
| 1731 | break; | ||
| 1732 | |||
| 1733 | format_map = (1 << i); | ||
| 1734 | memcpy(&tv_res, &format_map, | 1640 | memcpy(&tv_res, &format_map, |
| 1735 | sizeof(struct intel_sdvo_sdtv_resolution_request) > | 1641 | min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request))); |
| 1736 | sizeof(format_map) ? sizeof(format_map) : | ||
| 1737 | sizeof(struct intel_sdvo_sdtv_resolution_request)); | ||
| 1738 | 1642 | ||
| 1739 | intel_sdvo_set_target_output(intel_encoder, sdvo_priv->attached_output); | 1643 | if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output)) |
| 1644 | return; | ||
| 1740 | 1645 | ||
| 1741 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | 1646 | BUILD_BUG_ON(sizeof(tv_res) != 3); |
| 1742 | &tv_res, sizeof(tv_res)); | 1647 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, |
| 1743 | status = intel_sdvo_read_response(intel_encoder, &reply, 3); | 1648 | &tv_res, sizeof(tv_res))) |
| 1744 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1649 | return; |
| 1650 | if (!intel_sdvo_read_response(intel_sdvo, &reply, 3)) | ||
| 1745 | return; | 1651 | return; |
| 1746 | 1652 | ||
| 1747 | for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) | 1653 | for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) |
| 1748 | if (reply & (1 << i)) { | 1654 | if (reply & (1 << i)) { |
| 1749 | struct drm_display_mode *nmode; | 1655 | struct drm_display_mode *nmode; |
| 1750 | nmode = drm_mode_duplicate(connector->dev, | 1656 | nmode = drm_mode_duplicate(connector->dev, |
| 1751 | &sdvo_tv_modes[i]); | 1657 | &sdvo_tv_modes[i]); |
| 1752 | if (nmode) | 1658 | if (nmode) |
| 1753 | drm_mode_probed_add(connector, nmode); | 1659 | drm_mode_probed_add(connector, nmode); |
| 1754 | } | 1660 | } |
| 1755 | |||
| 1756 | } | 1661 | } |
| 1757 | 1662 | ||
| 1758 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1663 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
| 1759 | { | 1664 | { |
| 1760 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1665 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1761 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1666 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1762 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1667 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
| 1763 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1764 | struct drm_display_mode *newmode; | 1668 | struct drm_display_mode *newmode; |
| 1765 | 1669 | ||
| 1766 | /* | 1670 | /* |
| @@ -1768,7 +1672,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
| 1768 | * Assume that the preferred modes are | 1672 | * Assume that the preferred modes are |
| 1769 | * arranged in priority order. | 1673 | * arranged in priority order. |
| 1770 | */ | 1674 | */ |
| 1771 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1675 | intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); |
| 1772 | if (list_empty(&connector->probed_modes) == false) | 1676 | if (list_empty(&connector->probed_modes) == false) |
| 1773 | goto end; | 1677 | goto end; |
| 1774 | 1678 | ||
| @@ -1787,8 +1691,9 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
| 1787 | end: | 1691 | end: |
| 1788 | list_for_each_entry(newmode, &connector->probed_modes, head) { | 1692 | list_for_each_entry(newmode, &connector->probed_modes, head) { |
| 1789 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | 1693 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { |
| 1790 | sdvo_priv->sdvo_lvds_fixed_mode = | 1694 | intel_sdvo->sdvo_lvds_fixed_mode = |
| 1791 | drm_mode_duplicate(connector->dev, newmode); | 1695 | drm_mode_duplicate(connector->dev, newmode); |
| 1696 | intel_sdvo->is_lvds = true; | ||
| 1792 | break; | 1697 | break; |
| 1793 | } | 1698 | } |
| 1794 | } | 1699 | } |
| @@ -1797,66 +1702,67 @@ end: | |||
| 1797 | 1702 | ||
| 1798 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1703 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
| 1799 | { | 1704 | { |
| 1800 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1705 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1801 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 1802 | 1706 | ||
| 1803 | if (IS_TV(sdvo_connector)) | 1707 | if (IS_TV(intel_sdvo_connector)) |
| 1804 | intel_sdvo_get_tv_modes(connector); | 1708 | intel_sdvo_get_tv_modes(connector); |
| 1805 | else if (IS_LVDS(sdvo_connector)) | 1709 | else if (IS_LVDS(intel_sdvo_connector)) |
| 1806 | intel_sdvo_get_lvds_modes(connector); | 1710 | intel_sdvo_get_lvds_modes(connector); |
| 1807 | else | 1711 | else |
| 1808 | intel_sdvo_get_ddc_modes(connector); | 1712 | intel_sdvo_get_ddc_modes(connector); |
| 1809 | 1713 | ||
| 1810 | if (list_empty(&connector->probed_modes)) | 1714 | return !list_empty(&connector->probed_modes); |
| 1811 | return 0; | ||
| 1812 | return 1; | ||
| 1813 | } | 1715 | } |
| 1814 | 1716 | ||
| 1815 | static | 1717 | static void |
| 1816 | void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | 1718 | intel_sdvo_destroy_enhance_property(struct drm_connector *connector) |
| 1817 | { | 1719 | { |
| 1818 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1720 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1819 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; | ||
| 1820 | struct drm_device *dev = connector->dev; | 1721 | struct drm_device *dev = connector->dev; |
| 1821 | 1722 | ||
| 1822 | if (IS_TV(sdvo_priv)) { | 1723 | if (intel_sdvo_connector->left) |
| 1823 | if (sdvo_priv->left_property) | 1724 | drm_property_destroy(dev, intel_sdvo_connector->left); |
| 1824 | drm_property_destroy(dev, sdvo_priv->left_property); | 1725 | if (intel_sdvo_connector->right) |
| 1825 | if (sdvo_priv->right_property) | 1726 | drm_property_destroy(dev, intel_sdvo_connector->right); |
| 1826 | drm_property_destroy(dev, sdvo_priv->right_property); | 1727 | if (intel_sdvo_connector->top) |
| 1827 | if (sdvo_priv->top_property) | 1728 | drm_property_destroy(dev, intel_sdvo_connector->top); |
| 1828 | drm_property_destroy(dev, sdvo_priv->top_property); | 1729 | if (intel_sdvo_connector->bottom) |
| 1829 | if (sdvo_priv->bottom_property) | 1730 | drm_property_destroy(dev, intel_sdvo_connector->bottom); |
| 1830 | drm_property_destroy(dev, sdvo_priv->bottom_property); | 1731 | if (intel_sdvo_connector->hpos) |
| 1831 | if (sdvo_priv->hpos_property) | 1732 | drm_property_destroy(dev, intel_sdvo_connector->hpos); |
| 1832 | drm_property_destroy(dev, sdvo_priv->hpos_property); | 1733 | if (intel_sdvo_connector->vpos) |
| 1833 | if (sdvo_priv->vpos_property) | 1734 | drm_property_destroy(dev, intel_sdvo_connector->vpos); |
| 1834 | drm_property_destroy(dev, sdvo_priv->vpos_property); | 1735 | if (intel_sdvo_connector->saturation) |
| 1835 | if (sdvo_priv->saturation_property) | 1736 | drm_property_destroy(dev, intel_sdvo_connector->saturation); |
| 1836 | drm_property_destroy(dev, | 1737 | if (intel_sdvo_connector->contrast) |
| 1837 | sdvo_priv->saturation_property); | 1738 | drm_property_destroy(dev, intel_sdvo_connector->contrast); |
| 1838 | if (sdvo_priv->contrast_property) | 1739 | if (intel_sdvo_connector->hue) |
| 1839 | drm_property_destroy(dev, | 1740 | drm_property_destroy(dev, intel_sdvo_connector->hue); |
| 1840 | sdvo_priv->contrast_property); | 1741 | if (intel_sdvo_connector->sharpness) |
| 1841 | if (sdvo_priv->hue_property) | 1742 | drm_property_destroy(dev, intel_sdvo_connector->sharpness); |
| 1842 | drm_property_destroy(dev, sdvo_priv->hue_property); | 1743 | if (intel_sdvo_connector->flicker_filter) |
| 1843 | } | 1744 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter); |
| 1844 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { | 1745 | if (intel_sdvo_connector->flicker_filter_2d) |
| 1845 | if (sdvo_priv->brightness_property) | 1746 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_2d); |
| 1846 | drm_property_destroy(dev, | 1747 | if (intel_sdvo_connector->flicker_filter_adaptive) |
| 1847 | sdvo_priv->brightness_property); | 1748 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_adaptive); |
| 1848 | } | 1749 | if (intel_sdvo_connector->tv_luma_filter) |
| 1849 | return; | 1750 | drm_property_destroy(dev, intel_sdvo_connector->tv_luma_filter); |
| 1751 | if (intel_sdvo_connector->tv_chroma_filter) | ||
| 1752 | drm_property_destroy(dev, intel_sdvo_connector->tv_chroma_filter); | ||
| 1753 | if (intel_sdvo_connector->dot_crawl) | ||
| 1754 | drm_property_destroy(dev, intel_sdvo_connector->dot_crawl); | ||
| 1755 | if (intel_sdvo_connector->brightness) | ||
| 1756 | drm_property_destroy(dev, intel_sdvo_connector->brightness); | ||
| 1850 | } | 1757 | } |
| 1851 | 1758 | ||
| 1852 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1759 | static void intel_sdvo_destroy(struct drm_connector *connector) |
| 1853 | { | 1760 | { |
| 1854 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1761 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1855 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 1856 | 1762 | ||
| 1857 | if (sdvo_connector->tv_format_property) | 1763 | if (intel_sdvo_connector->tv_format) |
| 1858 | drm_property_destroy(connector->dev, | 1764 | drm_property_destroy(connector->dev, |
| 1859 | sdvo_connector->tv_format_property); | 1765 | intel_sdvo_connector->tv_format); |
| 1860 | 1766 | ||
| 1861 | intel_sdvo_destroy_enhance_property(connector); | 1767 | intel_sdvo_destroy_enhance_property(connector); |
| 1862 | drm_sysfs_connector_remove(connector); | 1768 | drm_sysfs_connector_remove(connector); |
| @@ -1870,132 +1776,118 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
| 1870 | uint64_t val) | 1776 | uint64_t val) |
| 1871 | { | 1777 | { |
| 1872 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1778 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1873 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1779 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1874 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1780 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1875 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
| 1876 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 1877 | struct drm_crtc *crtc = encoder->crtc; | ||
| 1878 | int ret = 0; | ||
| 1879 | bool changed = false; | ||
| 1880 | uint8_t cmd, status; | ||
| 1881 | uint16_t temp_value; | 1781 | uint16_t temp_value; |
| 1782 | uint8_t cmd; | ||
| 1783 | int ret; | ||
| 1882 | 1784 | ||
| 1883 | ret = drm_connector_property_set_value(connector, property, val); | 1785 | ret = drm_connector_property_set_value(connector, property, val); |
| 1884 | if (ret < 0) | 1786 | if (ret) |
| 1885 | goto out; | 1787 | return ret; |
| 1788 | |||
| 1789 | #define CHECK_PROPERTY(name, NAME) \ | ||
| 1790 | if (intel_sdvo_connector->name == property) { \ | ||
| 1791 | if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ | ||
| 1792 | if (intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \ | ||
| 1793 | cmd = SDVO_CMD_SET_##NAME; \ | ||
| 1794 | intel_sdvo_connector->cur_##name = temp_value; \ | ||
| 1795 | goto set_value; \ | ||
| 1796 | } | ||
| 1886 | 1797 | ||
| 1887 | if (property == sdvo_connector->tv_format_property) { | 1798 | if (property == intel_sdvo_connector->tv_format) { |
| 1888 | if (val >= TV_FORMAT_NUM) { | 1799 | if (val >= TV_FORMAT_NUM) |
| 1889 | ret = -EINVAL; | 1800 | return -EINVAL; |
| 1890 | goto out; | ||
| 1891 | } | ||
| 1892 | if (sdvo_priv->tv_format_name == | ||
| 1893 | sdvo_connector->tv_format_supported[val]) | ||
| 1894 | goto out; | ||
| 1895 | 1801 | ||
| 1896 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[val]; | 1802 | if (intel_sdvo->tv_format_index == |
| 1897 | changed = true; | 1803 | intel_sdvo_connector->tv_format_supported[val]) |
| 1898 | } | 1804 | return 0; |
| 1899 | 1805 | ||
| 1900 | if (IS_TV(sdvo_connector) || IS_LVDS(sdvo_connector)) { | 1806 | intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[val]; |
| 1901 | cmd = 0; | 1807 | goto done; |
| 1808 | } else if (IS_TV_OR_LVDS(intel_sdvo_connector)) { | ||
| 1902 | temp_value = val; | 1809 | temp_value = val; |
| 1903 | if (sdvo_connector->left_property == property) { | 1810 | if (intel_sdvo_connector->left == property) { |
| 1904 | drm_connector_property_set_value(connector, | 1811 | drm_connector_property_set_value(connector, |
| 1905 | sdvo_connector->right_property, val); | 1812 | intel_sdvo_connector->right, val); |
| 1906 | if (sdvo_connector->left_margin == temp_value) | 1813 | if (intel_sdvo_connector->left_margin == temp_value) |
| 1907 | goto out; | 1814 | return 0; |
| 1908 | 1815 | ||
| 1909 | sdvo_connector->left_margin = temp_value; | 1816 | intel_sdvo_connector->left_margin = temp_value; |
| 1910 | sdvo_connector->right_margin = temp_value; | 1817 | intel_sdvo_connector->right_margin = temp_value; |
| 1911 | temp_value = sdvo_connector->max_hscan - | 1818 | temp_value = intel_sdvo_connector->max_hscan - |
| 1912 | sdvo_connector->left_margin; | 1819 | intel_sdvo_connector->left_margin; |
| 1913 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1820 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
| 1914 | } else if (sdvo_connector->right_property == property) { | 1821 | goto set_value; |
| 1822 | } else if (intel_sdvo_connector->right == property) { | ||
| 1915 | drm_connector_property_set_value(connector, | 1823 | drm_connector_property_set_value(connector, |
| 1916 | sdvo_connector->left_property, val); | 1824 | intel_sdvo_connector->left, val); |
| 1917 | if (sdvo_connector->right_margin == temp_value) | 1825 | if (intel_sdvo_connector->right_margin == temp_value) |
| 1918 | goto out; | 1826 | return 0; |
| 1919 | 1827 | ||
| 1920 | sdvo_connector->left_margin = temp_value; | 1828 | intel_sdvo_connector->left_margin = temp_value; |
| 1921 | sdvo_connector->right_margin = temp_value; | 1829 | intel_sdvo_connector->right_margin = temp_value; |
| 1922 | temp_value = sdvo_connector->max_hscan - | 1830 | temp_value = intel_sdvo_connector->max_hscan - |
| 1923 | sdvo_connector->left_margin; | 1831 | intel_sdvo_connector->left_margin; |
| 1924 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1832 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
| 1925 | } else if (sdvo_connector->top_property == property) { | 1833 | goto set_value; |
| 1834 | } else if (intel_sdvo_connector->top == property) { | ||
| 1926 | drm_connector_property_set_value(connector, | 1835 | drm_connector_property_set_value(connector, |
| 1927 | sdvo_connector->bottom_property, val); | 1836 | intel_sdvo_connector->bottom, val); |
| 1928 | if (sdvo_connector->top_margin == temp_value) | 1837 | if (intel_sdvo_connector->top_margin == temp_value) |
| 1929 | goto out; | 1838 | return 0; |
| 1930 | 1839 | ||
| 1931 | sdvo_connector->top_margin = temp_value; | 1840 | intel_sdvo_connector->top_margin = temp_value; |
| 1932 | sdvo_connector->bottom_margin = temp_value; | 1841 | intel_sdvo_connector->bottom_margin = temp_value; |
| 1933 | temp_value = sdvo_connector->max_vscan - | 1842 | temp_value = intel_sdvo_connector->max_vscan - |
| 1934 | sdvo_connector->top_margin; | 1843 | intel_sdvo_connector->top_margin; |
| 1935 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1844 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
| 1936 | } else if (sdvo_connector->bottom_property == property) { | 1845 | goto set_value; |
| 1846 | } else if (intel_sdvo_connector->bottom == property) { | ||
| 1937 | drm_connector_property_set_value(connector, | 1847 | drm_connector_property_set_value(connector, |
| 1938 | sdvo_connector->top_property, val); | 1848 | intel_sdvo_connector->top, val); |
| 1939 | if (sdvo_connector->bottom_margin == temp_value) | 1849 | if (intel_sdvo_connector->bottom_margin == temp_value) |
| 1940 | goto out; | 1850 | return 0; |
| 1941 | sdvo_connector->top_margin = temp_value; | 1851 | |
| 1942 | sdvo_connector->bottom_margin = temp_value; | 1852 | intel_sdvo_connector->top_margin = temp_value; |
| 1943 | temp_value = sdvo_connector->max_vscan - | 1853 | intel_sdvo_connector->bottom_margin = temp_value; |
| 1944 | sdvo_connector->top_margin; | 1854 | temp_value = intel_sdvo_connector->max_vscan - |
| 1855 | intel_sdvo_connector->top_margin; | ||
| 1945 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1856 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
| 1946 | } else if (sdvo_connector->hpos_property == property) { | 1857 | goto set_value; |
| 1947 | if (sdvo_connector->cur_hpos == temp_value) | ||
| 1948 | goto out; | ||
| 1949 | |||
| 1950 | cmd = SDVO_CMD_SET_POSITION_H; | ||
| 1951 | sdvo_connector->cur_hpos = temp_value; | ||
| 1952 | } else if (sdvo_connector->vpos_property == property) { | ||
| 1953 | if (sdvo_connector->cur_vpos == temp_value) | ||
| 1954 | goto out; | ||
| 1955 | |||
| 1956 | cmd = SDVO_CMD_SET_POSITION_V; | ||
| 1957 | sdvo_connector->cur_vpos = temp_value; | ||
| 1958 | } else if (sdvo_connector->saturation_property == property) { | ||
| 1959 | if (sdvo_connector->cur_saturation == temp_value) | ||
| 1960 | goto out; | ||
| 1961 | |||
| 1962 | cmd = SDVO_CMD_SET_SATURATION; | ||
| 1963 | sdvo_connector->cur_saturation = temp_value; | ||
| 1964 | } else if (sdvo_connector->contrast_property == property) { | ||
| 1965 | if (sdvo_connector->cur_contrast == temp_value) | ||
| 1966 | goto out; | ||
| 1967 | |||
| 1968 | cmd = SDVO_CMD_SET_CONTRAST; | ||
| 1969 | sdvo_connector->cur_contrast = temp_value; | ||
| 1970 | } else if (sdvo_connector->hue_property == property) { | ||
| 1971 | if (sdvo_connector->cur_hue == temp_value) | ||
| 1972 | goto out; | ||
| 1973 | |||
| 1974 | cmd = SDVO_CMD_SET_HUE; | ||
| 1975 | sdvo_connector->cur_hue = temp_value; | ||
| 1976 | } else if (sdvo_connector->brightness_property == property) { | ||
| 1977 | if (sdvo_connector->cur_brightness == temp_value) | ||
| 1978 | goto out; | ||
| 1979 | |||
| 1980 | cmd = SDVO_CMD_SET_BRIGHTNESS; | ||
| 1981 | sdvo_connector->cur_brightness = temp_value; | ||
| 1982 | } | ||
| 1983 | if (cmd) { | ||
| 1984 | intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); | ||
| 1985 | status = intel_sdvo_read_response(intel_encoder, | ||
| 1986 | NULL, 0); | ||
| 1987 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 1988 | DRM_DEBUG_KMS("Incorrect SDVO command \n"); | ||
| 1989 | return -EINVAL; | ||
| 1990 | } | ||
| 1991 | changed = true; | ||
| 1992 | } | 1858 | } |
| 1859 | CHECK_PROPERTY(hpos, HPOS) | ||
| 1860 | CHECK_PROPERTY(vpos, VPOS) | ||
| 1861 | CHECK_PROPERTY(saturation, SATURATION) | ||
| 1862 | CHECK_PROPERTY(contrast, CONTRAST) | ||
| 1863 | CHECK_PROPERTY(hue, HUE) | ||
| 1864 | CHECK_PROPERTY(brightness, BRIGHTNESS) | ||
| 1865 | CHECK_PROPERTY(sharpness, SHARPNESS) | ||
| 1866 | CHECK_PROPERTY(flicker_filter, FLICKER_FILTER) | ||
| 1867 | CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D) | ||
| 1868 | CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE) | ||
| 1869 | CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER) | ||
| 1870 | CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER) | ||
| 1871 | CHECK_PROPERTY(dot_crawl, DOT_CRAWL) | ||
| 1993 | } | 1872 | } |
| 1994 | if (changed && crtc) | 1873 | |
| 1874 | return -EINVAL; /* unknown property */ | ||
| 1875 | |||
| 1876 | set_value: | ||
| 1877 | if (!intel_sdvo_set_value(intel_sdvo, cmd, &temp_value, 2)) | ||
| 1878 | return -EIO; | ||
| 1879 | |||
| 1880 | |||
| 1881 | done: | ||
| 1882 | if (encoder->crtc) { | ||
| 1883 | struct drm_crtc *crtc = encoder->crtc; | ||
| 1884 | |||
| 1995 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | 1885 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, |
| 1996 | crtc->y, crtc->fb); | 1886 | crtc->y, crtc->fb); |
| 1997 | out: | 1887 | } |
| 1998 | return ret; | 1888 | |
| 1889 | return 0; | ||
| 1890 | #undef CHECK_PROPERTY | ||
| 1999 | } | 1891 | } |
| 2000 | 1892 | ||
| 2001 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | 1893 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
| @@ -2022,28 +1914,57 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs | |||
| 2022 | 1914 | ||
| 2023 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) | 1915 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) |
| 2024 | { | 1916 | { |
| 2025 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1917 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 2026 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2027 | 1918 | ||
| 2028 | if (intel_encoder->i2c_bus) | 1919 | if (intel_sdvo->analog_ddc_bus) |
| 2029 | intel_i2c_destroy(intel_encoder->i2c_bus); | 1920 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); |
| 2030 | if (intel_encoder->ddc_bus) | ||
| 2031 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
| 2032 | if (sdvo_priv->analog_ddc_bus) | ||
| 2033 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
| 2034 | 1921 | ||
| 2035 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | 1922 | if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) |
| 2036 | drm_mode_destroy(encoder->dev, | 1923 | drm_mode_destroy(encoder->dev, |
| 2037 | sdvo_priv->sdvo_lvds_fixed_mode); | 1924 | intel_sdvo->sdvo_lvds_fixed_mode); |
| 2038 | 1925 | ||
| 2039 | drm_encoder_cleanup(encoder); | 1926 | intel_encoder_destroy(encoder); |
| 2040 | kfree(intel_encoder); | ||
| 2041 | } | 1927 | } |
| 2042 | 1928 | ||
| 2043 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | 1929 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { |
| 2044 | .destroy = intel_sdvo_enc_destroy, | 1930 | .destroy = intel_sdvo_enc_destroy, |
| 2045 | }; | 1931 | }; |
| 2046 | 1932 | ||
| 1933 | static void | ||
| 1934 | intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo) | ||
| 1935 | { | ||
| 1936 | uint16_t mask = 0; | ||
| 1937 | unsigned int num_bits; | ||
| 1938 | |||
| 1939 | /* Make a mask of outputs less than or equal to our own priority in the | ||
| 1940 | * list. | ||
| 1941 | */ | ||
| 1942 | switch (sdvo->controlled_output) { | ||
| 1943 | case SDVO_OUTPUT_LVDS1: | ||
| 1944 | mask |= SDVO_OUTPUT_LVDS1; | ||
| 1945 | case SDVO_OUTPUT_LVDS0: | ||
| 1946 | mask |= SDVO_OUTPUT_LVDS0; | ||
| 1947 | case SDVO_OUTPUT_TMDS1: | ||
| 1948 | mask |= SDVO_OUTPUT_TMDS1; | ||
| 1949 | case SDVO_OUTPUT_TMDS0: | ||
| 1950 | mask |= SDVO_OUTPUT_TMDS0; | ||
| 1951 | case SDVO_OUTPUT_RGB1: | ||
| 1952 | mask |= SDVO_OUTPUT_RGB1; | ||
| 1953 | case SDVO_OUTPUT_RGB0: | ||
| 1954 | mask |= SDVO_OUTPUT_RGB0; | ||
| 1955 | break; | ||
| 1956 | } | ||
| 1957 | |||
| 1958 | /* Count bits to find what number we are in the priority list. */ | ||
| 1959 | mask &= sdvo->caps.output_flags; | ||
| 1960 | num_bits = hweight16(mask); | ||
| 1961 | /* If more than 3 outputs, default to DDC bus 3 for now. */ | ||
| 1962 | if (num_bits > 3) | ||
| 1963 | num_bits = 3; | ||
| 1964 | |||
| 1965 | /* Corresponds to SDVO_CONTROL_BUS_DDCx */ | ||
| 1966 | sdvo->ddc_bus = 1 << num_bits; | ||
| 1967 | } | ||
| 2047 | 1968 | ||
| 2048 | /** | 1969 | /** |
| 2049 | * Choose the appropriate DDC bus for control bus switch command for this | 1970 | * Choose the appropriate DDC bus for control bus switch command for this |
| @@ -2054,7 +1975,7 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | |||
| 2054 | */ | 1975 | */ |
| 2055 | static void | 1976 | static void |
| 2056 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | 1977 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, |
| 2057 | struct intel_sdvo_priv *sdvo, u32 reg) | 1978 | struct intel_sdvo *sdvo, u32 reg) |
| 2058 | { | 1979 | { |
| 2059 | struct sdvo_device_mapping *mapping; | 1980 | struct sdvo_device_mapping *mapping; |
| 2060 | 1981 | ||
| @@ -2063,61 +1984,53 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | |||
| 2063 | else | 1984 | else |
| 2064 | mapping = &(dev_priv->sdvo_mappings[1]); | 1985 | mapping = &(dev_priv->sdvo_mappings[1]); |
| 2065 | 1986 | ||
| 2066 | sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); | 1987 | if (mapping->initialized) |
| 1988 | sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); | ||
| 1989 | else | ||
| 1990 | intel_sdvo_guess_ddc_bus(sdvo); | ||
| 2067 | } | 1991 | } |
| 2068 | 1992 | ||
| 2069 | static bool | 1993 | static bool |
| 2070 | intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output, int device) | 1994 | intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device) |
| 2071 | { | 1995 | { |
| 2072 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1996 | return intel_sdvo_set_target_output(intel_sdvo, |
| 2073 | uint8_t status; | 1997 | device == 0 ? SDVO_OUTPUT_TMDS0 : SDVO_OUTPUT_TMDS1) && |
| 2074 | 1998 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE, | |
| 2075 | if (device == 0) | 1999 | &intel_sdvo->is_hdmi, 1); |
| 2076 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS0); | ||
| 2077 | else | ||
| 2078 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS1); | ||
| 2079 | |||
| 2080 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); | ||
| 2081 | status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1); | ||
| 2082 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 2083 | return false; | ||
| 2084 | return true; | ||
| 2085 | } | 2000 | } |
| 2086 | 2001 | ||
| 2087 | static struct intel_encoder * | 2002 | static struct intel_sdvo * |
| 2088 | intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) | 2003 | intel_sdvo_chan_to_intel_sdvo(struct intel_i2c_chan *chan) |
| 2089 | { | 2004 | { |
| 2090 | struct drm_device *dev = chan->drm_dev; | 2005 | struct drm_device *dev = chan->drm_dev; |
| 2091 | struct drm_encoder *encoder; | 2006 | struct drm_encoder *encoder; |
| 2092 | struct intel_encoder *intel_encoder = NULL; | ||
| 2093 | 2007 | ||
| 2094 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 2008 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 2095 | intel_encoder = enc_to_intel_encoder(encoder); | 2009 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 2096 | if (intel_encoder->ddc_bus == &chan->adapter) | 2010 | if (intel_sdvo->base.ddc_bus == &chan->adapter) |
| 2097 | break; | 2011 | return intel_sdvo; |
| 2098 | } | 2012 | } |
| 2099 | return intel_encoder; | 2013 | |
| 2014 | return NULL; | ||
| 2100 | } | 2015 | } |
| 2101 | 2016 | ||
| 2102 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | 2017 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, |
| 2103 | struct i2c_msg msgs[], int num) | 2018 | struct i2c_msg msgs[], int num) |
| 2104 | { | 2019 | { |
| 2105 | struct intel_encoder *intel_encoder; | 2020 | struct intel_sdvo *intel_sdvo; |
| 2106 | struct intel_sdvo_priv *sdvo_priv; | ||
| 2107 | struct i2c_algo_bit_data *algo_data; | 2021 | struct i2c_algo_bit_data *algo_data; |
| 2108 | const struct i2c_algorithm *algo; | 2022 | const struct i2c_algorithm *algo; |
| 2109 | 2023 | ||
| 2110 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | 2024 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; |
| 2111 | intel_encoder = | 2025 | intel_sdvo = |
| 2112 | intel_sdvo_chan_to_intel_encoder( | 2026 | intel_sdvo_chan_to_intel_sdvo((struct intel_i2c_chan *) |
| 2113 | (struct intel_i2c_chan *)(algo_data->data)); | 2027 | (algo_data->data)); |
| 2114 | if (intel_encoder == NULL) | 2028 | if (intel_sdvo == NULL) |
| 2115 | return -EINVAL; | 2029 | return -EINVAL; |
| 2116 | 2030 | ||
| 2117 | sdvo_priv = intel_encoder->dev_priv; | 2031 | algo = intel_sdvo->base.i2c_bus->algo; |
| 2118 | algo = intel_encoder->i2c_bus->algo; | ||
| 2119 | 2032 | ||
| 2120 | intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus); | 2033 | intel_sdvo_set_control_bus_switch(intel_sdvo, intel_sdvo->ddc_bus); |
| 2121 | return algo->master_xfer(i2c_adap, msgs, num); | 2034 | return algo->master_xfer(i2c_adap, msgs, num); |
| 2122 | } | 2035 | } |
| 2123 | 2036 | ||
| @@ -2162,27 +2075,9 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
| 2162 | return 0x72; | 2075 | return 0x72; |
| 2163 | } | 2076 | } |
| 2164 | 2077 | ||
| 2165 | static bool | ||
| 2166 | intel_sdvo_connector_alloc (struct intel_connector **ret) | ||
| 2167 | { | ||
| 2168 | struct intel_connector *intel_connector; | ||
| 2169 | struct intel_sdvo_connector *sdvo_connector; | ||
| 2170 | |||
| 2171 | *ret = kzalloc(sizeof(*intel_connector) + | ||
| 2172 | sizeof(*sdvo_connector), GFP_KERNEL); | ||
| 2173 | if (!*ret) | ||
| 2174 | return false; | ||
| 2175 | |||
| 2176 | intel_connector = *ret; | ||
| 2177 | sdvo_connector = (struct intel_sdvo_connector *)(intel_connector + 1); | ||
| 2178 | intel_connector->dev_priv = sdvo_connector; | ||
| 2179 | |||
| 2180 | return true; | ||
| 2181 | } | ||
| 2182 | |||
| 2183 | static void | 2078 | static void |
| 2184 | intel_sdvo_connector_create (struct drm_encoder *encoder, | 2079 | intel_sdvo_connector_init(struct drm_encoder *encoder, |
| 2185 | struct drm_connector *connector) | 2080 | struct drm_connector *connector) |
| 2186 | { | 2081 | { |
| 2187 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, | 2082 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, |
| 2188 | connector->connector_type); | 2083 | connector->connector_type); |
| @@ -2198,582 +2093,467 @@ intel_sdvo_connector_create (struct drm_encoder *encoder, | |||
| 2198 | } | 2093 | } |
| 2199 | 2094 | ||
| 2200 | static bool | 2095 | static bool |
| 2201 | intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device) | 2096 | intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) |
| 2202 | { | 2097 | { |
| 2203 | struct drm_encoder *encoder = &intel_encoder->enc; | 2098 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
| 2204 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2205 | struct drm_connector *connector; | 2099 | struct drm_connector *connector; |
| 2206 | struct intel_connector *intel_connector; | 2100 | struct intel_connector *intel_connector; |
| 2207 | struct intel_sdvo_connector *sdvo_connector; | 2101 | struct intel_sdvo_connector *intel_sdvo_connector; |
| 2208 | 2102 | ||
| 2209 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2103 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
| 2104 | if (!intel_sdvo_connector) | ||
| 2210 | return false; | 2105 | return false; |
| 2211 | 2106 | ||
| 2212 | sdvo_connector = intel_connector->dev_priv; | ||
| 2213 | |||
| 2214 | if (device == 0) { | 2107 | if (device == 0) { |
| 2215 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS0; | 2108 | intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0; |
| 2216 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; | 2109 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; |
| 2217 | } else if (device == 1) { | 2110 | } else if (device == 1) { |
| 2218 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS1; | 2111 | intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1; |
| 2219 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; | 2112 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; |
| 2220 | } | 2113 | } |
| 2221 | 2114 | ||
| 2115 | intel_connector = &intel_sdvo_connector->base; | ||
| 2222 | connector = &intel_connector->base; | 2116 | connector = &intel_connector->base; |
| 2223 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; | 2117 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; |
| 2224 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | 2118 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; |
| 2225 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | 2119 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; |
| 2226 | 2120 | ||
| 2227 | if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_priv->encode) | 2121 | if (intel_sdvo_get_supp_encode(intel_sdvo, &intel_sdvo->encode) |
| 2228 | && intel_sdvo_get_digital_encoding_mode(intel_encoder, device) | 2122 | && intel_sdvo_get_digital_encoding_mode(intel_sdvo, device) |
| 2229 | && sdvo_priv->is_hdmi) { | 2123 | && intel_sdvo->is_hdmi) { |
| 2230 | /* enable hdmi encoding mode if supported */ | 2124 | /* enable hdmi encoding mode if supported */ |
| 2231 | intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); | 2125 | intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI); |
| 2232 | intel_sdvo_set_colorimetry(intel_encoder, | 2126 | intel_sdvo_set_colorimetry(intel_sdvo, |
| 2233 | SDVO_COLORIMETRY_RGB256); | 2127 | SDVO_COLORIMETRY_RGB256); |
| 2234 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2128 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
| 2235 | } | 2129 | } |
| 2236 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2130 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
| 2237 | (1 << INTEL_ANALOG_CLONE_BIT); | 2131 | (1 << INTEL_ANALOG_CLONE_BIT)); |
| 2238 | 2132 | ||
| 2239 | intel_sdvo_connector_create(encoder, connector); | 2133 | intel_sdvo_connector_init(encoder, connector); |
| 2240 | 2134 | ||
| 2241 | return true; | 2135 | return true; |
| 2242 | } | 2136 | } |
| 2243 | 2137 | ||
| 2244 | static bool | 2138 | static bool |
| 2245 | intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type) | 2139 | intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) |
| 2246 | { | 2140 | { |
| 2247 | struct drm_encoder *encoder = &intel_encoder->enc; | 2141 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
| 2248 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2249 | struct drm_connector *connector; | 2142 | struct drm_connector *connector; |
| 2250 | struct intel_connector *intel_connector; | 2143 | struct intel_connector *intel_connector; |
| 2251 | struct intel_sdvo_connector *sdvo_connector; | 2144 | struct intel_sdvo_connector *intel_sdvo_connector; |
| 2252 | 2145 | ||
| 2253 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2146 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
| 2254 | return false; | 2147 | if (!intel_sdvo_connector) |
| 2148 | return false; | ||
| 2255 | 2149 | ||
| 2150 | intel_connector = &intel_sdvo_connector->base; | ||
| 2256 | connector = &intel_connector->base; | 2151 | connector = &intel_connector->base; |
| 2257 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | 2152 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; |
| 2258 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 2153 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
| 2259 | sdvo_connector = intel_connector->dev_priv; | ||
| 2260 | 2154 | ||
| 2261 | sdvo_priv->controlled_output |= type; | 2155 | intel_sdvo->controlled_output |= type; |
| 2262 | sdvo_connector->output_flag = type; | 2156 | intel_sdvo_connector->output_flag = type; |
| 2263 | 2157 | ||
| 2264 | sdvo_priv->is_tv = true; | 2158 | intel_sdvo->is_tv = true; |
| 2265 | intel_encoder->needs_tv_clock = true; | 2159 | intel_sdvo->base.needs_tv_clock = true; |
| 2266 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | 2160 | intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; |
| 2267 | 2161 | ||
| 2268 | intel_sdvo_connector_create(encoder, connector); | 2162 | intel_sdvo_connector_init(encoder, connector); |
| 2269 | 2163 | ||
| 2270 | intel_sdvo_tv_create_property(connector, type); | 2164 | if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type)) |
| 2165 | goto err; | ||
| 2271 | 2166 | ||
| 2272 | intel_sdvo_create_enhance_property(connector); | 2167 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
| 2168 | goto err; | ||
| 2273 | 2169 | ||
| 2274 | return true; | 2170 | return true; |
| 2171 | |||
| 2172 | err: | ||
| 2173 | intel_sdvo_destroy(connector); | ||
| 2174 | return false; | ||
| 2275 | } | 2175 | } |
| 2276 | 2176 | ||
| 2277 | static bool | 2177 | static bool |
| 2278 | intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device) | 2178 | intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) |
| 2279 | { | 2179 | { |
| 2280 | struct drm_encoder *encoder = &intel_encoder->enc; | 2180 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
| 2281 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2282 | struct drm_connector *connector; | 2181 | struct drm_connector *connector; |
| 2283 | struct intel_connector *intel_connector; | 2182 | struct intel_connector *intel_connector; |
| 2284 | struct intel_sdvo_connector *sdvo_connector; | 2183 | struct intel_sdvo_connector *intel_sdvo_connector; |
| 2285 | 2184 | ||
| 2286 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2185 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
| 2287 | return false; | 2186 | if (!intel_sdvo_connector) |
| 2187 | return false; | ||
| 2288 | 2188 | ||
| 2189 | intel_connector = &intel_sdvo_connector->base; | ||
| 2289 | connector = &intel_connector->base; | 2190 | connector = &intel_connector->base; |
| 2290 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 2191 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
| 2291 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | 2192 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
| 2292 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2193 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
| 2293 | sdvo_connector = intel_connector->dev_priv; | ||
| 2294 | 2194 | ||
| 2295 | if (device == 0) { | 2195 | if (device == 0) { |
| 2296 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB0; | 2196 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; |
| 2297 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; | 2197 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; |
| 2298 | } else if (device == 1) { | 2198 | } else if (device == 1) { |
| 2299 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB1; | 2199 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; |
| 2300 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; | 2200 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
| 2301 | } | 2201 | } |
| 2302 | 2202 | ||
| 2303 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2203 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
| 2304 | (1 << INTEL_ANALOG_CLONE_BIT); | 2204 | (1 << INTEL_ANALOG_CLONE_BIT)); |
| 2305 | 2205 | ||
| 2306 | intel_sdvo_connector_create(encoder, connector); | 2206 | intel_sdvo_connector_init(encoder, connector); |
| 2307 | return true; | 2207 | return true; |
| 2308 | } | 2208 | } |
| 2309 | 2209 | ||
| 2310 | static bool | 2210 | static bool |
| 2311 | intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device) | 2211 | intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) |
| 2312 | { | 2212 | { |
| 2313 | struct drm_encoder *encoder = &intel_encoder->enc; | 2213 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
| 2314 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2315 | struct drm_connector *connector; | 2214 | struct drm_connector *connector; |
| 2316 | struct intel_connector *intel_connector; | 2215 | struct intel_connector *intel_connector; |
| 2317 | struct intel_sdvo_connector *sdvo_connector; | 2216 | struct intel_sdvo_connector *intel_sdvo_connector; |
| 2318 | 2217 | ||
| 2319 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2218 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
| 2320 | return false; | 2219 | if (!intel_sdvo_connector) |
| 2220 | return false; | ||
| 2321 | 2221 | ||
| 2322 | connector = &intel_connector->base; | 2222 | intel_connector = &intel_sdvo_connector->base; |
| 2223 | connector = &intel_connector->base; | ||
| 2323 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2224 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
| 2324 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2225 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
| 2325 | sdvo_connector = intel_connector->dev_priv; | ||
| 2326 | |||
| 2327 | sdvo_priv->is_lvds = true; | ||
| 2328 | 2226 | ||
| 2329 | if (device == 0) { | 2227 | if (device == 0) { |
| 2330 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS0; | 2228 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; |
| 2331 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; | 2229 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; |
| 2332 | } else if (device == 1) { | 2230 | } else if (device == 1) { |
| 2333 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS1; | 2231 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; |
| 2334 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; | 2232 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
| 2335 | } | 2233 | } |
| 2336 | 2234 | ||
| 2337 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | 2235 | intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | |
| 2338 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | 2236 | (1 << INTEL_SDVO_LVDS_CLONE_BIT)); |
| 2339 | 2237 | ||
| 2340 | intel_sdvo_connector_create(encoder, connector); | 2238 | intel_sdvo_connector_init(encoder, connector); |
| 2341 | intel_sdvo_create_enhance_property(connector); | 2239 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
| 2342 | return true; | 2240 | goto err; |
| 2241 | |||
| 2242 | return true; | ||
| 2243 | |||
| 2244 | err: | ||
| 2245 | intel_sdvo_destroy(connector); | ||
| 2246 | return false; | ||
| 2343 | } | 2247 | } |
| 2344 | 2248 | ||
| 2345 | static bool | 2249 | static bool |
| 2346 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) | 2250 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) |
| 2347 | { | 2251 | { |
| 2348 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 2252 | intel_sdvo->is_tv = false; |
| 2349 | 2253 | intel_sdvo->base.needs_tv_clock = false; | |
| 2350 | sdvo_priv->is_tv = false; | 2254 | intel_sdvo->is_lvds = false; |
| 2351 | intel_encoder->needs_tv_clock = false; | ||
| 2352 | sdvo_priv->is_lvds = false; | ||
| 2353 | 2255 | ||
| 2354 | /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ | 2256 | /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ |
| 2355 | 2257 | ||
| 2356 | if (flags & SDVO_OUTPUT_TMDS0) | 2258 | if (flags & SDVO_OUTPUT_TMDS0) |
| 2357 | if (!intel_sdvo_dvi_init(intel_encoder, 0)) | 2259 | if (!intel_sdvo_dvi_init(intel_sdvo, 0)) |
| 2358 | return false; | 2260 | return false; |
| 2359 | 2261 | ||
| 2360 | if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) | 2262 | if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) |
| 2361 | if (!intel_sdvo_dvi_init(intel_encoder, 1)) | 2263 | if (!intel_sdvo_dvi_init(intel_sdvo, 1)) |
| 2362 | return false; | 2264 | return false; |
| 2363 | 2265 | ||
| 2364 | /* TV has no XXX1 function block */ | 2266 | /* TV has no XXX1 function block */ |
| 2365 | if (flags & SDVO_OUTPUT_SVID0) | 2267 | if (flags & SDVO_OUTPUT_SVID0) |
| 2366 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_SVID0)) | 2268 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0)) |
| 2367 | return false; | 2269 | return false; |
| 2368 | 2270 | ||
| 2369 | if (flags & SDVO_OUTPUT_CVBS0) | 2271 | if (flags & SDVO_OUTPUT_CVBS0) |
| 2370 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_CVBS0)) | 2272 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0)) |
| 2371 | return false; | 2273 | return false; |
| 2372 | 2274 | ||
| 2373 | if (flags & SDVO_OUTPUT_RGB0) | 2275 | if (flags & SDVO_OUTPUT_RGB0) |
| 2374 | if (!intel_sdvo_analog_init(intel_encoder, 0)) | 2276 | if (!intel_sdvo_analog_init(intel_sdvo, 0)) |
| 2375 | return false; | 2277 | return false; |
| 2376 | 2278 | ||
| 2377 | if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) | 2279 | if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) |
| 2378 | if (!intel_sdvo_analog_init(intel_encoder, 1)) | 2280 | if (!intel_sdvo_analog_init(intel_sdvo, 1)) |
| 2379 | return false; | 2281 | return false; |
| 2380 | 2282 | ||
| 2381 | if (flags & SDVO_OUTPUT_LVDS0) | 2283 | if (flags & SDVO_OUTPUT_LVDS0) |
| 2382 | if (!intel_sdvo_lvds_init(intel_encoder, 0)) | 2284 | if (!intel_sdvo_lvds_init(intel_sdvo, 0)) |
| 2383 | return false; | 2285 | return false; |
| 2384 | 2286 | ||
| 2385 | if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) | 2287 | if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) |
| 2386 | if (!intel_sdvo_lvds_init(intel_encoder, 1)) | 2288 | if (!intel_sdvo_lvds_init(intel_sdvo, 1)) |
| 2387 | return false; | 2289 | return false; |
| 2388 | 2290 | ||
| 2389 | if ((flags & SDVO_OUTPUT_MASK) == 0) { | 2291 | if ((flags & SDVO_OUTPUT_MASK) == 0) { |
| 2390 | unsigned char bytes[2]; | 2292 | unsigned char bytes[2]; |
| 2391 | 2293 | ||
| 2392 | sdvo_priv->controlled_output = 0; | 2294 | intel_sdvo->controlled_output = 0; |
| 2393 | memcpy(bytes, &sdvo_priv->caps.output_flags, 2); | 2295 | memcpy(bytes, &intel_sdvo->caps.output_flags, 2); |
| 2394 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", | 2296 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", |
| 2395 | SDVO_NAME(sdvo_priv), | 2297 | SDVO_NAME(intel_sdvo), |
| 2396 | bytes[0], bytes[1]); | 2298 | bytes[0], bytes[1]); |
| 2397 | return false; | 2299 | return false; |
| 2398 | } | 2300 | } |
| 2399 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 2301 | intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1); |
| 2400 | 2302 | ||
| 2401 | return true; | 2303 | return true; |
| 2402 | } | 2304 | } |
| 2403 | 2305 | ||
| 2404 | static void intel_sdvo_tv_create_property(struct drm_connector *connector, int type) | 2306 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
| 2307 | struct intel_sdvo_connector *intel_sdvo_connector, | ||
| 2308 | int type) | ||
| 2405 | { | 2309 | { |
| 2406 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 2310 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
| 2407 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 2408 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2409 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
| 2410 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 2411 | struct intel_sdvo_tv_format format; | 2311 | struct intel_sdvo_tv_format format; |
| 2412 | uint32_t format_map, i; | 2312 | uint32_t format_map, i; |
| 2413 | uint8_t status; | ||
| 2414 | 2313 | ||
| 2415 | intel_sdvo_set_target_output(intel_encoder, type); | 2314 | if (!intel_sdvo_set_target_output(intel_sdvo, type)) |
| 2315 | return false; | ||
| 2416 | 2316 | ||
| 2417 | intel_sdvo_write_cmd(intel_encoder, | 2317 | if (!intel_sdvo_get_value(intel_sdvo, |
| 2418 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); | 2318 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, |
| 2419 | status = intel_sdvo_read_response(intel_encoder, | 2319 | &format, sizeof(format))) |
| 2420 | &format, sizeof(format)); | 2320 | return false; |
| 2421 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 2422 | return; | ||
| 2423 | 2321 | ||
| 2424 | memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ? | 2322 | memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format))); |
| 2425 | sizeof(format_map) : sizeof(format)); | ||
| 2426 | 2323 | ||
| 2427 | if (format_map == 0) | 2324 | if (format_map == 0) |
| 2428 | return; | 2325 | return false; |
| 2429 | 2326 | ||
| 2430 | sdvo_connector->format_supported_num = 0; | 2327 | intel_sdvo_connector->format_supported_num = 0; |
| 2431 | for (i = 0 ; i < TV_FORMAT_NUM; i++) | 2328 | for (i = 0 ; i < TV_FORMAT_NUM; i++) |
| 2432 | if (format_map & (1 << i)) { | 2329 | if (format_map & (1 << i)) |
| 2433 | sdvo_connector->tv_format_supported | 2330 | intel_sdvo_connector->tv_format_supported[intel_sdvo_connector->format_supported_num++] = i; |
| 2434 | [sdvo_connector->format_supported_num++] = | ||
| 2435 | tv_format_names[i]; | ||
| 2436 | } | ||
| 2437 | 2331 | ||
| 2438 | 2332 | ||
| 2439 | sdvo_connector->tv_format_property = | 2333 | intel_sdvo_connector->tv_format = |
| 2440 | drm_property_create( | 2334 | drm_property_create(dev, DRM_MODE_PROP_ENUM, |
| 2441 | connector->dev, DRM_MODE_PROP_ENUM, | 2335 | "mode", intel_sdvo_connector->format_supported_num); |
| 2442 | "mode", sdvo_connector->format_supported_num); | 2336 | if (!intel_sdvo_connector->tv_format) |
| 2337 | return false; | ||
| 2443 | 2338 | ||
| 2444 | for (i = 0; i < sdvo_connector->format_supported_num; i++) | 2339 | for (i = 0; i < intel_sdvo_connector->format_supported_num; i++) |
| 2445 | drm_property_add_enum( | 2340 | drm_property_add_enum( |
| 2446 | sdvo_connector->tv_format_property, i, | 2341 | intel_sdvo_connector->tv_format, i, |
| 2447 | i, sdvo_connector->tv_format_supported[i]); | 2342 | i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]); |
| 2448 | 2343 | ||
| 2449 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[0]; | 2344 | intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[0]; |
| 2450 | drm_connector_attach_property( | 2345 | drm_connector_attach_property(&intel_sdvo_connector->base.base, |
| 2451 | connector, sdvo_connector->tv_format_property, 0); | 2346 | intel_sdvo_connector->tv_format, 0); |
| 2347 | return true; | ||
| 2452 | 2348 | ||
| 2453 | } | 2349 | } |
| 2454 | 2350 | ||
| 2455 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | 2351 | #define ENHANCEMENT(name, NAME) do { \ |
| 2352 | if (enhancements.name) { \ | ||
| 2353 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \ | ||
| 2354 | !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ | ||
| 2355 | return false; \ | ||
| 2356 | intel_sdvo_connector->max_##name = data_value[0]; \ | ||
| 2357 | intel_sdvo_connector->cur_##name = response; \ | ||
| 2358 | intel_sdvo_connector->name = \ | ||
| 2359 | drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \ | ||
| 2360 | if (!intel_sdvo_connector->name) return false; \ | ||
| 2361 | intel_sdvo_connector->name->values[0] = 0; \ | ||
| 2362 | intel_sdvo_connector->name->values[1] = data_value[0]; \ | ||
| 2363 | drm_connector_attach_property(connector, \ | ||
| 2364 | intel_sdvo_connector->name, \ | ||
| 2365 | intel_sdvo_connector->cur_##name); \ | ||
| 2366 | DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ | ||
| 2367 | data_value[0], data_value[1], response); \ | ||
| 2368 | } \ | ||
| 2369 | } while(0) | ||
| 2370 | |||
| 2371 | static bool | ||
| 2372 | intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, | ||
| 2373 | struct intel_sdvo_connector *intel_sdvo_connector, | ||
| 2374 | struct intel_sdvo_enhancements_reply enhancements) | ||
| 2456 | { | 2375 | { |
| 2457 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 2376 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
| 2458 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 2377 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
| 2459 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
| 2460 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; | ||
| 2461 | struct intel_sdvo_enhancements_reply sdvo_data; | ||
| 2462 | struct drm_device *dev = connector->dev; | ||
| 2463 | uint8_t status; | ||
| 2464 | uint16_t response, data_value[2]; | 2378 | uint16_t response, data_value[2]; |
| 2465 | 2379 | ||
| 2466 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, | 2380 | /* when horizontal overscan is supported, Add the left/right property */ |
| 2467 | NULL, 0); | 2381 | if (enhancements.overscan_h) { |
| 2468 | status = intel_sdvo_read_response(intel_encoder, &sdvo_data, | 2382 | if (!intel_sdvo_get_value(intel_sdvo, |
| 2469 | sizeof(sdvo_data)); | 2383 | SDVO_CMD_GET_MAX_OVERSCAN_H, |
| 2470 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2384 | &data_value, 4)) |
| 2471 | DRM_DEBUG_KMS(" incorrect response is returned\n"); | 2385 | return false; |
| 2472 | return; | 2386 | |
| 2387 | if (!intel_sdvo_get_value(intel_sdvo, | ||
| 2388 | SDVO_CMD_GET_OVERSCAN_H, | ||
| 2389 | &response, 2)) | ||
| 2390 | return false; | ||
| 2391 | |||
| 2392 | intel_sdvo_connector->max_hscan = data_value[0]; | ||
| 2393 | intel_sdvo_connector->left_margin = data_value[0] - response; | ||
| 2394 | intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; | ||
| 2395 | intel_sdvo_connector->left = | ||
| 2396 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2397 | "left_margin", 2); | ||
| 2398 | if (!intel_sdvo_connector->left) | ||
| 2399 | return false; | ||
| 2400 | |||
| 2401 | intel_sdvo_connector->left->values[0] = 0; | ||
| 2402 | intel_sdvo_connector->left->values[1] = data_value[0]; | ||
| 2403 | drm_connector_attach_property(connector, | ||
| 2404 | intel_sdvo_connector->left, | ||
| 2405 | intel_sdvo_connector->left_margin); | ||
| 2406 | |||
| 2407 | intel_sdvo_connector->right = | ||
| 2408 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2409 | "right_margin", 2); | ||
| 2410 | if (!intel_sdvo_connector->right) | ||
| 2411 | return false; | ||
| 2412 | |||
| 2413 | intel_sdvo_connector->right->values[0] = 0; | ||
| 2414 | intel_sdvo_connector->right->values[1] = data_value[0]; | ||
| 2415 | drm_connector_attach_property(connector, | ||
| 2416 | intel_sdvo_connector->right, | ||
| 2417 | intel_sdvo_connector->right_margin); | ||
| 2418 | DRM_DEBUG_KMS("h_overscan: max %d, " | ||
| 2419 | "default %d, current %d\n", | ||
| 2420 | data_value[0], data_value[1], response); | ||
| 2473 | } | 2421 | } |
| 2474 | response = *((uint16_t *)&sdvo_data); | 2422 | |
| 2475 | if (!response) { | 2423 | if (enhancements.overscan_v) { |
| 2476 | DRM_DEBUG_KMS("No enhancement is supported\n"); | 2424 | if (!intel_sdvo_get_value(intel_sdvo, |
| 2477 | return; | 2425 | SDVO_CMD_GET_MAX_OVERSCAN_V, |
| 2426 | &data_value, 4)) | ||
| 2427 | return false; | ||
| 2428 | |||
| 2429 | if (!intel_sdvo_get_value(intel_sdvo, | ||
| 2430 | SDVO_CMD_GET_OVERSCAN_V, | ||
| 2431 | &response, 2)) | ||
| 2432 | return false; | ||
| 2433 | |||
| 2434 | intel_sdvo_connector->max_vscan = data_value[0]; | ||
| 2435 | intel_sdvo_connector->top_margin = data_value[0] - response; | ||
| 2436 | intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; | ||
| 2437 | intel_sdvo_connector->top = | ||
| 2438 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2439 | "top_margin", 2); | ||
| 2440 | if (!intel_sdvo_connector->top) | ||
| 2441 | return false; | ||
| 2442 | |||
| 2443 | intel_sdvo_connector->top->values[0] = 0; | ||
| 2444 | intel_sdvo_connector->top->values[1] = data_value[0]; | ||
| 2445 | drm_connector_attach_property(connector, | ||
| 2446 | intel_sdvo_connector->top, | ||
| 2447 | intel_sdvo_connector->top_margin); | ||
| 2448 | |||
| 2449 | intel_sdvo_connector->bottom = | ||
| 2450 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2451 | "bottom_margin", 2); | ||
| 2452 | if (!intel_sdvo_connector->bottom) | ||
| 2453 | return false; | ||
| 2454 | |||
| 2455 | intel_sdvo_connector->bottom->values[0] = 0; | ||
| 2456 | intel_sdvo_connector->bottom->values[1] = data_value[0]; | ||
| 2457 | drm_connector_attach_property(connector, | ||
| 2458 | intel_sdvo_connector->bottom, | ||
| 2459 | intel_sdvo_connector->bottom_margin); | ||
| 2460 | DRM_DEBUG_KMS("v_overscan: max %d, " | ||
| 2461 | "default %d, current %d\n", | ||
| 2462 | data_value[0], data_value[1], response); | ||
| 2478 | } | 2463 | } |
| 2479 | if (IS_TV(sdvo_priv)) { | 2464 | |
| 2480 | /* when horizontal overscan is supported, Add the left/right | 2465 | ENHANCEMENT(hpos, HPOS); |
| 2481 | * property | 2466 | ENHANCEMENT(vpos, VPOS); |
| 2482 | */ | 2467 | ENHANCEMENT(saturation, SATURATION); |
| 2483 | if (sdvo_data.overscan_h) { | 2468 | ENHANCEMENT(contrast, CONTRAST); |
| 2484 | intel_sdvo_write_cmd(intel_encoder, | 2469 | ENHANCEMENT(hue, HUE); |
| 2485 | SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); | 2470 | ENHANCEMENT(sharpness, SHARPNESS); |
| 2486 | status = intel_sdvo_read_response(intel_encoder, | 2471 | ENHANCEMENT(brightness, BRIGHTNESS); |
| 2487 | &data_value, 4); | 2472 | ENHANCEMENT(flicker_filter, FLICKER_FILTER); |
| 2488 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2473 | ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE); |
| 2489 | DRM_DEBUG_KMS("Incorrect SDVO max " | 2474 | ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D); |
| 2490 | "h_overscan\n"); | 2475 | ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER); |
| 2491 | return; | 2476 | ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER); |
| 2492 | } | 2477 | |
| 2493 | intel_sdvo_write_cmd(intel_encoder, | 2478 | if (enhancements.dot_crawl) { |
| 2494 | SDVO_CMD_GET_OVERSCAN_H, NULL, 0); | 2479 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2)) |
| 2495 | status = intel_sdvo_read_response(intel_encoder, | 2480 | return false; |
| 2496 | &response, 2); | 2481 | |
| 2497 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2482 | intel_sdvo_connector->max_dot_crawl = 1; |
| 2498 | DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); | 2483 | intel_sdvo_connector->cur_dot_crawl = response & 0x1; |
| 2499 | return; | 2484 | intel_sdvo_connector->dot_crawl = |
| 2500 | } | 2485 | drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2); |
| 2501 | sdvo_priv->max_hscan = data_value[0]; | 2486 | if (!intel_sdvo_connector->dot_crawl) |
| 2502 | sdvo_priv->left_margin = data_value[0] - response; | 2487 | return false; |
| 2503 | sdvo_priv->right_margin = sdvo_priv->left_margin; | 2488 | |
| 2504 | sdvo_priv->left_property = | 2489 | intel_sdvo_connector->dot_crawl->values[0] = 0; |
| 2505 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2490 | intel_sdvo_connector->dot_crawl->values[1] = 1; |
| 2506 | "left_margin", 2); | 2491 | drm_connector_attach_property(connector, |
| 2507 | sdvo_priv->left_property->values[0] = 0; | 2492 | intel_sdvo_connector->dot_crawl, |
| 2508 | sdvo_priv->left_property->values[1] = data_value[0]; | 2493 | intel_sdvo_connector->cur_dot_crawl); |
| 2509 | drm_connector_attach_property(connector, | 2494 | DRM_DEBUG_KMS("dot crawl: current %d\n", response); |
| 2510 | sdvo_priv->left_property, | ||
| 2511 | sdvo_priv->left_margin); | ||
| 2512 | sdvo_priv->right_property = | ||
| 2513 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2514 | "right_margin", 2); | ||
| 2515 | sdvo_priv->right_property->values[0] = 0; | ||
| 2516 | sdvo_priv->right_property->values[1] = data_value[0]; | ||
| 2517 | drm_connector_attach_property(connector, | ||
| 2518 | sdvo_priv->right_property, | ||
| 2519 | sdvo_priv->right_margin); | ||
| 2520 | DRM_DEBUG_KMS("h_overscan: max %d, " | ||
| 2521 | "default %d, current %d\n", | ||
| 2522 | data_value[0], data_value[1], response); | ||
| 2523 | } | ||
| 2524 | if (sdvo_data.overscan_v) { | ||
| 2525 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2526 | SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); | ||
| 2527 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2528 | &data_value, 4); | ||
| 2529 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2530 | DRM_DEBUG_KMS("Incorrect SDVO max " | ||
| 2531 | "v_overscan\n"); | ||
| 2532 | return; | ||
| 2533 | } | ||
| 2534 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2535 | SDVO_CMD_GET_OVERSCAN_V, NULL, 0); | ||
| 2536 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2537 | &response, 2); | ||
| 2538 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2539 | DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); | ||
| 2540 | return; | ||
| 2541 | } | ||
| 2542 | sdvo_priv->max_vscan = data_value[0]; | ||
| 2543 | sdvo_priv->top_margin = data_value[0] - response; | ||
| 2544 | sdvo_priv->bottom_margin = sdvo_priv->top_margin; | ||
| 2545 | sdvo_priv->top_property = | ||
| 2546 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2547 | "top_margin", 2); | ||
| 2548 | sdvo_priv->top_property->values[0] = 0; | ||
| 2549 | sdvo_priv->top_property->values[1] = data_value[0]; | ||
| 2550 | drm_connector_attach_property(connector, | ||
| 2551 | sdvo_priv->top_property, | ||
| 2552 | sdvo_priv->top_margin); | ||
| 2553 | sdvo_priv->bottom_property = | ||
| 2554 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2555 | "bottom_margin", 2); | ||
| 2556 | sdvo_priv->bottom_property->values[0] = 0; | ||
| 2557 | sdvo_priv->bottom_property->values[1] = data_value[0]; | ||
| 2558 | drm_connector_attach_property(connector, | ||
| 2559 | sdvo_priv->bottom_property, | ||
| 2560 | sdvo_priv->bottom_margin); | ||
| 2561 | DRM_DEBUG_KMS("v_overscan: max %d, " | ||
| 2562 | "default %d, current %d\n", | ||
| 2563 | data_value[0], data_value[1], response); | ||
| 2564 | } | ||
| 2565 | if (sdvo_data.position_h) { | ||
| 2566 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2567 | SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); | ||
| 2568 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2569 | &data_value, 4); | ||
| 2570 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2571 | DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n"); | ||
| 2572 | return; | ||
| 2573 | } | ||
| 2574 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2575 | SDVO_CMD_GET_POSITION_H, NULL, 0); | ||
| 2576 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2577 | &response, 2); | ||
| 2578 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2579 | DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); | ||
| 2580 | return; | ||
| 2581 | } | ||
| 2582 | sdvo_priv->max_hpos = data_value[0]; | ||
| 2583 | sdvo_priv->cur_hpos = response; | ||
| 2584 | sdvo_priv->hpos_property = | ||
| 2585 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2586 | "hpos", 2); | ||
| 2587 | sdvo_priv->hpos_property->values[0] = 0; | ||
| 2588 | sdvo_priv->hpos_property->values[1] = data_value[0]; | ||
| 2589 | drm_connector_attach_property(connector, | ||
| 2590 | sdvo_priv->hpos_property, | ||
| 2591 | sdvo_priv->cur_hpos); | ||
| 2592 | DRM_DEBUG_KMS("h_position: max %d, " | ||
| 2593 | "default %d, current %d\n", | ||
| 2594 | data_value[0], data_value[1], response); | ||
| 2595 | } | ||
| 2596 | if (sdvo_data.position_v) { | ||
| 2597 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2598 | SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); | ||
| 2599 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2600 | &data_value, 4); | ||
| 2601 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2602 | DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n"); | ||
| 2603 | return; | ||
| 2604 | } | ||
| 2605 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2606 | SDVO_CMD_GET_POSITION_V, NULL, 0); | ||
| 2607 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2608 | &response, 2); | ||
| 2609 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2610 | DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); | ||
| 2611 | return; | ||
| 2612 | } | ||
| 2613 | sdvo_priv->max_vpos = data_value[0]; | ||
| 2614 | sdvo_priv->cur_vpos = response; | ||
| 2615 | sdvo_priv->vpos_property = | ||
| 2616 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2617 | "vpos", 2); | ||
| 2618 | sdvo_priv->vpos_property->values[0] = 0; | ||
| 2619 | sdvo_priv->vpos_property->values[1] = data_value[0]; | ||
| 2620 | drm_connector_attach_property(connector, | ||
| 2621 | sdvo_priv->vpos_property, | ||
| 2622 | sdvo_priv->cur_vpos); | ||
| 2623 | DRM_DEBUG_KMS("v_position: max %d, " | ||
| 2624 | "default %d, current %d\n", | ||
| 2625 | data_value[0], data_value[1], response); | ||
| 2626 | } | ||
| 2627 | if (sdvo_data.saturation) { | ||
| 2628 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2629 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); | ||
| 2630 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2631 | &data_value, 4); | ||
| 2632 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2633 | DRM_DEBUG_KMS("Incorrect SDVO Max sat\n"); | ||
| 2634 | return; | ||
| 2635 | } | ||
| 2636 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2637 | SDVO_CMD_GET_SATURATION, NULL, 0); | ||
| 2638 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2639 | &response, 2); | ||
| 2640 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2641 | DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); | ||
| 2642 | return; | ||
| 2643 | } | ||
| 2644 | sdvo_priv->max_saturation = data_value[0]; | ||
| 2645 | sdvo_priv->cur_saturation = response; | ||
| 2646 | sdvo_priv->saturation_property = | ||
| 2647 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2648 | "saturation", 2); | ||
| 2649 | sdvo_priv->saturation_property->values[0] = 0; | ||
| 2650 | sdvo_priv->saturation_property->values[1] = | ||
| 2651 | data_value[0]; | ||
| 2652 | drm_connector_attach_property(connector, | ||
| 2653 | sdvo_priv->saturation_property, | ||
| 2654 | sdvo_priv->cur_saturation); | ||
| 2655 | DRM_DEBUG_KMS("saturation: max %d, " | ||
| 2656 | "default %d, current %d\n", | ||
| 2657 | data_value[0], data_value[1], response); | ||
| 2658 | } | ||
| 2659 | if (sdvo_data.contrast) { | ||
| 2660 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2661 | SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); | ||
| 2662 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2663 | &data_value, 4); | ||
| 2664 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2665 | DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n"); | ||
| 2666 | return; | ||
| 2667 | } | ||
| 2668 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2669 | SDVO_CMD_GET_CONTRAST, NULL, 0); | ||
| 2670 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2671 | &response, 2); | ||
| 2672 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2673 | DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); | ||
| 2674 | return; | ||
| 2675 | } | ||
| 2676 | sdvo_priv->max_contrast = data_value[0]; | ||
| 2677 | sdvo_priv->cur_contrast = response; | ||
| 2678 | sdvo_priv->contrast_property = | ||
| 2679 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2680 | "contrast", 2); | ||
| 2681 | sdvo_priv->contrast_property->values[0] = 0; | ||
| 2682 | sdvo_priv->contrast_property->values[1] = data_value[0]; | ||
| 2683 | drm_connector_attach_property(connector, | ||
| 2684 | sdvo_priv->contrast_property, | ||
| 2685 | sdvo_priv->cur_contrast); | ||
| 2686 | DRM_DEBUG_KMS("contrast: max %d, " | ||
| 2687 | "default %d, current %d\n", | ||
| 2688 | data_value[0], data_value[1], response); | ||
| 2689 | } | ||
| 2690 | if (sdvo_data.hue) { | ||
| 2691 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2692 | SDVO_CMD_GET_MAX_HUE, NULL, 0); | ||
| 2693 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2694 | &data_value, 4); | ||
| 2695 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2696 | DRM_DEBUG_KMS("Incorrect SDVO Max hue\n"); | ||
| 2697 | return; | ||
| 2698 | } | ||
| 2699 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2700 | SDVO_CMD_GET_HUE, NULL, 0); | ||
| 2701 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2702 | &response, 2); | ||
| 2703 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2704 | DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); | ||
| 2705 | return; | ||
| 2706 | } | ||
| 2707 | sdvo_priv->max_hue = data_value[0]; | ||
| 2708 | sdvo_priv->cur_hue = response; | ||
| 2709 | sdvo_priv->hue_property = | ||
| 2710 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2711 | "hue", 2); | ||
| 2712 | sdvo_priv->hue_property->values[0] = 0; | ||
| 2713 | sdvo_priv->hue_property->values[1] = | ||
| 2714 | data_value[0]; | ||
| 2715 | drm_connector_attach_property(connector, | ||
| 2716 | sdvo_priv->hue_property, | ||
| 2717 | sdvo_priv->cur_hue); | ||
| 2718 | DRM_DEBUG_KMS("hue: max %d, default %d, current %d\n", | ||
| 2719 | data_value[0], data_value[1], response); | ||
| 2720 | } | ||
| 2721 | } | 2495 | } |
| 2722 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { | 2496 | |
| 2723 | if (sdvo_data.brightness) { | 2497 | return true; |
| 2724 | intel_sdvo_write_cmd(intel_encoder, | 2498 | } |
| 2725 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); | 2499 | |
| 2726 | status = intel_sdvo_read_response(intel_encoder, | 2500 | static bool |
| 2727 | &data_value, 4); | 2501 | intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo, |
| 2728 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2502 | struct intel_sdvo_connector *intel_sdvo_connector, |
| 2729 | DRM_DEBUG_KMS("Incorrect SDVO Max bright\n"); | 2503 | struct intel_sdvo_enhancements_reply enhancements) |
| 2730 | return; | 2504 | { |
| 2731 | } | 2505 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
| 2732 | intel_sdvo_write_cmd(intel_encoder, | 2506 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
| 2733 | SDVO_CMD_GET_BRIGHTNESS, NULL, 0); | 2507 | uint16_t response, data_value[2]; |
| 2734 | status = intel_sdvo_read_response(intel_encoder, | 2508 | |
| 2735 | &response, 2); | 2509 | ENHANCEMENT(brightness, BRIGHTNESS); |
| 2736 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2510 | |
| 2737 | DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); | 2511 | return true; |
| 2738 | return; | 2512 | } |
| 2739 | } | 2513 | #undef ENHANCEMENT |
| 2740 | sdvo_priv->max_brightness = data_value[0]; | 2514 | |
| 2741 | sdvo_priv->cur_brightness = response; | 2515 | static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, |
| 2742 | sdvo_priv->brightness_property = | 2516 | struct intel_sdvo_connector *intel_sdvo_connector) |
| 2743 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2517 | { |
| 2744 | "brightness", 2); | 2518 | union { |
| 2745 | sdvo_priv->brightness_property->values[0] = 0; | 2519 | struct intel_sdvo_enhancements_reply reply; |
| 2746 | sdvo_priv->brightness_property->values[1] = | 2520 | uint16_t response; |
| 2747 | data_value[0]; | 2521 | } enhancements; |
| 2748 | drm_connector_attach_property(connector, | 2522 | |
| 2749 | sdvo_priv->brightness_property, | 2523 | enhancements.response = 0; |
| 2750 | sdvo_priv->cur_brightness); | 2524 | intel_sdvo_get_value(intel_sdvo, |
| 2751 | DRM_DEBUG_KMS("brightness: max %d, " | 2525 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, |
| 2752 | "default %d, current %d\n", | 2526 | &enhancements, sizeof(enhancements)); |
| 2753 | data_value[0], data_value[1], response); | 2527 | if (enhancements.response == 0) { |
| 2754 | } | 2528 | DRM_DEBUG_KMS("No enhancement is supported\n"); |
| 2529 | return true; | ||
| 2755 | } | 2530 | } |
| 2756 | return; | 2531 | |
| 2532 | if (IS_TV(intel_sdvo_connector)) | ||
| 2533 | return intel_sdvo_create_enhance_property_tv(intel_sdvo, intel_sdvo_connector, enhancements.reply); | ||
| 2534 | else if(IS_LVDS(intel_sdvo_connector)) | ||
| 2535 | return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply); | ||
| 2536 | else | ||
| 2537 | return true; | ||
| 2538 | |||
| 2757 | } | 2539 | } |
| 2758 | 2540 | ||
| 2759 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | 2541 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) |
| 2760 | { | 2542 | { |
| 2761 | struct drm_i915_private *dev_priv = dev->dev_private; | 2543 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2762 | struct intel_encoder *intel_encoder; | 2544 | struct intel_encoder *intel_encoder; |
| 2763 | struct intel_sdvo_priv *sdvo_priv; | 2545 | struct intel_sdvo *intel_sdvo; |
| 2764 | u8 ch[0x40]; | 2546 | u8 ch[0x40]; |
| 2765 | int i; | 2547 | int i; |
| 2766 | u32 i2c_reg, ddc_reg, analog_ddc_reg; | 2548 | u32 i2c_reg, ddc_reg, analog_ddc_reg; |
| 2767 | 2549 | ||
| 2768 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2550 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
| 2769 | if (!intel_encoder) { | 2551 | if (!intel_sdvo) |
| 2770 | return false; | 2552 | return false; |
| 2771 | } | ||
| 2772 | 2553 | ||
| 2773 | sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1); | 2554 | intel_sdvo->sdvo_reg = sdvo_reg; |
| 2774 | sdvo_priv->sdvo_reg = sdvo_reg; | ||
| 2775 | 2555 | ||
| 2776 | intel_encoder->dev_priv = sdvo_priv; | 2556 | intel_encoder = &intel_sdvo->base; |
| 2777 | intel_encoder->type = INTEL_OUTPUT_SDVO; | 2557 | intel_encoder->type = INTEL_OUTPUT_SDVO; |
| 2778 | 2558 | ||
| 2779 | if (HAS_PCH_SPLIT(dev)) { | 2559 | if (HAS_PCH_SPLIT(dev)) { |
| @@ -2795,14 +2575,14 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
| 2795 | if (!intel_encoder->i2c_bus) | 2575 | if (!intel_encoder->i2c_bus) |
| 2796 | goto err_inteloutput; | 2576 | goto err_inteloutput; |
| 2797 | 2577 | ||
| 2798 | sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); | 2578 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); |
| 2799 | 2579 | ||
| 2800 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ | 2580 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ |
| 2801 | intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; | 2581 | intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; |
| 2802 | 2582 | ||
| 2803 | /* Read the regs to test if we can talk to the device */ | 2583 | /* Read the regs to test if we can talk to the device */ |
| 2804 | for (i = 0; i < 0x40; i++) { | 2584 | for (i = 0; i < 0x40; i++) { |
| 2805 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { | 2585 | if (!intel_sdvo_read_byte(intel_sdvo, i, &ch[i])) { |
| 2806 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", | 2586 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", |
| 2807 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2587 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
| 2808 | goto err_i2c; | 2588 | goto err_i2c; |
| @@ -2812,17 +2592,16 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
| 2812 | /* setup the DDC bus. */ | 2592 | /* setup the DDC bus. */ |
| 2813 | if (IS_SDVOB(sdvo_reg)) { | 2593 | if (IS_SDVOB(sdvo_reg)) { |
| 2814 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); | 2594 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); |
| 2815 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, | 2595 | intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
| 2816 | "SDVOB/VGA DDC BUS"); | 2596 | "SDVOB/VGA DDC BUS"); |
| 2817 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2597 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; |
| 2818 | } else { | 2598 | } else { |
| 2819 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); | 2599 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); |
| 2820 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, | 2600 | intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
| 2821 | "SDVOC/VGA DDC BUS"); | 2601 | "SDVOC/VGA DDC BUS"); |
| 2822 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2602 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
| 2823 | } | 2603 | } |
| 2824 | 2604 | if (intel_encoder->ddc_bus == NULL || intel_sdvo->analog_ddc_bus == NULL) | |
| 2825 | if (intel_encoder->ddc_bus == NULL) | ||
| 2826 | goto err_i2c; | 2605 | goto err_i2c; |
| 2827 | 2606 | ||
| 2828 | /* Wrap with our custom algo which switches to DDC mode */ | 2607 | /* Wrap with our custom algo which switches to DDC mode */ |
| @@ -2833,53 +2612,56 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
| 2833 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); | 2612 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); |
| 2834 | 2613 | ||
| 2835 | /* In default case sdvo lvds is false */ | 2614 | /* In default case sdvo lvds is false */ |
| 2836 | intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); | 2615 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
| 2616 | goto err_enc; | ||
| 2837 | 2617 | ||
| 2838 | if (intel_sdvo_output_setup(intel_encoder, | 2618 | if (intel_sdvo_output_setup(intel_sdvo, |
| 2839 | sdvo_priv->caps.output_flags) != true) { | 2619 | intel_sdvo->caps.output_flags) != true) { |
| 2840 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", | 2620 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
| 2841 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2621 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
| 2842 | goto err_i2c; | 2622 | goto err_enc; |
| 2843 | } | 2623 | } |
| 2844 | 2624 | ||
| 2845 | intel_sdvo_select_ddc_bus(dev_priv, sdvo_priv, sdvo_reg); | 2625 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); |
| 2846 | 2626 | ||
| 2847 | /* Set the input timing to the screen. Assume always input 0. */ | 2627 | /* Set the input timing to the screen. Assume always input 0. */ |
| 2848 | intel_sdvo_set_target_input(intel_encoder, true, false); | 2628 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 2849 | 2629 | goto err_enc; | |
| 2850 | intel_sdvo_get_input_pixel_clock_range(intel_encoder, | ||
| 2851 | &sdvo_priv->pixel_clock_min, | ||
| 2852 | &sdvo_priv->pixel_clock_max); | ||
| 2853 | 2630 | ||
| 2631 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, | ||
| 2632 | &intel_sdvo->pixel_clock_min, | ||
| 2633 | &intel_sdvo->pixel_clock_max)) | ||
| 2634 | goto err_enc; | ||
| 2854 | 2635 | ||
| 2855 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " | 2636 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
| 2856 | "clock range %dMHz - %dMHz, " | 2637 | "clock range %dMHz - %dMHz, " |
| 2857 | "input 1: %c, input 2: %c, " | 2638 | "input 1: %c, input 2: %c, " |
| 2858 | "output 1: %c, output 2: %c\n", | 2639 | "output 1: %c, output 2: %c\n", |
| 2859 | SDVO_NAME(sdvo_priv), | 2640 | SDVO_NAME(intel_sdvo), |
| 2860 | sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id, | 2641 | intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id, |
| 2861 | sdvo_priv->caps.device_rev_id, | 2642 | intel_sdvo->caps.device_rev_id, |
| 2862 | sdvo_priv->pixel_clock_min / 1000, | 2643 | intel_sdvo->pixel_clock_min / 1000, |
| 2863 | sdvo_priv->pixel_clock_max / 1000, | 2644 | intel_sdvo->pixel_clock_max / 1000, |
| 2864 | (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', | 2645 | (intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', |
| 2865 | (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', | 2646 | (intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', |
| 2866 | /* check currently supported outputs */ | 2647 | /* check currently supported outputs */ |
| 2867 | sdvo_priv->caps.output_flags & | 2648 | intel_sdvo->caps.output_flags & |
| 2868 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', | 2649 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', |
| 2869 | sdvo_priv->caps.output_flags & | 2650 | intel_sdvo->caps.output_flags & |
| 2870 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 2651 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
| 2871 | |||
| 2872 | return true; | 2652 | return true; |
| 2873 | 2653 | ||
| 2654 | err_enc: | ||
| 2655 | drm_encoder_cleanup(&intel_encoder->enc); | ||
| 2874 | err_i2c: | 2656 | err_i2c: |
| 2875 | if (sdvo_priv->analog_ddc_bus != NULL) | 2657 | if (intel_sdvo->analog_ddc_bus != NULL) |
| 2876 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | 2658 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); |
| 2877 | if (intel_encoder->ddc_bus != NULL) | 2659 | if (intel_encoder->ddc_bus != NULL) |
| 2878 | intel_i2c_destroy(intel_encoder->ddc_bus); | 2660 | intel_i2c_destroy(intel_encoder->ddc_bus); |
| 2879 | if (intel_encoder->i2c_bus != NULL) | 2661 | if (intel_encoder->i2c_bus != NULL) |
| 2880 | intel_i2c_destroy(intel_encoder->i2c_bus); | 2662 | intel_i2c_destroy(intel_encoder->i2c_bus); |
| 2881 | err_inteloutput: | 2663 | err_inteloutput: |
| 2882 | kfree(intel_encoder); | 2664 | kfree(intel_sdvo); |
| 2883 | 2665 | ||
| 2884 | return false; | 2666 | return false; |
| 2885 | } | 2667 | } |
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index ba5cdf8ae40b..a386b022e538 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
| @@ -312,7 +312,7 @@ struct intel_sdvo_set_target_input_args { | |||
| 312 | # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) | 312 | # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) |
| 313 | 313 | ||
| 314 | #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 | 314 | #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 |
| 315 | /** 5 bytes of bit flags for TV formats shared by all TV format functions */ | 315 | /** 6 bytes of bit flags for TV formats shared by all TV format functions */ |
| 316 | struct intel_sdvo_tv_format { | 316 | struct intel_sdvo_tv_format { |
| 317 | unsigned int ntsc_m:1; | 317 | unsigned int ntsc_m:1; |
| 318 | unsigned int ntsc_j:1; | 318 | unsigned int ntsc_j:1; |
| @@ -596,32 +596,32 @@ struct intel_sdvo_enhancements_reply { | |||
| 596 | unsigned int overscan_h:1; | 596 | unsigned int overscan_h:1; |
| 597 | 597 | ||
| 598 | unsigned int overscan_v:1; | 598 | unsigned int overscan_v:1; |
| 599 | unsigned int position_h:1; | 599 | unsigned int hpos:1; |
| 600 | unsigned int position_v:1; | 600 | unsigned int vpos:1; |
| 601 | unsigned int sharpness:1; | 601 | unsigned int sharpness:1; |
| 602 | unsigned int dot_crawl:1; | 602 | unsigned int dot_crawl:1; |
| 603 | unsigned int dither:1; | 603 | unsigned int dither:1; |
| 604 | unsigned int max_tv_chroma_filter:1; | 604 | unsigned int tv_chroma_filter:1; |
| 605 | unsigned int max_tv_luma_filter:1; | 605 | unsigned int tv_luma_filter:1; |
| 606 | } __attribute__((packed)); | 606 | } __attribute__((packed)); |
| 607 | 607 | ||
| 608 | /* Picture enhancement limits below are dependent on the current TV format, | 608 | /* Picture enhancement limits below are dependent on the current TV format, |
| 609 | * and thus need to be queried and set after it. | 609 | * and thus need to be queried and set after it. |
| 610 | */ | 610 | */ |
| 611 | #define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d | 611 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER 0x4d |
| 612 | #define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b | 612 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE 0x7b |
| 613 | #define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52 | 613 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER_2D 0x52 |
| 614 | #define SDVO_CMD_GET_MAX_SATURATION 0x55 | 614 | #define SDVO_CMD_GET_MAX_SATURATION 0x55 |
| 615 | #define SDVO_CMD_GET_MAX_HUE 0x58 | 615 | #define SDVO_CMD_GET_MAX_HUE 0x58 |
| 616 | #define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b | 616 | #define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b |
| 617 | #define SDVO_CMD_GET_MAX_CONTRAST 0x5e | 617 | #define SDVO_CMD_GET_MAX_CONTRAST 0x5e |
| 618 | #define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 | 618 | #define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 |
| 619 | #define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 | 619 | #define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 |
| 620 | #define SDVO_CMD_GET_MAX_POSITION_H 0x67 | 620 | #define SDVO_CMD_GET_MAX_HPOS 0x67 |
| 621 | #define SDVO_CMD_GET_MAX_POSITION_V 0x6a | 621 | #define SDVO_CMD_GET_MAX_VPOS 0x6a |
| 622 | #define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d | 622 | #define SDVO_CMD_GET_MAX_SHARPNESS 0x6d |
| 623 | #define SDVO_CMD_GET_MAX_TV_CHROMA 0x74 | 623 | #define SDVO_CMD_GET_MAX_TV_CHROMA_FILTER 0x74 |
| 624 | #define SDVO_CMD_GET_MAX_TV_LUMA 0x77 | 624 | #define SDVO_CMD_GET_MAX_TV_LUMA_FILTER 0x77 |
| 625 | struct intel_sdvo_enhancement_limits_reply { | 625 | struct intel_sdvo_enhancement_limits_reply { |
| 626 | u16 max_value; | 626 | u16 max_value; |
| 627 | u16 default_value; | 627 | u16 default_value; |
| @@ -638,10 +638,10 @@ struct intel_sdvo_enhancement_limits_reply { | |||
| 638 | 638 | ||
| 639 | #define SDVO_CMD_GET_FLICKER_FILTER 0x4e | 639 | #define SDVO_CMD_GET_FLICKER_FILTER 0x4e |
| 640 | #define SDVO_CMD_SET_FLICKER_FILTER 0x4f | 640 | #define SDVO_CMD_SET_FLICKER_FILTER 0x4f |
| 641 | #define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50 | 641 | #define SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE 0x50 |
| 642 | #define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51 | 642 | #define SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE 0x51 |
| 643 | #define SDVO_CMD_GET_2D_FLICKER_FITER 0x53 | 643 | #define SDVO_CMD_GET_FLICKER_FILTER_2D 0x53 |
| 644 | #define SDVO_CMD_SET_2D_FLICKER_FITER 0x54 | 644 | #define SDVO_CMD_SET_FLICKER_FILTER_2D 0x54 |
| 645 | #define SDVO_CMD_GET_SATURATION 0x56 | 645 | #define SDVO_CMD_GET_SATURATION 0x56 |
| 646 | #define SDVO_CMD_SET_SATURATION 0x57 | 646 | #define SDVO_CMD_SET_SATURATION 0x57 |
| 647 | #define SDVO_CMD_GET_HUE 0x59 | 647 | #define SDVO_CMD_GET_HUE 0x59 |
| @@ -654,16 +654,16 @@ struct intel_sdvo_enhancement_limits_reply { | |||
| 654 | #define SDVO_CMD_SET_OVERSCAN_H 0x63 | 654 | #define SDVO_CMD_SET_OVERSCAN_H 0x63 |
| 655 | #define SDVO_CMD_GET_OVERSCAN_V 0x65 | 655 | #define SDVO_CMD_GET_OVERSCAN_V 0x65 |
| 656 | #define SDVO_CMD_SET_OVERSCAN_V 0x66 | 656 | #define SDVO_CMD_SET_OVERSCAN_V 0x66 |
| 657 | #define SDVO_CMD_GET_POSITION_H 0x68 | 657 | #define SDVO_CMD_GET_HPOS 0x68 |
| 658 | #define SDVO_CMD_SET_POSITION_H 0x69 | 658 | #define SDVO_CMD_SET_HPOS 0x69 |
| 659 | #define SDVO_CMD_GET_POSITION_V 0x6b | 659 | #define SDVO_CMD_GET_VPOS 0x6b |
| 660 | #define SDVO_CMD_SET_POSITION_V 0x6c | 660 | #define SDVO_CMD_SET_VPOS 0x6c |
| 661 | #define SDVO_CMD_GET_SHARPNESS 0x6e | 661 | #define SDVO_CMD_GET_SHARPNESS 0x6e |
| 662 | #define SDVO_CMD_SET_SHARPNESS 0x6f | 662 | #define SDVO_CMD_SET_SHARPNESS 0x6f |
| 663 | #define SDVO_CMD_GET_TV_CHROMA 0x75 | 663 | #define SDVO_CMD_GET_TV_CHROMA_FILTER 0x75 |
| 664 | #define SDVO_CMD_SET_TV_CHROMA 0x76 | 664 | #define SDVO_CMD_SET_TV_CHROMA_FILTER 0x76 |
| 665 | #define SDVO_CMD_GET_TV_LUMA 0x78 | 665 | #define SDVO_CMD_GET_TV_LUMA_FILTER 0x78 |
| 666 | #define SDVO_CMD_SET_TV_LUMA 0x79 | 666 | #define SDVO_CMD_SET_TV_LUMA_FILTER 0x79 |
| 667 | struct intel_sdvo_enhancements_arg { | 667 | struct intel_sdvo_enhancements_arg { |
| 668 | u16 value; | 668 | u16 value; |
| 669 | }__attribute__((packed)); | 669 | }__attribute__((packed)); |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index cc3726a4a1cb..4a117e318a73 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
| @@ -44,7 +44,9 @@ enum tv_margin { | |||
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | /** Private structure for the integrated TV support */ | 46 | /** Private structure for the integrated TV support */ |
| 47 | struct intel_tv_priv { | 47 | struct intel_tv { |
| 48 | struct intel_encoder base; | ||
| 49 | |||
| 48 | int type; | 50 | int type; |
| 49 | char *tv_format; | 51 | char *tv_format; |
| 50 | int margin[4]; | 52 | int margin[4]; |
| @@ -896,6 +898,11 @@ static const struct tv_mode tv_modes[] = { | |||
| 896 | }, | 898 | }, |
| 897 | }; | 899 | }; |
| 898 | 900 | ||
| 901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) | ||
| 902 | { | ||
| 903 | return container_of(enc_to_intel_encoder(encoder), struct intel_tv, base); | ||
| 904 | } | ||
| 905 | |||
| 899 | static void | 906 | static void |
| 900 | intel_tv_dpms(struct drm_encoder *encoder, int mode) | 907 | intel_tv_dpms(struct drm_encoder *encoder, int mode) |
| 901 | { | 908 | { |
| @@ -929,19 +936,17 @@ intel_tv_mode_lookup (char *tv_format) | |||
| 929 | } | 936 | } |
| 930 | 937 | ||
| 931 | static const struct tv_mode * | 938 | static const struct tv_mode * |
| 932 | intel_tv_mode_find (struct intel_encoder *intel_encoder) | 939 | intel_tv_mode_find (struct intel_tv *intel_tv) |
| 933 | { | 940 | { |
| 934 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 941 | return intel_tv_mode_lookup(intel_tv->tv_format); |
| 935 | |||
| 936 | return intel_tv_mode_lookup(tv_priv->tv_format); | ||
| 937 | } | 942 | } |
| 938 | 943 | ||
| 939 | static enum drm_mode_status | 944 | static enum drm_mode_status |
| 940 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) | 945 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) |
| 941 | { | 946 | { |
| 942 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 947 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 943 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 948 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 944 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 949 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 945 | 950 | ||
| 946 | /* Ensure TV refresh is close to desired refresh */ | 951 | /* Ensure TV refresh is close to desired refresh */ |
| 947 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) | 952 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) |
| @@ -957,8 +962,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 957 | { | 962 | { |
| 958 | struct drm_device *dev = encoder->dev; | 963 | struct drm_device *dev = encoder->dev; |
| 959 | struct drm_mode_config *drm_config = &dev->mode_config; | 964 | struct drm_mode_config *drm_config = &dev->mode_config; |
| 960 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 965 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 961 | const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder); | 966 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 962 | struct drm_encoder *other_encoder; | 967 | struct drm_encoder *other_encoder; |
| 963 | 968 | ||
| 964 | if (!tv_mode) | 969 | if (!tv_mode) |
| @@ -983,9 +988,8 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 983 | struct drm_i915_private *dev_priv = dev->dev_private; | 988 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 984 | struct drm_crtc *crtc = encoder->crtc; | 989 | struct drm_crtc *crtc = encoder->crtc; |
| 985 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 990 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 986 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 991 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 987 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 992 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 988 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | ||
| 989 | u32 tv_ctl; | 993 | u32 tv_ctl; |
| 990 | u32 hctl1, hctl2, hctl3; | 994 | u32 hctl1, hctl2, hctl3; |
| 991 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; | 995 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; |
| @@ -1001,7 +1005,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 1001 | tv_ctl = I915_READ(TV_CTL); | 1005 | tv_ctl = I915_READ(TV_CTL); |
| 1002 | tv_ctl &= TV_CTL_SAVE; | 1006 | tv_ctl &= TV_CTL_SAVE; |
| 1003 | 1007 | ||
| 1004 | switch (tv_priv->type) { | 1008 | switch (intel_tv->type) { |
| 1005 | default: | 1009 | default: |
| 1006 | case DRM_MODE_CONNECTOR_Unknown: | 1010 | case DRM_MODE_CONNECTOR_Unknown: |
| 1007 | case DRM_MODE_CONNECTOR_Composite: | 1011 | case DRM_MODE_CONNECTOR_Composite: |
| @@ -1154,11 +1158,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 1154 | 1158 | ||
| 1155 | /* Wait for vblank for the disable to take effect */ | 1159 | /* Wait for vblank for the disable to take effect */ |
| 1156 | if (!IS_I9XX(dev)) | 1160 | if (!IS_I9XX(dev)) |
| 1157 | intel_wait_for_vblank(dev); | 1161 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1158 | 1162 | ||
| 1159 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); | 1163 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); |
| 1160 | /* Wait for vblank for the disable to take effect. */ | 1164 | /* Wait for vblank for the disable to take effect. */ |
| 1161 | intel_wait_for_vblank(dev); | 1165 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1162 | 1166 | ||
| 1163 | /* Filter ctl must be set before TV_WIN_SIZE */ | 1167 | /* Filter ctl must be set before TV_WIN_SIZE */ |
| 1164 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); | 1168 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); |
| @@ -1168,12 +1172,12 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 1168 | else | 1172 | else |
| 1169 | ysize = 2*tv_mode->nbr_end + 1; | 1173 | ysize = 2*tv_mode->nbr_end + 1; |
| 1170 | 1174 | ||
| 1171 | xpos += tv_priv->margin[TV_MARGIN_LEFT]; | 1175 | xpos += intel_tv->margin[TV_MARGIN_LEFT]; |
| 1172 | ypos += tv_priv->margin[TV_MARGIN_TOP]; | 1176 | ypos += intel_tv->margin[TV_MARGIN_TOP]; |
| 1173 | xsize -= (tv_priv->margin[TV_MARGIN_LEFT] + | 1177 | xsize -= (intel_tv->margin[TV_MARGIN_LEFT] + |
| 1174 | tv_priv->margin[TV_MARGIN_RIGHT]); | 1178 | intel_tv->margin[TV_MARGIN_RIGHT]); |
| 1175 | ysize -= (tv_priv->margin[TV_MARGIN_TOP] + | 1179 | ysize -= (intel_tv->margin[TV_MARGIN_TOP] + |
| 1176 | tv_priv->margin[TV_MARGIN_BOTTOM]); | 1180 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
| 1177 | I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); | 1181 | I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); |
| 1178 | I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); | 1182 | I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); |
| 1179 | 1183 | ||
| @@ -1222,9 +1226,9 @@ static const struct drm_display_mode reported_modes[] = { | |||
| 1222 | * \return false if TV is disconnected. | 1226 | * \return false if TV is disconnected. |
| 1223 | */ | 1227 | */ |
| 1224 | static int | 1228 | static int |
| 1225 | intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder) | 1229 | intel_tv_detect_type (struct intel_tv *intel_tv) |
| 1226 | { | 1230 | { |
| 1227 | struct drm_encoder *encoder = &intel_encoder->enc; | 1231 | struct drm_encoder *encoder = &intel_tv->base.enc; |
| 1228 | struct drm_device *dev = encoder->dev; | 1232 | struct drm_device *dev = encoder->dev; |
| 1229 | struct drm_i915_private *dev_priv = dev->dev_private; | 1233 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1230 | unsigned long irqflags; | 1234 | unsigned long irqflags; |
| @@ -1263,11 +1267,15 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
| 1263 | DAC_C_0_7_V); | 1267 | DAC_C_0_7_V); |
| 1264 | I915_WRITE(TV_CTL, tv_ctl); | 1268 | I915_WRITE(TV_CTL, tv_ctl); |
| 1265 | I915_WRITE(TV_DAC, tv_dac); | 1269 | I915_WRITE(TV_DAC, tv_dac); |
| 1266 | intel_wait_for_vblank(dev); | 1270 | POSTING_READ(TV_DAC); |
| 1271 | msleep(20); | ||
| 1272 | |||
| 1267 | tv_dac = I915_READ(TV_DAC); | 1273 | tv_dac = I915_READ(TV_DAC); |
| 1268 | I915_WRITE(TV_DAC, save_tv_dac); | 1274 | I915_WRITE(TV_DAC, save_tv_dac); |
| 1269 | I915_WRITE(TV_CTL, save_tv_ctl); | 1275 | I915_WRITE(TV_CTL, save_tv_ctl); |
| 1270 | intel_wait_for_vblank(dev); | 1276 | POSTING_READ(TV_CTL); |
| 1277 | msleep(20); | ||
| 1278 | |||
| 1271 | /* | 1279 | /* |
| 1272 | * A B C | 1280 | * A B C |
| 1273 | * 0 1 1 Composite | 1281 | * 0 1 1 Composite |
| @@ -1304,12 +1312,11 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
| 1304 | static void intel_tv_find_better_format(struct drm_connector *connector) | 1312 | static void intel_tv_find_better_format(struct drm_connector *connector) |
| 1305 | { | 1313 | { |
| 1306 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1314 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1307 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1315 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 1308 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1316 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 1309 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | ||
| 1310 | int i; | 1317 | int i; |
| 1311 | 1318 | ||
| 1312 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1319 | if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == |
| 1313 | tv_mode->component_only) | 1320 | tv_mode->component_only) |
| 1314 | return; | 1321 | return; |
| 1315 | 1322 | ||
| @@ -1317,12 +1324,12 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
| 1317 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { | 1324 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { |
| 1318 | tv_mode = tv_modes + i; | 1325 | tv_mode = tv_modes + i; |
| 1319 | 1326 | ||
| 1320 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1327 | if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == |
| 1321 | tv_mode->component_only) | 1328 | tv_mode->component_only) |
| 1322 | break; | 1329 | break; |
| 1323 | } | 1330 | } |
| 1324 | 1331 | ||
| 1325 | tv_priv->tv_format = tv_mode->name; | 1332 | intel_tv->tv_format = tv_mode->name; |
| 1326 | drm_connector_property_set_value(connector, | 1333 | drm_connector_property_set_value(connector, |
| 1327 | connector->dev->mode_config.tv_mode_property, i); | 1334 | connector->dev->mode_config.tv_mode_property, i); |
| 1328 | } | 1335 | } |
| @@ -1334,33 +1341,32 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
| 1334 | * we have a pipe programmed in order to probe the TV. | 1341 | * we have a pipe programmed in order to probe the TV. |
| 1335 | */ | 1342 | */ |
| 1336 | static enum drm_connector_status | 1343 | static enum drm_connector_status |
| 1337 | intel_tv_detect(struct drm_connector *connector) | 1344 | intel_tv_detect(struct drm_connector *connector, bool force) |
| 1338 | { | 1345 | { |
| 1339 | struct drm_crtc *crtc; | ||
| 1340 | struct drm_display_mode mode; | 1346 | struct drm_display_mode mode; |
| 1341 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1347 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1342 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1348 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 1343 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1349 | int type; |
| 1344 | int dpms_mode; | ||
| 1345 | int type = tv_priv->type; | ||
| 1346 | 1350 | ||
| 1347 | mode = reported_modes[0]; | 1351 | mode = reported_modes[0]; |
| 1348 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); | 1352 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); |
| 1349 | 1353 | ||
| 1350 | if (encoder->crtc && encoder->crtc->enabled) { | 1354 | if (encoder->crtc && encoder->crtc->enabled) { |
| 1351 | type = intel_tv_detect_type(encoder->crtc, intel_encoder); | 1355 | type = intel_tv_detect_type(intel_tv); |
| 1352 | } else { | 1356 | } else if (force) { |
| 1353 | crtc = intel_get_load_detect_pipe(intel_encoder, connector, | 1357 | struct drm_crtc *crtc; |
| 1358 | int dpms_mode; | ||
| 1359 | |||
| 1360 | crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, | ||
| 1354 | &mode, &dpms_mode); | 1361 | &mode, &dpms_mode); |
| 1355 | if (crtc) { | 1362 | if (crtc) { |
| 1356 | type = intel_tv_detect_type(crtc, intel_encoder); | 1363 | type = intel_tv_detect_type(intel_tv); |
| 1357 | intel_release_load_detect_pipe(intel_encoder, connector, | 1364 | intel_release_load_detect_pipe(&intel_tv->base, connector, |
| 1358 | dpms_mode); | 1365 | dpms_mode); |
| 1359 | } else | 1366 | } else |
| 1360 | type = -1; | 1367 | return connector_status_unknown; |
| 1361 | } | 1368 | } else |
| 1362 | 1369 | return connector->status; | |
| 1363 | tv_priv->type = type; | ||
| 1364 | 1370 | ||
| 1365 | if (type < 0) | 1371 | if (type < 0) |
| 1366 | return connector_status_disconnected; | 1372 | return connector_status_disconnected; |
| @@ -1391,8 +1397,8 @@ intel_tv_chose_preferred_modes(struct drm_connector *connector, | |||
| 1391 | struct drm_display_mode *mode_ptr) | 1397 | struct drm_display_mode *mode_ptr) |
| 1392 | { | 1398 | { |
| 1393 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1399 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1394 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1400 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 1395 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1401 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 1396 | 1402 | ||
| 1397 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | 1403 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) |
| 1398 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | 1404 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; |
| @@ -1417,8 +1423,8 @@ intel_tv_get_modes(struct drm_connector *connector) | |||
| 1417 | { | 1423 | { |
| 1418 | struct drm_display_mode *mode_ptr; | 1424 | struct drm_display_mode *mode_ptr; |
| 1419 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1425 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1420 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1426 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 1421 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1427 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 1422 | int j, count = 0; | 1428 | int j, count = 0; |
| 1423 | u64 tmp; | 1429 | u64 tmp; |
| 1424 | 1430 | ||
| @@ -1483,8 +1489,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
| 1483 | { | 1489 | { |
| 1484 | struct drm_device *dev = connector->dev; | 1490 | struct drm_device *dev = connector->dev; |
| 1485 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1491 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1486 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1492 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 1487 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | ||
| 1488 | struct drm_crtc *crtc = encoder->crtc; | 1493 | struct drm_crtc *crtc = encoder->crtc; |
| 1489 | int ret = 0; | 1494 | int ret = 0; |
| 1490 | bool changed = false; | 1495 | bool changed = false; |
| @@ -1494,30 +1499,30 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
| 1494 | goto out; | 1499 | goto out; |
| 1495 | 1500 | ||
| 1496 | if (property == dev->mode_config.tv_left_margin_property && | 1501 | if (property == dev->mode_config.tv_left_margin_property && |
| 1497 | tv_priv->margin[TV_MARGIN_LEFT] != val) { | 1502 | intel_tv->margin[TV_MARGIN_LEFT] != val) { |
| 1498 | tv_priv->margin[TV_MARGIN_LEFT] = val; | 1503 | intel_tv->margin[TV_MARGIN_LEFT] = val; |
| 1499 | changed = true; | 1504 | changed = true; |
| 1500 | } else if (property == dev->mode_config.tv_right_margin_property && | 1505 | } else if (property == dev->mode_config.tv_right_margin_property && |
| 1501 | tv_priv->margin[TV_MARGIN_RIGHT] != val) { | 1506 | intel_tv->margin[TV_MARGIN_RIGHT] != val) { |
| 1502 | tv_priv->margin[TV_MARGIN_RIGHT] = val; | 1507 | intel_tv->margin[TV_MARGIN_RIGHT] = val; |
| 1503 | changed = true; | 1508 | changed = true; |
| 1504 | } else if (property == dev->mode_config.tv_top_margin_property && | 1509 | } else if (property == dev->mode_config.tv_top_margin_property && |
| 1505 | tv_priv->margin[TV_MARGIN_TOP] != val) { | 1510 | intel_tv->margin[TV_MARGIN_TOP] != val) { |
| 1506 | tv_priv->margin[TV_MARGIN_TOP] = val; | 1511 | intel_tv->margin[TV_MARGIN_TOP] = val; |
| 1507 | changed = true; | 1512 | changed = true; |
| 1508 | } else if (property == dev->mode_config.tv_bottom_margin_property && | 1513 | } else if (property == dev->mode_config.tv_bottom_margin_property && |
| 1509 | tv_priv->margin[TV_MARGIN_BOTTOM] != val) { | 1514 | intel_tv->margin[TV_MARGIN_BOTTOM] != val) { |
| 1510 | tv_priv->margin[TV_MARGIN_BOTTOM] = val; | 1515 | intel_tv->margin[TV_MARGIN_BOTTOM] = val; |
| 1511 | changed = true; | 1516 | changed = true; |
| 1512 | } else if (property == dev->mode_config.tv_mode_property) { | 1517 | } else if (property == dev->mode_config.tv_mode_property) { |
| 1513 | if (val >= ARRAY_SIZE(tv_modes)) { | 1518 | if (val >= ARRAY_SIZE(tv_modes)) { |
| 1514 | ret = -EINVAL; | 1519 | ret = -EINVAL; |
| 1515 | goto out; | 1520 | goto out; |
| 1516 | } | 1521 | } |
| 1517 | if (!strcmp(tv_priv->tv_format, tv_modes[val].name)) | 1522 | if (!strcmp(intel_tv->tv_format, tv_modes[val].name)) |
| 1518 | goto out; | 1523 | goto out; |
| 1519 | 1524 | ||
| 1520 | tv_priv->tv_format = tv_modes[val].name; | 1525 | intel_tv->tv_format = tv_modes[val].name; |
| 1521 | changed = true; | 1526 | changed = true; |
| 1522 | } else { | 1527 | } else { |
| 1523 | ret = -EINVAL; | 1528 | ret = -EINVAL; |
| @@ -1553,16 +1558,8 @@ static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = | |||
| 1553 | .best_encoder = intel_attached_encoder, | 1558 | .best_encoder = intel_attached_encoder, |
| 1554 | }; | 1559 | }; |
| 1555 | 1560 | ||
| 1556 | static void intel_tv_enc_destroy(struct drm_encoder *encoder) | ||
| 1557 | { | ||
| 1558 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 1559 | |||
| 1560 | drm_encoder_cleanup(encoder); | ||
| 1561 | kfree(intel_encoder); | ||
| 1562 | } | ||
| 1563 | |||
| 1564 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { | 1561 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { |
| 1565 | .destroy = intel_tv_enc_destroy, | 1562 | .destroy = intel_encoder_destroy, |
| 1566 | }; | 1563 | }; |
| 1567 | 1564 | ||
| 1568 | /* | 1565 | /* |
| @@ -1606,9 +1603,9 @@ intel_tv_init(struct drm_device *dev) | |||
| 1606 | { | 1603 | { |
| 1607 | struct drm_i915_private *dev_priv = dev->dev_private; | 1604 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1608 | struct drm_connector *connector; | 1605 | struct drm_connector *connector; |
| 1606 | struct intel_tv *intel_tv; | ||
| 1609 | struct intel_encoder *intel_encoder; | 1607 | struct intel_encoder *intel_encoder; |
| 1610 | struct intel_connector *intel_connector; | 1608 | struct intel_connector *intel_connector; |
| 1611 | struct intel_tv_priv *tv_priv; | ||
| 1612 | u32 tv_dac_on, tv_dac_off, save_tv_dac; | 1609 | u32 tv_dac_on, tv_dac_off, save_tv_dac; |
| 1613 | char **tv_format_names; | 1610 | char **tv_format_names; |
| 1614 | int i, initial_mode = 0; | 1611 | int i, initial_mode = 0; |
| @@ -1647,18 +1644,18 @@ intel_tv_init(struct drm_device *dev) | |||
| 1647 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) | 1644 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) |
| 1648 | return; | 1645 | return; |
| 1649 | 1646 | ||
| 1650 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + | 1647 | intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL); |
| 1651 | sizeof(struct intel_tv_priv), GFP_KERNEL); | 1648 | if (!intel_tv) { |
| 1652 | if (!intel_encoder) { | ||
| 1653 | return; | 1649 | return; |
| 1654 | } | 1650 | } |
| 1655 | 1651 | ||
| 1656 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1652 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 1657 | if (!intel_connector) { | 1653 | if (!intel_connector) { |
| 1658 | kfree(intel_encoder); | 1654 | kfree(intel_tv); |
| 1659 | return; | 1655 | return; |
| 1660 | } | 1656 | } |
| 1661 | 1657 | ||
| 1658 | intel_encoder = &intel_tv->base; | ||
| 1662 | connector = &intel_connector->base; | 1659 | connector = &intel_connector->base; |
| 1663 | 1660 | ||
| 1664 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1661 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
| @@ -1668,22 +1665,20 @@ intel_tv_init(struct drm_device *dev) | |||
| 1668 | DRM_MODE_ENCODER_TVDAC); | 1665 | DRM_MODE_ENCODER_TVDAC); |
| 1669 | 1666 | ||
| 1670 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); | 1667 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); |
| 1671 | tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); | ||
| 1672 | intel_encoder->type = INTEL_OUTPUT_TVOUT; | 1668 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
| 1673 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1669 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
| 1674 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); | 1670 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); |
| 1675 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1671 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); |
| 1676 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1672 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
| 1677 | intel_encoder->dev_priv = tv_priv; | 1673 | intel_tv->type = DRM_MODE_CONNECTOR_Unknown; |
| 1678 | tv_priv->type = DRM_MODE_CONNECTOR_Unknown; | ||
| 1679 | 1674 | ||
| 1680 | /* BIOS margin values */ | 1675 | /* BIOS margin values */ |
| 1681 | tv_priv->margin[TV_MARGIN_LEFT] = 54; | 1676 | intel_tv->margin[TV_MARGIN_LEFT] = 54; |
| 1682 | tv_priv->margin[TV_MARGIN_TOP] = 36; | 1677 | intel_tv->margin[TV_MARGIN_TOP] = 36; |
| 1683 | tv_priv->margin[TV_MARGIN_RIGHT] = 46; | 1678 | intel_tv->margin[TV_MARGIN_RIGHT] = 46; |
| 1684 | tv_priv->margin[TV_MARGIN_BOTTOM] = 37; | 1679 | intel_tv->margin[TV_MARGIN_BOTTOM] = 37; |
| 1685 | 1680 | ||
| 1686 | tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); | 1681 | intel_tv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); |
| 1687 | 1682 | ||
| 1688 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); | 1683 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); |
| 1689 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); | 1684 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); |
| @@ -1703,16 +1698,16 @@ intel_tv_init(struct drm_device *dev) | |||
| 1703 | initial_mode); | 1698 | initial_mode); |
| 1704 | drm_connector_attach_property(connector, | 1699 | drm_connector_attach_property(connector, |
| 1705 | dev->mode_config.tv_left_margin_property, | 1700 | dev->mode_config.tv_left_margin_property, |
| 1706 | tv_priv->margin[TV_MARGIN_LEFT]); | 1701 | intel_tv->margin[TV_MARGIN_LEFT]); |
| 1707 | drm_connector_attach_property(connector, | 1702 | drm_connector_attach_property(connector, |
| 1708 | dev->mode_config.tv_top_margin_property, | 1703 | dev->mode_config.tv_top_margin_property, |
| 1709 | tv_priv->margin[TV_MARGIN_TOP]); | 1704 | intel_tv->margin[TV_MARGIN_TOP]); |
| 1710 | drm_connector_attach_property(connector, | 1705 | drm_connector_attach_property(connector, |
| 1711 | dev->mode_config.tv_right_margin_property, | 1706 | dev->mode_config.tv_right_margin_property, |
| 1712 | tv_priv->margin[TV_MARGIN_RIGHT]); | 1707 | intel_tv->margin[TV_MARGIN_RIGHT]); |
| 1713 | drm_connector_attach_property(connector, | 1708 | drm_connector_attach_property(connector, |
| 1714 | dev->mode_config.tv_bottom_margin_property, | 1709 | dev->mode_config.tv_bottom_margin_property, |
| 1715 | tv_priv->margin[TV_MARGIN_BOTTOM]); | 1710 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
| 1716 | out: | 1711 | out: |
| 1717 | drm_sysfs_connector_add(connector); | 1712 | drm_sysfs_connector_add(connector); |
| 1718 | } | 1713 | } |
diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c index fff82045c427..9ce2827f8c00 100644 --- a/drivers/gpu/drm/mga/mga_state.c +++ b/drivers/gpu/drm/mga/mga_state.c | |||
| @@ -1085,19 +1085,19 @@ file_priv) | |||
| 1085 | } | 1085 | } |
| 1086 | 1086 | ||
| 1087 | struct drm_ioctl_desc mga_ioctls[] = { | 1087 | struct drm_ioctl_desc mga_ioctls[] = { |
| 1088 | DRM_IOCTL_DEF(DRM_MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1088 | DRM_IOCTL_DEF_DRV(MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1089 | DRM_IOCTL_DEF(DRM_MGA_FLUSH, mga_dma_flush, DRM_AUTH), | 1089 | DRM_IOCTL_DEF_DRV(MGA_FLUSH, mga_dma_flush, DRM_AUTH), |
| 1090 | DRM_IOCTL_DEF(DRM_MGA_RESET, mga_dma_reset, DRM_AUTH), | 1090 | DRM_IOCTL_DEF_DRV(MGA_RESET, mga_dma_reset, DRM_AUTH), |
| 1091 | DRM_IOCTL_DEF(DRM_MGA_SWAP, mga_dma_swap, DRM_AUTH), | 1091 | DRM_IOCTL_DEF_DRV(MGA_SWAP, mga_dma_swap, DRM_AUTH), |
| 1092 | DRM_IOCTL_DEF(DRM_MGA_CLEAR, mga_dma_clear, DRM_AUTH), | 1092 | DRM_IOCTL_DEF_DRV(MGA_CLEAR, mga_dma_clear, DRM_AUTH), |
| 1093 | DRM_IOCTL_DEF(DRM_MGA_VERTEX, mga_dma_vertex, DRM_AUTH), | 1093 | DRM_IOCTL_DEF_DRV(MGA_VERTEX, mga_dma_vertex, DRM_AUTH), |
| 1094 | DRM_IOCTL_DEF(DRM_MGA_INDICES, mga_dma_indices, DRM_AUTH), | 1094 | DRM_IOCTL_DEF_DRV(MGA_INDICES, mga_dma_indices, DRM_AUTH), |
| 1095 | DRM_IOCTL_DEF(DRM_MGA_ILOAD, mga_dma_iload, DRM_AUTH), | 1095 | DRM_IOCTL_DEF_DRV(MGA_ILOAD, mga_dma_iload, DRM_AUTH), |
| 1096 | DRM_IOCTL_DEF(DRM_MGA_BLIT, mga_dma_blit, DRM_AUTH), | 1096 | DRM_IOCTL_DEF_DRV(MGA_BLIT, mga_dma_blit, DRM_AUTH), |
| 1097 | DRM_IOCTL_DEF(DRM_MGA_GETPARAM, mga_getparam, DRM_AUTH), | 1097 | DRM_IOCTL_DEF_DRV(MGA_GETPARAM, mga_getparam, DRM_AUTH), |
| 1098 | DRM_IOCTL_DEF(DRM_MGA_SET_FENCE, mga_set_fence, DRM_AUTH), | 1098 | DRM_IOCTL_DEF_DRV(MGA_SET_FENCE, mga_set_fence, DRM_AUTH), |
| 1099 | DRM_IOCTL_DEF(DRM_MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), | 1099 | DRM_IOCTL_DEF_DRV(MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), |
| 1100 | DRM_IOCTL_DEF(DRM_MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1100 | DRM_IOCTL_DEF_DRV(MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1101 | }; | 1101 | }; |
| 1102 | 1102 | ||
| 1103 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); | 1103 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 0b69a9628c95..974b0f8ae048 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
| @@ -2166,7 +2166,7 @@ peek_fb(struct drm_device *dev, struct io_mapping *fb, | |||
| 2166 | uint32_t val = 0; | 2166 | uint32_t val = 0; |
| 2167 | 2167 | ||
| 2168 | if (off < pci_resource_len(dev->pdev, 1)) { | 2168 | if (off < pci_resource_len(dev->pdev, 1)) { |
| 2169 | uint32_t __iomem *p = | 2169 | uint8_t __iomem *p = |
| 2170 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); | 2170 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); |
| 2171 | 2171 | ||
| 2172 | val = ioread32(p + (off & ~PAGE_MASK)); | 2172 | val = ioread32(p + (off & ~PAGE_MASK)); |
| @@ -2182,7 +2182,7 @@ poke_fb(struct drm_device *dev, struct io_mapping *fb, | |||
| 2182 | uint32_t off, uint32_t val) | 2182 | uint32_t off, uint32_t val) |
| 2183 | { | 2183 | { |
| 2184 | if (off < pci_resource_len(dev->pdev, 1)) { | 2184 | if (off < pci_resource_len(dev->pdev, 1)) { |
| 2185 | uint32_t __iomem *p = | 2185 | uint8_t __iomem *p = |
| 2186 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); | 2186 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); |
| 2187 | 2187 | ||
| 2188 | iowrite32(val, p + (off & ~PAGE_MASK)); | 2188 | iowrite32(val, p + (off & ~PAGE_MASK)); |
| @@ -3869,27 +3869,10 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entr | |||
| 3869 | } | 3869 | } |
| 3870 | #ifdef __powerpc__ | 3870 | #ifdef __powerpc__ |
| 3871 | /* Powerbook specific quirks */ | 3871 | /* Powerbook specific quirks */ |
| 3872 | if ((dev->pci_device & 0xffff) == 0x0179 || | 3872 | if (script == LVDS_RESET && |
| 3873 | (dev->pci_device & 0xffff) == 0x0189 || | 3873 | (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || |
| 3874 | (dev->pci_device & 0xffff) == 0x0329) { | 3874 | dev->pci_device == 0x0329)) |
| 3875 | if (script == LVDS_RESET) { | 3875 | nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); |
| 3876 | nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); | ||
| 3877 | |||
| 3878 | } else if (script == LVDS_PANEL_ON) { | ||
| 3879 | bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, | ||
| 3880 | bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) | ||
| 3881 | | (1 << 31)); | ||
| 3882 | bios_wr32(bios, NV_PCRTC_GPIO_EXT, | ||
| 3883 | bios_rd32(bios, NV_PCRTC_GPIO_EXT) | 1); | ||
| 3884 | |||
| 3885 | } else if (script == LVDS_PANEL_OFF) { | ||
| 3886 | bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, | ||
| 3887 | bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) | ||
| 3888 | & ~(1 << 31)); | ||
| 3889 | bios_wr32(bios, NV_PCRTC_GPIO_EXT, | ||
| 3890 | bios_rd32(bios, NV_PCRTC_GPIO_EXT) & ~3); | ||
| 3891 | } | ||
| 3892 | } | ||
| 3893 | #endif | 3876 | #endif |
| 3894 | 3877 | ||
| 3895 | return 0; | 3878 | return 0; |
| @@ -4381,11 +4364,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b | |||
| 4381 | * | 4364 | * |
| 4382 | * For the moment, a quirk will do :) | 4365 | * For the moment, a quirk will do :) |
| 4383 | */ | 4366 | */ |
| 4384 | if ((dev->pdev->device == 0x01d7) && | 4367 | if (nv_match_device(dev, 0x01d7, 0x1028, 0x01c2)) |
| 4385 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
| 4386 | (dev->pdev->subsystem_device == 0x01c2)) { | ||
| 4387 | bios->fp.duallink_transition_clk = 80000; | 4368 | bios->fp.duallink_transition_clk = 80000; |
| 4388 | } | ||
| 4389 | 4369 | ||
| 4390 | /* set dual_link flag for EDID case */ | 4370 | /* set dual_link flag for EDID case */ |
| 4391 | if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) | 4371 | if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) |
| @@ -4587,7 +4567,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
| 4587 | return 1; | 4567 | return 1; |
| 4588 | } | 4568 | } |
| 4589 | 4569 | ||
| 4590 | NV_TRACE(dev, "0x%04X: parsing output script 0\n", script); | 4570 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script); |
| 4591 | nouveau_bios_run_init_table(dev, script, dcbent); | 4571 | nouveau_bios_run_init_table(dev, script, dcbent); |
| 4592 | } else | 4572 | } else |
| 4593 | if (pxclk == -1) { | 4573 | if (pxclk == -1) { |
| @@ -4597,7 +4577,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
| 4597 | return 1; | 4577 | return 1; |
| 4598 | } | 4578 | } |
| 4599 | 4579 | ||
| 4600 | NV_TRACE(dev, "0x%04X: parsing output script 1\n", script); | 4580 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script); |
| 4601 | nouveau_bios_run_init_table(dev, script, dcbent); | 4581 | nouveau_bios_run_init_table(dev, script, dcbent); |
| 4602 | } else | 4582 | } else |
| 4603 | if (pxclk == -2) { | 4583 | if (pxclk == -2) { |
| @@ -4610,7 +4590,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
| 4610 | return 1; | 4590 | return 1; |
| 4611 | } | 4591 | } |
| 4612 | 4592 | ||
| 4613 | NV_TRACE(dev, "0x%04X: parsing output script 2\n", script); | 4593 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script); |
| 4614 | nouveau_bios_run_init_table(dev, script, dcbent); | 4594 | nouveau_bios_run_init_table(dev, script, dcbent); |
| 4615 | } else | 4595 | } else |
| 4616 | if (pxclk > 0) { | 4596 | if (pxclk > 0) { |
| @@ -4622,7 +4602,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
| 4622 | return 1; | 4602 | return 1; |
| 4623 | } | 4603 | } |
| 4624 | 4604 | ||
| 4625 | NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script); | 4605 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script); |
| 4626 | nouveau_bios_run_init_table(dev, script, dcbent); | 4606 | nouveau_bios_run_init_table(dev, script, dcbent); |
| 4627 | } else | 4607 | } else |
| 4628 | if (pxclk < 0) { | 4608 | if (pxclk < 0) { |
| @@ -4634,7 +4614,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
| 4634 | return 1; | 4614 | return 1; |
| 4635 | } | 4615 | } |
| 4636 | 4616 | ||
| 4637 | NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script); | 4617 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script); |
| 4638 | nouveau_bios_run_init_table(dev, script, dcbent); | 4618 | nouveau_bios_run_init_table(dev, script, dcbent); |
| 4639 | } | 4619 | } |
| 4640 | 4620 | ||
| @@ -5357,19 +5337,17 @@ static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios, | |||
| 5357 | } | 5337 | } |
| 5358 | 5338 | ||
| 5359 | tmdstableptr = ROM16(bios->data[bitentry->offset]); | 5339 | tmdstableptr = ROM16(bios->data[bitentry->offset]); |
| 5360 | 5340 | if (!tmdstableptr) { | |
| 5361 | if (tmdstableptr == 0x0) { | ||
| 5362 | NV_ERROR(dev, "Pointer to TMDS table invalid\n"); | 5341 | NV_ERROR(dev, "Pointer to TMDS table invalid\n"); |
| 5363 | return -EINVAL; | 5342 | return -EINVAL; |
| 5364 | } | 5343 | } |
| 5365 | 5344 | ||
| 5345 | NV_INFO(dev, "TMDS table version %d.%d\n", | ||
| 5346 | bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); | ||
| 5347 | |||
| 5366 | /* nv50+ has v2.0, but we don't parse it atm */ | 5348 | /* nv50+ has v2.0, but we don't parse it atm */ |
| 5367 | if (bios->data[tmdstableptr] != 0x11) { | 5349 | if (bios->data[tmdstableptr] != 0x11) |
| 5368 | NV_WARN(dev, | ||
| 5369 | "TMDS table revision %d.%d not currently supported\n", | ||
| 5370 | bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); | ||
| 5371 | return -ENOSYS; | 5350 | return -ENOSYS; |
| 5372 | } | ||
| 5373 | 5351 | ||
| 5374 | /* | 5352 | /* |
| 5375 | * These two scripts are odd: they don't seem to get run even when | 5353 | * These two scripts are odd: they don't seem to get run even when |
| @@ -5809,6 +5787,20 @@ parse_dcb_gpio_table(struct nvbios *bios) | |||
| 5809 | gpio->line = tvdac_gpio[1] >> 4; | 5787 | gpio->line = tvdac_gpio[1] >> 4; |
| 5810 | gpio->invert = tvdac_gpio[0] & 2; | 5788 | gpio->invert = tvdac_gpio[0] & 2; |
| 5811 | } | 5789 | } |
| 5790 | } else { | ||
| 5791 | /* | ||
| 5792 | * No systematic way to store GPIO info on pre-v2.2 | ||
| 5793 | * DCBs, try to match the PCI device IDs. | ||
| 5794 | */ | ||
| 5795 | |||
| 5796 | /* Apple iMac G4 NV18 */ | ||
| 5797 | if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) { | ||
| 5798 | struct dcb_gpio_entry *gpio = new_gpio_entry(bios); | ||
| 5799 | |||
| 5800 | gpio->tag = DCB_GPIO_TVDAC0; | ||
| 5801 | gpio->line = 4; | ||
| 5802 | } | ||
| 5803 | |||
| 5812 | } | 5804 | } |
| 5813 | 5805 | ||
| 5814 | if (!gpio_table_ptr) | 5806 | if (!gpio_table_ptr) |
| @@ -5884,9 +5876,7 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx) | |||
| 5884 | struct drm_device *dev = bios->dev; | 5876 | struct drm_device *dev = bios->dev; |
| 5885 | 5877 | ||
| 5886 | /* Gigabyte NX85T */ | 5878 | /* Gigabyte NX85T */ |
| 5887 | if ((dev->pdev->device == 0x0421) && | 5879 | if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) { |
| 5888 | (dev->pdev->subsystem_vendor == 0x1458) && | ||
| 5889 | (dev->pdev->subsystem_device == 0x344c)) { | ||
| 5890 | if (cte->type == DCB_CONNECTOR_HDMI_1) | 5880 | if (cte->type == DCB_CONNECTOR_HDMI_1) |
| 5891 | cte->type = DCB_CONNECTOR_DVI_I; | 5881 | cte->type = DCB_CONNECTOR_DVI_I; |
| 5892 | } | 5882 | } |
| @@ -6139,7 +6129,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
| 6139 | entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; | 6129 | entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; |
| 6140 | 6130 | ||
| 6141 | break; | 6131 | break; |
| 6142 | case 0xe: | 6132 | case OUTPUT_EOL: |
| 6143 | /* weird g80 mobile type that "nv" treats as a terminator */ | 6133 | /* weird g80 mobile type that "nv" treats as a terminator */ |
| 6144 | dcb->entries--; | 6134 | dcb->entries--; |
| 6145 | return false; | 6135 | return false; |
| @@ -6176,22 +6166,14 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
| 6176 | entry->type = OUTPUT_TV; | 6166 | entry->type = OUTPUT_TV; |
| 6177 | break; | 6167 | break; |
| 6178 | case 2: | 6168 | case 2: |
| 6179 | case 3: | ||
| 6180 | entry->type = OUTPUT_LVDS; | ||
| 6181 | break; | ||
| 6182 | case 4: | 6169 | case 4: |
| 6183 | switch ((conn & 0x000000f0) >> 4) { | 6170 | if (conn & 0x10) |
| 6184 | case 0: | ||
| 6185 | entry->type = OUTPUT_TMDS; | ||
| 6186 | break; | ||
| 6187 | case 1: | ||
| 6188 | entry->type = OUTPUT_LVDS; | 6171 | entry->type = OUTPUT_LVDS; |
| 6189 | break; | 6172 | else |
| 6190 | default: | 6173 | entry->type = OUTPUT_TMDS; |
| 6191 | NV_ERROR(dev, "Unknown DCB subtype 4/%d\n", | 6174 | break; |
| 6192 | (conn & 0x000000f0) >> 4); | 6175 | case 3: |
| 6193 | return false; | 6176 | entry->type = OUTPUT_LVDS; |
| 6194 | } | ||
| 6195 | break; | 6177 | break; |
| 6196 | default: | 6178 | default: |
| 6197 | NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); | 6179 | NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); |
| @@ -6307,9 +6289,7 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) | |||
| 6307 | * nasty problems until this is sorted (assuming it's not a | 6289 | * nasty problems until this is sorted (assuming it's not a |
| 6308 | * VBIOS bug). | 6290 | * VBIOS bug). |
| 6309 | */ | 6291 | */ |
| 6310 | if ((dev->pdev->device == 0x040d) && | 6292 | if (nv_match_device(dev, 0x040d, 0x1028, 0x019b)) { |
| 6311 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
| 6312 | (dev->pdev->subsystem_device == 0x019b)) { | ||
| 6313 | if (*conn == 0x02026312 && *conf == 0x00000020) | 6293 | if (*conn == 0x02026312 && *conf == 0x00000020) |
| 6314 | return false; | 6294 | return false; |
| 6315 | } | 6295 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index fd14dfd3d780..c1de2f3fcb0e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
| @@ -95,6 +95,7 @@ enum dcb_type { | |||
| 95 | OUTPUT_TMDS = 2, | 95 | OUTPUT_TMDS = 2, |
| 96 | OUTPUT_LVDS = 3, | 96 | OUTPUT_LVDS = 3, |
| 97 | OUTPUT_DP = 6, | 97 | OUTPUT_DP = 6, |
| 98 | OUTPUT_EOL = 14, /* DCB 4.0+, appears to be end-of-list */ | ||
| 98 | OUTPUT_ANY = -1 | 99 | OUTPUT_ANY = -1 |
| 99 | }; | 100 | }; |
| 100 | 101 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 84f85183d041..f6f44779d82f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
| @@ -36,6 +36,21 @@ | |||
| 36 | #include <linux/log2.h> | 36 | #include <linux/log2.h> |
| 37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
| 38 | 38 | ||
| 39 | int | ||
| 40 | nouveau_bo_sync_gpu(struct nouveau_bo *nvbo, struct nouveau_channel *chan) | ||
| 41 | { | ||
| 42 | struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; | ||
| 43 | int ret; | ||
| 44 | |||
| 45 | if (!prev_fence || nouveau_fence_channel(prev_fence) == chan) | ||
| 46 | return 0; | ||
| 47 | |||
| 48 | spin_lock(&nvbo->bo.lock); | ||
| 49 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); | ||
| 50 | spin_unlock(&nvbo->bo.lock); | ||
| 51 | return ret; | ||
| 52 | } | ||
| 53 | |||
| 39 | static void | 54 | static void |
| 40 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) | 55 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) |
| 41 | { | 56 | { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 90fdcda332be..0480f064f2c1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
| @@ -426,18 +426,18 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, | |||
| 426 | ***********************************/ | 426 | ***********************************/ |
| 427 | 427 | ||
| 428 | struct drm_ioctl_desc nouveau_ioctls[] = { | 428 | struct drm_ioctl_desc nouveau_ioctls[] = { |
| 429 | DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), | 429 | DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), |
| 430 | DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 430 | DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 431 | DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), | 431 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), |
| 432 | DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), | 432 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), |
| 433 | DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), | 433 | DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), |
| 434 | DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), | 434 | DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), |
| 435 | DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), | 435 | DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), |
| 436 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), | 436 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), |
| 437 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), | 437 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), |
| 438 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), | 438 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), |
| 439 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), | 439 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), |
| 440 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), | 440 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), |
| 441 | }; | 441 | }; |
| 442 | 442 | ||
| 443 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); | 443 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index b1b22baf1428..fc737037f751 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
| @@ -104,7 +104,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, | |||
| 104 | int i; | 104 | int i; |
| 105 | 105 | ||
| 106 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 106 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
| 107 | struct nouveau_i2c_chan *i2c; | 107 | struct nouveau_i2c_chan *i2c = NULL; |
| 108 | struct nouveau_encoder *nv_encoder; | 108 | struct nouveau_encoder *nv_encoder; |
| 109 | struct drm_mode_object *obj; | 109 | struct drm_mode_object *obj; |
| 110 | int id; | 110 | int id; |
| @@ -117,7 +117,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, | |||
| 117 | if (!obj) | 117 | if (!obj) |
| 118 | continue; | 118 | continue; |
| 119 | nv_encoder = nouveau_encoder(obj_to_encoder(obj)); | 119 | nv_encoder = nouveau_encoder(obj_to_encoder(obj)); |
| 120 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | 120 | |
| 121 | if (nv_encoder->dcb->i2c_index < 0xf) | ||
| 122 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | ||
| 121 | 123 | ||
| 122 | if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { | 124 | if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { |
| 123 | *pnv_encoder = nv_encoder; | 125 | *pnv_encoder = nv_encoder; |
| @@ -166,7 +168,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector, | |||
| 166 | } | 168 | } |
| 167 | 169 | ||
| 168 | static enum drm_connector_status | 170 | static enum drm_connector_status |
| 169 | nouveau_connector_detect(struct drm_connector *connector) | 171 | nouveau_connector_detect(struct drm_connector *connector, bool force) |
| 170 | { | 172 | { |
| 171 | struct drm_device *dev = connector->dev; | 173 | struct drm_device *dev = connector->dev; |
| 172 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 174 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
| @@ -244,7 +246,7 @@ detect_analog: | |||
| 244 | } | 246 | } |
| 245 | 247 | ||
| 246 | static enum drm_connector_status | 248 | static enum drm_connector_status |
| 247 | nouveau_connector_detect_lvds(struct drm_connector *connector) | 249 | nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) |
| 248 | { | 250 | { |
| 249 | struct drm_device *dev = connector->dev; | 251 | struct drm_device *dev = connector->dev; |
| 250 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 252 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| @@ -265,7 +267,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector) | |||
| 265 | 267 | ||
| 266 | /* Try retrieving EDID via DDC */ | 268 | /* Try retrieving EDID via DDC */ |
| 267 | if (!dev_priv->vbios.fp_no_ddc) { | 269 | if (!dev_priv->vbios.fp_no_ddc) { |
| 268 | status = nouveau_connector_detect(connector); | 270 | status = nouveau_connector_detect(connector, force); |
| 269 | if (status == connector_status_connected) | 271 | if (status == connector_status_connected) |
| 270 | goto out; | 272 | goto out; |
| 271 | } | 273 | } |
| @@ -556,8 +558,10 @@ nouveau_connector_get_modes(struct drm_connector *connector) | |||
| 556 | if (nv_encoder->dcb->type == OUTPUT_LVDS && | 558 | if (nv_encoder->dcb->type == OUTPUT_LVDS && |
| 557 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || | 559 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || |
| 558 | dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { | 560 | dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { |
| 559 | nv_connector->native_mode = drm_mode_create(dev); | 561 | struct drm_display_mode mode; |
| 560 | nouveau_bios_fp_mode(dev, nv_connector->native_mode); | 562 | |
| 563 | nouveau_bios_fp_mode(dev, &mode); | ||
| 564 | nv_connector->native_mode = drm_mode_duplicate(dev, &mode); | ||
| 561 | } | 565 | } |
| 562 | 566 | ||
| 563 | /* Find the native mode if this is a digital panel, if we didn't | 567 | /* Find the native mode if this is a digital panel, if we didn't |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e424bf74d706..b1be617373b6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
| @@ -1165,6 +1165,7 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); | |||
| 1165 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); | 1165 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); |
| 1166 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); | 1166 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); |
| 1167 | extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); | 1167 | extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); |
| 1168 | extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *); | ||
| 1168 | 1169 | ||
| 1169 | /* nouveau_fence.c */ | 1170 | /* nouveau_fence.c */ |
| 1170 | struct nouveau_fence; | 1171 | struct nouveau_fence; |
| @@ -1388,6 +1389,15 @@ nv_two_reg_pll(struct drm_device *dev) | |||
| 1388 | return false; | 1389 | return false; |
| 1389 | } | 1390 | } |
| 1390 | 1391 | ||
| 1392 | static inline bool | ||
| 1393 | nv_match_device(struct drm_device *dev, unsigned device, | ||
| 1394 | unsigned sub_vendor, unsigned sub_device) | ||
| 1395 | { | ||
| 1396 | return dev->pdev->device == device && | ||
| 1397 | dev->pdev->subsystem_vendor == sub_vendor && | ||
| 1398 | dev->pdev->subsystem_device == sub_device; | ||
| 1399 | } | ||
| 1400 | |||
| 1391 | #define NV_SW 0x0000506e | 1401 | #define NV_SW 0x0000506e |
| 1392 | #define NV_SW_DMA_SEMAPHORE 0x00000060 | 1402 | #define NV_SW_DMA_SEMAPHORE 0x00000060 |
| 1393 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 | 1403 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 6b208ffafa8d..87ac21ec23d2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
| @@ -64,16 +64,17 @@ nouveau_fence_update(struct nouveau_channel *chan) | |||
| 64 | struct nouveau_fence *fence; | 64 | struct nouveau_fence *fence; |
| 65 | uint32_t sequence; | 65 | uint32_t sequence; |
| 66 | 66 | ||
| 67 | spin_lock(&chan->fence.lock); | ||
| 68 | |||
| 67 | if (USE_REFCNT) | 69 | if (USE_REFCNT) |
| 68 | sequence = nvchan_rd32(chan, 0x48); | 70 | sequence = nvchan_rd32(chan, 0x48); |
| 69 | else | 71 | else |
| 70 | sequence = atomic_read(&chan->fence.last_sequence_irq); | 72 | sequence = atomic_read(&chan->fence.last_sequence_irq); |
| 71 | 73 | ||
| 72 | if (chan->fence.sequence_ack == sequence) | 74 | if (chan->fence.sequence_ack == sequence) |
| 73 | return; | 75 | goto out; |
| 74 | chan->fence.sequence_ack = sequence; | 76 | chan->fence.sequence_ack = sequence; |
| 75 | 77 | ||
| 76 | spin_lock(&chan->fence.lock); | ||
| 77 | list_for_each_safe(entry, tmp, &chan->fence.pending) { | 78 | list_for_each_safe(entry, tmp, &chan->fence.pending) { |
| 78 | fence = list_entry(entry, struct nouveau_fence, entry); | 79 | fence = list_entry(entry, struct nouveau_fence, entry); |
| 79 | 80 | ||
| @@ -85,6 +86,7 @@ nouveau_fence_update(struct nouveau_channel *chan) | |||
| 85 | if (sequence == chan->fence.sequence_ack) | 86 | if (sequence == chan->fence.sequence_ack) |
| 86 | break; | 87 | break; |
| 87 | } | 88 | } |
| 89 | out: | ||
| 88 | spin_unlock(&chan->fence.lock); | 90 | spin_unlock(&chan->fence.lock); |
| 89 | } | 91 | } |
| 90 | 92 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 0f417ac1b696..19620a6709f5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
| @@ -167,11 +167,9 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, | |||
| 167 | goto out; | 167 | goto out; |
| 168 | 168 | ||
| 169 | ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); | 169 | ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); |
| 170 | /* drop reference from allocate - handle holds it now */ | ||
| 171 | drm_gem_object_unreference_unlocked(nvbo->gem); | ||
| 170 | out: | 172 | out: |
| 171 | drm_gem_object_handle_unreference_unlocked(nvbo->gem); | ||
| 172 | |||
| 173 | if (ret) | ||
| 174 | drm_gem_object_unreference_unlocked(nvbo->gem); | ||
| 175 | return ret; | 173 | return ret; |
| 176 | } | 174 | } |
| 177 | 175 | ||
| @@ -245,7 +243,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence) | |||
| 245 | list_del(&nvbo->entry); | 243 | list_del(&nvbo->entry); |
| 246 | nvbo->reserved_by = NULL; | 244 | nvbo->reserved_by = NULL; |
| 247 | ttm_bo_unreserve(&nvbo->bo); | 245 | ttm_bo_unreserve(&nvbo->bo); |
| 248 | drm_gem_object_unreference(nvbo->gem); | 246 | drm_gem_object_unreference_unlocked(nvbo->gem); |
| 249 | } | 247 | } |
| 250 | } | 248 | } |
| 251 | 249 | ||
| @@ -300,7 +298,7 @@ retry: | |||
| 300 | validate_fini(op, NULL); | 298 | validate_fini(op, NULL); |
| 301 | if (ret == -EAGAIN) | 299 | if (ret == -EAGAIN) |
| 302 | ret = ttm_bo_wait_unreserved(&nvbo->bo, false); | 300 | ret = ttm_bo_wait_unreserved(&nvbo->bo, false); |
| 303 | drm_gem_object_unreference(gem); | 301 | drm_gem_object_unreference_unlocked(gem); |
| 304 | if (ret) { | 302 | if (ret) { |
| 305 | NV_ERROR(dev, "fail reserve\n"); | 303 | NV_ERROR(dev, "fail reserve\n"); |
| 306 | return ret; | 304 | return ret; |
| @@ -337,7 +335,9 @@ retry: | |||
| 337 | return -EINVAL; | 335 | return -EINVAL; |
| 338 | } | 336 | } |
| 339 | 337 | ||
| 338 | mutex_unlock(&drm_global_mutex); | ||
| 340 | ret = ttm_bo_wait_cpu(&nvbo->bo, false); | 339 | ret = ttm_bo_wait_cpu(&nvbo->bo, false); |
| 340 | mutex_lock(&drm_global_mutex); | ||
| 341 | if (ret) { | 341 | if (ret) { |
| 342 | NV_ERROR(dev, "fail wait_cpu\n"); | 342 | NV_ERROR(dev, "fail wait_cpu\n"); |
| 343 | return ret; | 343 | return ret; |
| @@ -361,16 +361,11 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
| 361 | 361 | ||
| 362 | list_for_each_entry(nvbo, list, entry) { | 362 | list_for_each_entry(nvbo, list, entry) { |
| 363 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; | 363 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; |
| 364 | struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; | ||
| 365 | 364 | ||
| 366 | if (prev_fence && nouveau_fence_channel(prev_fence) != chan) { | 365 | ret = nouveau_bo_sync_gpu(nvbo, chan); |
| 367 | spin_lock(&nvbo->bo.lock); | 366 | if (unlikely(ret)) { |
| 368 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); | 367 | NV_ERROR(dev, "fail pre-validate sync\n"); |
| 369 | spin_unlock(&nvbo->bo.lock); | 368 | return ret; |
| 370 | if (unlikely(ret)) { | ||
| 371 | NV_ERROR(dev, "fail wait other chan\n"); | ||
| 372 | return ret; | ||
| 373 | } | ||
| 374 | } | 369 | } |
| 375 | 370 | ||
| 376 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, | 371 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, |
| @@ -381,7 +376,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
| 381 | return ret; | 376 | return ret; |
| 382 | } | 377 | } |
| 383 | 378 | ||
| 384 | nvbo->channel = chan; | 379 | nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan; |
| 385 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, | 380 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, |
| 386 | false, false, false); | 381 | false, false, false); |
| 387 | nvbo->channel = NULL; | 382 | nvbo->channel = NULL; |
| @@ -390,6 +385,12 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
| 390 | return ret; | 385 | return ret; |
| 391 | } | 386 | } |
| 392 | 387 | ||
| 388 | ret = nouveau_bo_sync_gpu(nvbo, chan); | ||
| 389 | if (unlikely(ret)) { | ||
| 390 | NV_ERROR(dev, "fail post-validate sync\n"); | ||
| 391 | return ret; | ||
| 392 | } | ||
| 393 | |||
| 393 | if (nvbo->bo.offset == b->presumed.offset && | 394 | if (nvbo->bo.offset == b->presumed.offset && |
| 394 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && | 395 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && |
| 395 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || | 396 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || |
| @@ -613,7 +614,20 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
| 613 | return PTR_ERR(bo); | 614 | return PTR_ERR(bo); |
| 614 | } | 615 | } |
| 615 | 616 | ||
| 616 | mutex_lock(&dev->struct_mutex); | 617 | /* Mark push buffers as being used on PFIFO, the validation code |
| 618 | * will then make sure that if the pushbuf bo moves, that they | ||
| 619 | * happen on the kernel channel, which will in turn cause a sync | ||
| 620 | * to happen before we try and submit the push buffer. | ||
| 621 | */ | ||
| 622 | for (i = 0; i < req->nr_push; i++) { | ||
| 623 | if (push[i].bo_index >= req->nr_buffers) { | ||
| 624 | NV_ERROR(dev, "push %d buffer not in list\n", i); | ||
| 625 | ret = -EINVAL; | ||
| 626 | goto out; | ||
| 627 | } | ||
| 628 | |||
| 629 | bo[push[i].bo_index].read_domains |= (1 << 31); | ||
| 630 | } | ||
| 617 | 631 | ||
| 618 | /* Validate buffer list */ | 632 | /* Validate buffer list */ |
| 619 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, | 633 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, |
| @@ -647,7 +661,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
| 647 | push[i].length); | 661 | push[i].length); |
| 648 | } | 662 | } |
| 649 | } else | 663 | } else |
| 650 | if (dev_priv->card_type >= NV_20) { | 664 | if (dev_priv->chipset >= 0x25) { |
| 651 | ret = RING_SPACE(chan, req->nr_push * 2); | 665 | ret = RING_SPACE(chan, req->nr_push * 2); |
| 652 | if (ret) { | 666 | if (ret) { |
| 653 | NV_ERROR(dev, "cal_space: %d\n", ret); | 667 | NV_ERROR(dev, "cal_space: %d\n", ret); |
| @@ -713,7 +727,6 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
| 713 | out: | 727 | out: |
| 714 | validate_fini(&op, fence); | 728 | validate_fini(&op, fence); |
| 715 | nouveau_fence_unref((void**)&fence); | 729 | nouveau_fence_unref((void**)&fence); |
| 716 | mutex_unlock(&dev->struct_mutex); | ||
| 717 | kfree(bo); | 730 | kfree(bo); |
| 718 | kfree(push); | 731 | kfree(push); |
| 719 | 732 | ||
| @@ -722,7 +735,7 @@ out_next: | |||
| 722 | req->suffix0 = 0x00000000; | 735 | req->suffix0 = 0x00000000; |
| 723 | req->suffix1 = 0x00000000; | 736 | req->suffix1 = 0x00000000; |
| 724 | } else | 737 | } else |
| 725 | if (dev_priv->card_type >= NV_20) { | 738 | if (dev_priv->chipset >= 0x25) { |
| 726 | req->suffix0 = 0x00020000; | 739 | req->suffix0 = 0x00020000; |
| 727 | req->suffix1 = 0x00000000; | 740 | req->suffix1 = 0x00000000; |
| 728 | } else { | 741 | } else { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 0bd407ca3d42..84614858728b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
| @@ -163,7 +163,7 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index) | |||
| 163 | if (entry->chan) | 163 | if (entry->chan) |
| 164 | return -EEXIST; | 164 | return -EEXIST; |
| 165 | 165 | ||
| 166 | if (dev_priv->card_type == NV_C0 && entry->read >= NV50_I2C_PORTS) { | 166 | if (dev_priv->card_type >= NV_50 && entry->read >= NV50_I2C_PORTS) { |
| 167 | NV_ERROR(dev, "unknown i2c port %d\n", entry->read); | 167 | NV_ERROR(dev, "unknown i2c port %d\n", entry->read); |
| 168 | return -EINVAL; | 168 | return -EINVAL; |
| 169 | } | 169 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 491767fe4fcf..6b9187d7f67d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
| @@ -214,6 +214,7 @@ int | |||
| 214 | nouveau_sgdma_init(struct drm_device *dev) | 214 | nouveau_sgdma_init(struct drm_device *dev) |
| 215 | { | 215 | { |
| 216 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 216 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 217 | struct pci_dev *pdev = dev->pdev; | ||
| 217 | struct nouveau_gpuobj *gpuobj = NULL; | 218 | struct nouveau_gpuobj *gpuobj = NULL; |
| 218 | uint32_t aper_size, obj_size; | 219 | uint32_t aper_size, obj_size; |
| 219 | int i, ret; | 220 | int i, ret; |
| @@ -239,10 +240,19 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
| 239 | 240 | ||
| 240 | dev_priv->gart_info.sg_dummy_page = | 241 | dev_priv->gart_info.sg_dummy_page = |
| 241 | alloc_page(GFP_KERNEL|__GFP_DMA32); | 242 | alloc_page(GFP_KERNEL|__GFP_DMA32); |
| 243 | if (!dev_priv->gart_info.sg_dummy_page) { | ||
| 244 | nouveau_gpuobj_del(dev, &gpuobj); | ||
| 245 | return -ENOMEM; | ||
| 246 | } | ||
| 247 | |||
| 242 | set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); | 248 | set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); |
| 243 | dev_priv->gart_info.sg_dummy_bus = | 249 | dev_priv->gart_info.sg_dummy_bus = |
| 244 | pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, | 250 | pci_map_page(pdev, dev_priv->gart_info.sg_dummy_page, 0, |
| 245 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 251 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
| 252 | if (pci_dma_mapping_error(pdev, dev_priv->gart_info.sg_dummy_bus)) { | ||
| 253 | nouveau_gpuobj_del(dev, &gpuobj); | ||
| 254 | return -EFAULT; | ||
| 255 | } | ||
| 246 | 256 | ||
| 247 | if (dev_priv->card_type < NV_50) { | 257 | if (dev_priv->card_type < NV_50) { |
| 248 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and | 258 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index a5dcf7685800..0d3206a7046c 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
| @@ -444,6 +444,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
| 444 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 444 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
| 445 | struct dcb_entry *dcbe = nv_encoder->dcb; | 445 | struct dcb_entry *dcbe = nv_encoder->dcb; |
| 446 | int head = nouveau_crtc(encoder->crtc)->index; | 446 | int head = nouveau_crtc(encoder->crtc)->index; |
| 447 | struct drm_encoder *slave_encoder; | ||
| 447 | 448 | ||
| 448 | if (dcbe->type == OUTPUT_TMDS) | 449 | if (dcbe->type == OUTPUT_TMDS) |
| 449 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); | 450 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); |
| @@ -462,9 +463,10 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
| 462 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); | 463 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); |
| 463 | 464 | ||
| 464 | /* Init external transmitters */ | 465 | /* Init external transmitters */ |
| 465 | if (get_tmds_slave(encoder)) | 466 | slave_encoder = get_tmds_slave(encoder); |
| 466 | get_slave_funcs(get_tmds_slave(encoder))->mode_set( | 467 | if (slave_encoder) |
| 467 | encoder, &nv_encoder->mode, &nv_encoder->mode); | 468 | get_slave_funcs(slave_encoder)->mode_set( |
| 469 | slave_encoder, &nv_encoder->mode, &nv_encoder->mode); | ||
| 468 | 470 | ||
| 469 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 471 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
| 470 | 472 | ||
| @@ -473,6 +475,27 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
| 473 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | 475 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
| 474 | } | 476 | } |
| 475 | 477 | ||
| 478 | static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) | ||
| 479 | { | ||
| 480 | #ifdef __powerpc__ | ||
| 481 | struct drm_device *dev = encoder->dev; | ||
| 482 | |||
| 483 | /* BIOS scripts usually take care of the backlight, thanks | ||
| 484 | * Apple for your consistency. | ||
| 485 | */ | ||
| 486 | if (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || | ||
| 487 | dev->pci_device == 0x0329) { | ||
| 488 | if (mode == DRM_MODE_DPMS_ON) { | ||
| 489 | nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31); | ||
| 490 | nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 1); | ||
| 491 | } else { | ||
| 492 | nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0); | ||
| 493 | nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 0); | ||
| 494 | } | ||
| 495 | } | ||
| 496 | #endif | ||
| 497 | } | ||
| 498 | |||
| 476 | static inline bool is_powersaving_dpms(int mode) | 499 | static inline bool is_powersaving_dpms(int mode) |
| 477 | { | 500 | { |
| 478 | return (mode != DRM_MODE_DPMS_ON); | 501 | return (mode != DRM_MODE_DPMS_ON); |
| @@ -520,6 +543,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
| 520 | LVDS_PANEL_OFF, 0); | 543 | LVDS_PANEL_OFF, 0); |
| 521 | } | 544 | } |
| 522 | 545 | ||
| 546 | nv04_dfp_update_backlight(encoder, mode); | ||
| 523 | nv04_dfp_update_fp_control(encoder, mode); | 547 | nv04_dfp_update_fp_control(encoder, mode); |
| 524 | 548 | ||
| 525 | if (mode == DRM_MODE_DPMS_ON) | 549 | if (mode == DRM_MODE_DPMS_ON) |
| @@ -543,6 +567,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) | |||
| 543 | NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", | 567 | NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", |
| 544 | mode, nv_encoder->dcb->index); | 568 | mode, nv_encoder->dcb->index); |
| 545 | 569 | ||
| 570 | nv04_dfp_update_backlight(encoder, mode); | ||
| 546 | nv04_dfp_update_fp_control(encoder, mode); | 571 | nv04_dfp_update_fp_control(encoder, mode); |
| 547 | } | 572 | } |
| 548 | 573 | ||
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 44fefb0c7083..13cdc05b7c2d 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c | |||
| @@ -121,10 +121,14 @@ static bool | |||
| 121 | get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) | 121 | get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) |
| 122 | { | 122 | { |
| 123 | /* Zotac FX5200 */ | 123 | /* Zotac FX5200 */ |
| 124 | if (dev->pdev->device == 0x0322 && | 124 | if (nv_match_device(dev, 0x0322, 0x19da, 0x1035) || |
| 125 | dev->pdev->subsystem_vendor == 0x19da && | 125 | nv_match_device(dev, 0x0322, 0x19da, 0x2035)) { |
| 126 | (dev->pdev->subsystem_device == 0x1035 || | 126 | *pin_mask = 0xc; |
| 127 | dev->pdev->subsystem_device == 0x2035)) { | 127 | return false; |
| 128 | } | ||
| 129 | |||
| 130 | /* MSI nForce2 IGP */ | ||
| 131 | if (nv_match_device(dev, 0x01f0, 0x1462, 0x5710)) { | ||
| 128 | *pin_mask = 0xc; | 132 | *pin_mask = 0xc; |
| 129 | return false; | 133 | return false; |
| 130 | } | 134 | } |
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 37c7b48ab24a..91ef93cf1f35 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
| @@ -139,6 +139,8 @@ nv50_instmem_init(struct drm_device *dev) | |||
| 139 | chan->file_priv = (struct drm_file *)-2; | 139 | chan->file_priv = (struct drm_file *)-2; |
| 140 | dev_priv->fifos[0] = dev_priv->fifos[127] = chan; | 140 | dev_priv->fifos[0] = dev_priv->fifos[127] = chan; |
| 141 | 141 | ||
| 142 | INIT_LIST_HEAD(&chan->ramht_refs); | ||
| 143 | |||
| 142 | /* Channel's PRAMIN object + heap */ | 144 | /* Channel's PRAMIN object + heap */ |
| 143 | ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0, | 145 | ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0, |
| 144 | NULL, &chan->ramin); | 146 | NULL, &chan->ramin); |
| @@ -278,7 +280,7 @@ nv50_instmem_init(struct drm_device *dev) | |||
| 278 | /*XXX: incorrect, but needed to make hash func "work" */ | 280 | /*XXX: incorrect, but needed to make hash func "work" */ |
| 279 | dev_priv->ramht_offset = 0x10000; | 281 | dev_priv->ramht_offset = 0x10000; |
| 280 | dev_priv->ramht_bits = 9; | 282 | dev_priv->ramht_bits = 9; |
| 281 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits); | 283 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8; |
| 282 | return 0; | 284 | return 0; |
| 283 | } | 285 | } |
| 284 | 286 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c index 3ab3cdc42173..6b451f864783 100644 --- a/drivers/gpu/drm/nouveau/nvc0_instmem.c +++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c | |||
| @@ -142,14 +142,16 @@ int | |||
| 142 | nvc0_instmem_suspend(struct drm_device *dev) | 142 | nvc0_instmem_suspend(struct drm_device *dev) |
| 143 | { | 143 | { |
| 144 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 144 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 145 | u32 *buf; | ||
| 145 | int i; | 146 | int i; |
| 146 | 147 | ||
| 147 | dev_priv->susres.ramin_copy = vmalloc(65536); | 148 | dev_priv->susres.ramin_copy = vmalloc(65536); |
| 148 | if (!dev_priv->susres.ramin_copy) | 149 | if (!dev_priv->susres.ramin_copy) |
| 149 | return -ENOMEM; | 150 | return -ENOMEM; |
| 151 | buf = dev_priv->susres.ramin_copy; | ||
| 150 | 152 | ||
| 151 | for (i = 0x700000; i < 0x710000; i += 4) | 153 | for (i = 0; i < 65536; i += 4) |
| 152 | dev_priv->susres.ramin_copy[i/4] = nv_rd32(dev, i); | 154 | buf[i/4] = nv_rd32(dev, NV04_PRAMIN + i); |
| 153 | return 0; | 155 | return 0; |
| 154 | } | 156 | } |
| 155 | 157 | ||
| @@ -157,14 +159,15 @@ void | |||
| 157 | nvc0_instmem_resume(struct drm_device *dev) | 159 | nvc0_instmem_resume(struct drm_device *dev) |
| 158 | { | 160 | { |
| 159 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 161 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 162 | u32 *buf = dev_priv->susres.ramin_copy; | ||
| 160 | u64 chan; | 163 | u64 chan; |
| 161 | int i; | 164 | int i; |
| 162 | 165 | ||
| 163 | chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; | 166 | chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; |
| 164 | nv_wr32(dev, 0x001700, chan >> 16); | 167 | nv_wr32(dev, 0x001700, chan >> 16); |
| 165 | 168 | ||
| 166 | for (i = 0x700000; i < 0x710000; i += 4) | 169 | for (i = 0; i < 65536; i += 4) |
| 167 | nv_wr32(dev, i, dev_priv->susres.ramin_copy[i/4]); | 170 | nv_wr32(dev, NV04_PRAMIN + i, buf[i/4]); |
| 168 | vfree(dev_priv->susres.ramin_copy); | 171 | vfree(dev_priv->susres.ramin_copy); |
| 169 | dev_priv->susres.ramin_copy = NULL; | 172 | dev_priv->susres.ramin_copy = NULL; |
| 170 | 173 | ||
| @@ -221,7 +224,7 @@ nvc0_instmem_init(struct drm_device *dev) | |||
| 221 | /*XXX: incorrect, but needed to make hash func "work" */ | 224 | /*XXX: incorrect, but needed to make hash func "work" */ |
| 222 | dev_priv->ramht_offset = 0x10000; | 225 | dev_priv->ramht_offset = 0x10000; |
| 223 | dev_priv->ramht_bits = 9; | 226 | dev_priv->ramht_bits = 9; |
| 224 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits); | 227 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8; |
| 225 | return 0; | 228 | return 0; |
| 226 | } | 229 | } |
| 227 | 230 | ||
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c index 077af1f2f9b4..a9e33ce65918 100644 --- a/drivers/gpu/drm/r128/r128_state.c +++ b/drivers/gpu/drm/r128/r128_state.c | |||
| @@ -1639,30 +1639,29 @@ void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) | |||
| 1639 | r128_do_cleanup_pageflip(dev); | 1639 | r128_do_cleanup_pageflip(dev); |
| 1640 | } | 1640 | } |
| 1641 | } | 1641 | } |
| 1642 | |||
| 1643 | void r128_driver_lastclose(struct drm_device *dev) | 1642 | void r128_driver_lastclose(struct drm_device *dev) |
| 1644 | { | 1643 | { |
| 1645 | r128_do_cleanup_cce(dev); | 1644 | r128_do_cleanup_cce(dev); |
| 1646 | } | 1645 | } |
| 1647 | 1646 | ||
| 1648 | struct drm_ioctl_desc r128_ioctls[] = { | 1647 | struct drm_ioctl_desc r128_ioctls[] = { |
| 1649 | DRM_IOCTL_DEF(DRM_R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1648 | DRM_IOCTL_DEF_DRV(R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1650 | DRM_IOCTL_DEF(DRM_R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1649 | DRM_IOCTL_DEF_DRV(R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1651 | DRM_IOCTL_DEF(DRM_R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1650 | DRM_IOCTL_DEF_DRV(R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1652 | DRM_IOCTL_DEF(DRM_R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1651 | DRM_IOCTL_DEF_DRV(R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1653 | DRM_IOCTL_DEF(DRM_R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), | 1652 | DRM_IOCTL_DEF_DRV(R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), |
| 1654 | DRM_IOCTL_DEF(DRM_R128_RESET, r128_engine_reset, DRM_AUTH), | 1653 | DRM_IOCTL_DEF_DRV(R128_RESET, r128_engine_reset, DRM_AUTH), |
| 1655 | DRM_IOCTL_DEF(DRM_R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), | 1654 | DRM_IOCTL_DEF_DRV(R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), |
| 1656 | DRM_IOCTL_DEF(DRM_R128_SWAP, r128_cce_swap, DRM_AUTH), | 1655 | DRM_IOCTL_DEF_DRV(R128_SWAP, r128_cce_swap, DRM_AUTH), |
| 1657 | DRM_IOCTL_DEF(DRM_R128_FLIP, r128_cce_flip, DRM_AUTH), | 1656 | DRM_IOCTL_DEF_DRV(R128_FLIP, r128_cce_flip, DRM_AUTH), |
| 1658 | DRM_IOCTL_DEF(DRM_R128_CLEAR, r128_cce_clear, DRM_AUTH), | 1657 | DRM_IOCTL_DEF_DRV(R128_CLEAR, r128_cce_clear, DRM_AUTH), |
| 1659 | DRM_IOCTL_DEF(DRM_R128_VERTEX, r128_cce_vertex, DRM_AUTH), | 1658 | DRM_IOCTL_DEF_DRV(R128_VERTEX, r128_cce_vertex, DRM_AUTH), |
| 1660 | DRM_IOCTL_DEF(DRM_R128_INDICES, r128_cce_indices, DRM_AUTH), | 1659 | DRM_IOCTL_DEF_DRV(R128_INDICES, r128_cce_indices, DRM_AUTH), |
| 1661 | DRM_IOCTL_DEF(DRM_R128_BLIT, r128_cce_blit, DRM_AUTH), | 1660 | DRM_IOCTL_DEF_DRV(R128_BLIT, r128_cce_blit, DRM_AUTH), |
| 1662 | DRM_IOCTL_DEF(DRM_R128_DEPTH, r128_cce_depth, DRM_AUTH), | 1661 | DRM_IOCTL_DEF_DRV(R128_DEPTH, r128_cce_depth, DRM_AUTH), |
| 1663 | DRM_IOCTL_DEF(DRM_R128_STIPPLE, r128_cce_stipple, DRM_AUTH), | 1662 | DRM_IOCTL_DEF_DRV(R128_STIPPLE, r128_cce_stipple, DRM_AUTH), |
| 1664 | DRM_IOCTL_DEF(DRM_R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1663 | DRM_IOCTL_DEF_DRV(R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1665 | DRM_IOCTL_DEF(DRM_R128_GETPARAM, r128_getparam, DRM_AUTH), | 1664 | DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH), |
| 1666 | }; | 1665 | }; |
| 1667 | 1666 | ||
| 1668 | int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); | 1667 | int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 1bc72c3190a9..fe359a239df3 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
| @@ -4999,7 +4999,7 @@ typedef struct _SW_I2C_IO_DATA_PARAMETERS | |||
| 4999 | #define SW_I2C_CNTL_WRITE1BIT 6 | 4999 | #define SW_I2C_CNTL_WRITE1BIT 6 |
| 5000 | 5000 | ||
| 5001 | //==============================VESA definition Portion=============================== | 5001 | //==============================VESA definition Portion=============================== |
| 5002 | #define VESA_OEM_PRODUCT_REV '01.00' | 5002 | #define VESA_OEM_PRODUCT_REV "01.00" |
| 5003 | #define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB //refer to VBE spec p.32, no TTY support | 5003 | #define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB //refer to VBE spec p.32, no TTY support |
| 5004 | #define VESA_MODE_WIN_ATTRIBUTE 7 | 5004 | #define VESA_MODE_WIN_ATTRIBUTE 7 |
| 5005 | #define VESA_WIN_SIZE 64 | 5005 | #define VESA_WIN_SIZE 64 |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 12ad512bd3d3..cd0290f946cf 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -332,6 +332,11 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, | |||
| 332 | args.usV_SyncWidth = | 332 | args.usV_SyncWidth = |
| 333 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); | 333 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
| 334 | 334 | ||
| 335 | args.ucOverscanRight = radeon_crtc->h_border; | ||
| 336 | args.ucOverscanLeft = radeon_crtc->h_border; | ||
| 337 | args.ucOverscanBottom = radeon_crtc->v_border; | ||
| 338 | args.ucOverscanTop = radeon_crtc->v_border; | ||
| 339 | |||
| 335 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | 340 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
| 336 | misc |= ATOM_VSYNC_POLARITY; | 341 | misc |= ATOM_VSYNC_POLARITY; |
| 337 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | 342 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
| @@ -471,6 +476,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 471 | struct radeon_encoder *radeon_encoder = NULL; | 476 | struct radeon_encoder *radeon_encoder = NULL; |
| 472 | u32 adjusted_clock = mode->clock; | 477 | u32 adjusted_clock = mode->clock; |
| 473 | int encoder_mode = 0; | 478 | int encoder_mode = 0; |
| 479 | u32 dp_clock = mode->clock; | ||
| 480 | int bpc = 8; | ||
| 474 | 481 | ||
| 475 | /* reset the pll flags */ | 482 | /* reset the pll flags */ |
| 476 | pll->flags = 0; | 483 | pll->flags = 0; |
| @@ -513,6 +520,17 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 513 | if (encoder->crtc == crtc) { | 520 | if (encoder->crtc == crtc) { |
| 514 | radeon_encoder = to_radeon_encoder(encoder); | 521 | radeon_encoder = to_radeon_encoder(encoder); |
| 515 | encoder_mode = atombios_get_encoder_mode(encoder); | 522 | encoder_mode = atombios_get_encoder_mode(encoder); |
| 523 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { | ||
| 524 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 525 | if (connector) { | ||
| 526 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 527 | struct radeon_connector_atom_dig *dig_connector = | ||
| 528 | radeon_connector->con_priv; | ||
| 529 | |||
| 530 | dp_clock = dig_connector->dp_clock; | ||
| 531 | } | ||
| 532 | } | ||
| 533 | |||
| 516 | if (ASIC_IS_AVIVO(rdev)) { | 534 | if (ASIC_IS_AVIVO(rdev)) { |
| 517 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 535 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
| 518 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 536 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
| @@ -521,6 +539,21 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 521 | pll->algo = PLL_ALGO_LEGACY; | 539 | pll->algo = PLL_ALGO_LEGACY; |
| 522 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; | 540 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; |
| 523 | } | 541 | } |
| 542 | /* There is some evidence (often anecdotal) that RV515/RV620 LVDS | ||
| 543 | * (on some boards at least) prefers the legacy algo. I'm not | ||
| 544 | * sure whether this should handled generically or on a | ||
| 545 | * case-by-case quirk basis. Both algos should work fine in the | ||
| 546 | * majority of cases. | ||
| 547 | */ | ||
| 548 | if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) && | ||
| 549 | ((rdev->family == CHIP_RV515) || | ||
| 550 | (rdev->family == CHIP_RV620))) { | ||
| 551 | /* allow the user to overrride just in case */ | ||
| 552 | if (radeon_new_pll == 1) | ||
| 553 | pll->algo = PLL_ALGO_NEW; | ||
| 554 | else | ||
| 555 | pll->algo = PLL_ALGO_LEGACY; | ||
| 556 | } | ||
| 524 | } else { | 557 | } else { |
| 525 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | 558 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
| 526 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; | 559 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; |
| @@ -555,6 +588,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 555 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | 588 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
| 556 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; | 589 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; |
| 557 | args.v1.ucEncodeMode = encoder_mode; | 590 | args.v1.ucEncodeMode = encoder_mode; |
| 591 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { | ||
| 592 | /* may want to enable SS on DP eventually */ | ||
| 593 | /* args.v1.ucConfig |= | ||
| 594 | ADJUST_DISPLAY_CONFIG_SS_ENABLE;*/ | ||
| 595 | } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { | ||
| 596 | args.v1.ucConfig |= | ||
| 597 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; | ||
| 598 | } | ||
| 558 | 599 | ||
| 559 | atom_execute_table(rdev->mode_info.atom_context, | 600 | atom_execute_table(rdev->mode_info.atom_context, |
| 560 | index, (uint32_t *)&args); | 601 | index, (uint32_t *)&args); |
| @@ -568,10 +609,20 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 568 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 609 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
| 569 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 610 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 570 | 611 | ||
| 571 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | 612 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
| 613 | /* may want to enable SS on DP/eDP eventually */ | ||
| 614 | /*args.v3.sInput.ucDispPllConfig |= | ||
| 615 | DISPPLL_CONFIG_SS_ENABLE;*/ | ||
| 572 | args.v3.sInput.ucDispPllConfig |= | 616 | args.v3.sInput.ucDispPllConfig |= |
| 573 | DISPPLL_CONFIG_COHERENT_MODE; | 617 | DISPPLL_CONFIG_COHERENT_MODE; |
| 574 | else { | 618 | /* 16200 or 27000 */ |
| 619 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
| 620 | } else { | ||
| 621 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) { | ||
| 622 | /* deep color support */ | ||
| 623 | args.v3.sInput.usPixelClock = | ||
| 624 | cpu_to_le16((mode->clock * bpc / 8) / 10); | ||
| 625 | } | ||
| 575 | if (dig->coherent_mode) | 626 | if (dig->coherent_mode) |
| 576 | args.v3.sInput.ucDispPllConfig |= | 627 | args.v3.sInput.ucDispPllConfig |= |
| 577 | DISPPLL_CONFIG_COHERENT_MODE; | 628 | DISPPLL_CONFIG_COHERENT_MODE; |
| @@ -580,13 +631,19 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 580 | DISPPLL_CONFIG_DUAL_LINK; | 631 | DISPPLL_CONFIG_DUAL_LINK; |
| 581 | } | 632 | } |
| 582 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 633 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
| 583 | /* may want to enable SS on DP/eDP eventually */ | 634 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
| 584 | /*args.v3.sInput.ucDispPllConfig |= | 635 | /* may want to enable SS on DP/eDP eventually */ |
| 585 | DISPPLL_CONFIG_SS_ENABLE;*/ | 636 | /*args.v3.sInput.ucDispPllConfig |= |
| 586 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | 637 | DISPPLL_CONFIG_SS_ENABLE;*/ |
| 587 | args.v3.sInput.ucDispPllConfig |= | 638 | args.v3.sInput.ucDispPllConfig |= |
| 588 | DISPPLL_CONFIG_COHERENT_MODE; | 639 | DISPPLL_CONFIG_COHERENT_MODE; |
| 589 | else { | 640 | /* 16200 or 27000 */ |
| 641 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
| 642 | } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { | ||
| 643 | /* want to enable SS on LVDS eventually */ | ||
| 644 | /*args.v3.sInput.ucDispPllConfig |= | ||
| 645 | DISPPLL_CONFIG_SS_ENABLE;*/ | ||
| 646 | } else { | ||
| 590 | if (mode->clock > 165000) | 647 | if (mode->clock > 165000) |
| 591 | args.v3.sInput.ucDispPllConfig |= | 648 | args.v3.sInput.ucDispPllConfig |= |
| 592 | DISPPLL_CONFIG_DUAL_LINK; | 649 | DISPPLL_CONFIG_DUAL_LINK; |
| @@ -1019,11 +1076,11 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 1019 | 1076 | ||
| 1020 | if (rdev->family >= CHIP_RV770) { | 1077 | if (rdev->family >= CHIP_RV770) { |
| 1021 | if (radeon_crtc->crtc_id) { | 1078 | if (radeon_crtc->crtc_id) { |
| 1022 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | 1079 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
| 1023 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | 1080 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
| 1024 | } else { | 1081 | } else { |
| 1025 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | 1082 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
| 1026 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | 1083 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
| 1027 | } | 1084 | } |
| 1028 | } | 1085 | } |
| 1029 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | 1086 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
| @@ -1160,8 +1217,18 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
| 1160 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1217 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 1161 | struct drm_device *dev = crtc->dev; | 1218 | struct drm_device *dev = crtc->dev; |
| 1162 | struct radeon_device *rdev = dev->dev_private; | 1219 | struct radeon_device *rdev = dev->dev_private; |
| 1220 | struct drm_encoder *encoder; | ||
| 1221 | bool is_tvcv = false; | ||
| 1163 | 1222 | ||
| 1164 | /* TODO color tiling */ | 1223 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 1224 | /* find tv std */ | ||
| 1225 | if (encoder->crtc == crtc) { | ||
| 1226 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 1227 | if (radeon_encoder->active_device & | ||
| 1228 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
| 1229 | is_tvcv = true; | ||
| 1230 | } | ||
| 1231 | } | ||
| 1165 | 1232 | ||
| 1166 | atombios_disable_ss(crtc); | 1233 | atombios_disable_ss(crtc); |
| 1167 | /* always set DCPLL */ | 1234 | /* always set DCPLL */ |
| @@ -1170,9 +1237,14 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
| 1170 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1237 | atombios_crtc_set_pll(crtc, adjusted_mode); |
| 1171 | atombios_enable_ss(crtc); | 1238 | atombios_enable_ss(crtc); |
| 1172 | 1239 | ||
| 1173 | if (ASIC_IS_AVIVO(rdev)) | 1240 | if (ASIC_IS_DCE4(rdev)) |
| 1174 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1241 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
| 1175 | else { | 1242 | else if (ASIC_IS_AVIVO(rdev)) { |
| 1243 | if (is_tvcv) | ||
| 1244 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
| 1245 | else | ||
| 1246 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | ||
| 1247 | } else { | ||
| 1176 | atombios_crtc_set_timing(crtc, adjusted_mode); | 1248 | atombios_crtc_set_timing(crtc, adjusted_mode); |
| 1177 | if (radeon_crtc->crtc_id == 0) | 1249 | if (radeon_crtc->crtc_id == 0) |
| 1178 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1250 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 36e0d4b545e6..4e7778d44b8d 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
| @@ -610,7 +610,7 @@ void dp_link_train(struct drm_encoder *encoder, | |||
| 610 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; | 610 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; |
| 611 | else | 611 | else |
| 612 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; | 612 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; |
| 613 | if (dig_connector->linkb) | 613 | if (dig->linkb) |
| 614 | enc_id |= ATOM_DP_CONFIG_LINK_B; | 614 | enc_id |= ATOM_DP_CONFIG_LINK_B; |
| 615 | else | 615 | else |
| 616 | enc_id |= ATOM_DP_CONFIG_LINK_A; | 616 | enc_id |= ATOM_DP_CONFIG_LINK_A; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 957d5067ad9c..79082d4398ae 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -675,6 +675,43 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) | |||
| 675 | return 0; | 675 | return 0; |
| 676 | } | 676 | } |
| 677 | 677 | ||
| 678 | static int evergreen_cp_start(struct radeon_device *rdev) | ||
| 679 | { | ||
| 680 | int r; | ||
| 681 | uint32_t cp_me; | ||
| 682 | |||
| 683 | r = radeon_ring_lock(rdev, 7); | ||
| 684 | if (r) { | ||
| 685 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | ||
| 686 | return r; | ||
| 687 | } | ||
| 688 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); | ||
| 689 | radeon_ring_write(rdev, 0x1); | ||
| 690 | radeon_ring_write(rdev, 0x0); | ||
| 691 | radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1); | ||
| 692 | radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); | ||
| 693 | radeon_ring_write(rdev, 0); | ||
| 694 | radeon_ring_write(rdev, 0); | ||
| 695 | radeon_ring_unlock_commit(rdev); | ||
| 696 | |||
| 697 | cp_me = 0xff; | ||
| 698 | WREG32(CP_ME_CNTL, cp_me); | ||
| 699 | |||
| 700 | r = radeon_ring_lock(rdev, 4); | ||
| 701 | if (r) { | ||
| 702 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | ||
| 703 | return r; | ||
| 704 | } | ||
| 705 | /* init some VGT regs */ | ||
| 706 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); | ||
| 707 | radeon_ring_write(rdev, (VGT_VERTEX_REUSE_BLOCK_CNTL - PACKET3_SET_CONTEXT_REG_START) >> 2); | ||
| 708 | radeon_ring_write(rdev, 0xe); | ||
| 709 | radeon_ring_write(rdev, 0x10); | ||
| 710 | radeon_ring_unlock_commit(rdev); | ||
| 711 | |||
| 712 | return 0; | ||
| 713 | } | ||
| 714 | |||
| 678 | int evergreen_cp_resume(struct radeon_device *rdev) | 715 | int evergreen_cp_resume(struct radeon_device *rdev) |
| 679 | { | 716 | { |
| 680 | u32 tmp; | 717 | u32 tmp; |
| @@ -719,7 +756,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
| 719 | rdev->cp.rptr = RREG32(CP_RB_RPTR); | 756 | rdev->cp.rptr = RREG32(CP_RB_RPTR); |
| 720 | rdev->cp.wptr = RREG32(CP_RB_WPTR); | 757 | rdev->cp.wptr = RREG32(CP_RB_WPTR); |
| 721 | 758 | ||
| 722 | r600_cp_start(rdev); | 759 | evergreen_cp_start(rdev); |
| 723 | rdev->cp.ready = true; | 760 | rdev->cp.ready = true; |
| 724 | r = radeon_ring_test(rdev); | 761 | r = radeon_ring_test(rdev); |
| 725 | if (r) { | 762 | if (r) { |
| @@ -1123,14 +1160,25 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 1123 | EVERGREEN_MAX_BACKENDS_MASK)); | 1160 | EVERGREEN_MAX_BACKENDS_MASK)); |
| 1124 | break; | 1161 | break; |
| 1125 | } | 1162 | } |
| 1126 | } else | 1163 | } else { |
| 1127 | gb_backend_map = | 1164 | switch (rdev->family) { |
| 1128 | evergreen_get_tile_pipe_to_backend_map(rdev, | 1165 | case CHIP_CYPRESS: |
| 1129 | rdev->config.evergreen.max_tile_pipes, | 1166 | case CHIP_HEMLOCK: |
| 1130 | rdev->config.evergreen.max_backends, | 1167 | gb_backend_map = 0x66442200; |
| 1131 | ((EVERGREEN_MAX_BACKENDS_MASK << | 1168 | break; |
| 1132 | rdev->config.evergreen.max_backends) & | 1169 | case CHIP_JUNIPER: |
| 1133 | EVERGREEN_MAX_BACKENDS_MASK)); | 1170 | gb_backend_map = 0x00006420; |
| 1171 | break; | ||
| 1172 | default: | ||
| 1173 | gb_backend_map = | ||
| 1174 | evergreen_get_tile_pipe_to_backend_map(rdev, | ||
| 1175 | rdev->config.evergreen.max_tile_pipes, | ||
| 1176 | rdev->config.evergreen.max_backends, | ||
| 1177 | ((EVERGREEN_MAX_BACKENDS_MASK << | ||
| 1178 | rdev->config.evergreen.max_backends) & | ||
| 1179 | EVERGREEN_MAX_BACKENDS_MASK)); | ||
| 1180 | } | ||
| 1181 | } | ||
| 1134 | 1182 | ||
| 1135 | rdev->config.evergreen.tile_config = gb_addr_config; | 1183 | rdev->config.evergreen.tile_config = gb_addr_config; |
| 1136 | WREG32(GB_BACKEND_MAP, gb_backend_map); | 1184 | WREG32(GB_BACKEND_MAP, gb_backend_map); |
| @@ -2054,11 +2102,6 @@ int evergreen_resume(struct radeon_device *rdev) | |||
| 2054 | */ | 2102 | */ |
| 2055 | /* post card */ | 2103 | /* post card */ |
| 2056 | atom_asic_init(rdev->mode_info.atom_context); | 2104 | atom_asic_init(rdev->mode_info.atom_context); |
| 2057 | /* Initialize clocks */ | ||
| 2058 | r = radeon_clocks_init(rdev); | ||
| 2059 | if (r) { | ||
| 2060 | return r; | ||
| 2061 | } | ||
| 2062 | 2105 | ||
| 2063 | r = evergreen_startup(rdev); | 2106 | r = evergreen_startup(rdev); |
| 2064 | if (r) { | 2107 | if (r) { |
| @@ -2164,9 +2207,6 @@ int evergreen_init(struct radeon_device *rdev) | |||
| 2164 | radeon_surface_init(rdev); | 2207 | radeon_surface_init(rdev); |
| 2165 | /* Initialize clocks */ | 2208 | /* Initialize clocks */ |
| 2166 | radeon_get_clock_info(rdev->ddev); | 2209 | radeon_get_clock_info(rdev->ddev); |
| 2167 | r = radeon_clocks_init(rdev); | ||
| 2168 | if (r) | ||
| 2169 | return r; | ||
| 2170 | /* Fence driver */ | 2210 | /* Fence driver */ |
| 2171 | r = radeon_fence_driver_init(rdev); | 2211 | r = radeon_fence_driver_init(rdev); |
| 2172 | if (r) | 2212 | if (r) |
| @@ -2236,7 +2276,6 @@ void evergreen_fini(struct radeon_device *rdev) | |||
| 2236 | evergreen_pcie_gart_fini(rdev); | 2276 | evergreen_pcie_gart_fini(rdev); |
| 2237 | radeon_gem_fini(rdev); | 2277 | radeon_gem_fini(rdev); |
| 2238 | radeon_fence_driver_fini(rdev); | 2278 | radeon_fence_driver_fini(rdev); |
| 2239 | radeon_clocks_fini(rdev); | ||
| 2240 | radeon_agp_fini(rdev); | 2279 | radeon_agp_fini(rdev); |
| 2241 | radeon_bo_fini(rdev); | 2280 | radeon_bo_fini(rdev); |
| 2242 | radeon_atombios_fini(rdev); | 2281 | radeon_atombios_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e817a0bb5eb4..e151f16a8f86 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -2020,18 +2020,7 @@ bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *l | |||
| 2020 | return false; | 2020 | return false; |
| 2021 | } | 2021 | } |
| 2022 | elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); | 2022 | elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); |
| 2023 | if (elapsed >= 3000) { | 2023 | if (elapsed >= 10000) { |
| 2024 | /* very likely the improbable case where current | ||
| 2025 | * rptr is equal to last recorded, a while ago, rptr | ||
| 2026 | * this is more likely a false positive update tracking | ||
| 2027 | * information which should force us to be recall at | ||
| 2028 | * latter point | ||
| 2029 | */ | ||
| 2030 | lockup->last_cp_rptr = cp->rptr; | ||
| 2031 | lockup->last_jiffies = jiffies; | ||
| 2032 | return false; | ||
| 2033 | } | ||
| 2034 | if (elapsed >= 1000) { | ||
| 2035 | dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); | 2024 | dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); |
| 2036 | return true; | 2025 | return true; |
| 2037 | } | 2026 | } |
| @@ -3308,13 +3297,14 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
| 3308 | unsigned long size; | 3297 | unsigned long size; |
| 3309 | unsigned prim_walk; | 3298 | unsigned prim_walk; |
| 3310 | unsigned nverts; | 3299 | unsigned nverts; |
| 3300 | unsigned num_cb = track->num_cb; | ||
| 3311 | 3301 | ||
| 3312 | for (i = 0; i < track->num_cb; i++) { | 3302 | if (!track->zb_cb_clear && !track->color_channel_mask && |
| 3303 | !track->blend_read_enable) | ||
| 3304 | num_cb = 0; | ||
| 3305 | |||
| 3306 | for (i = 0; i < num_cb; i++) { | ||
| 3313 | if (track->cb[i].robj == NULL) { | 3307 | if (track->cb[i].robj == NULL) { |
| 3314 | if (!(track->zb_cb_clear || track->color_channel_mask || | ||
| 3315 | track->blend_read_enable)) { | ||
| 3316 | continue; | ||
| 3317 | } | ||
| 3318 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); | 3308 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); |
| 3319 | return -EINVAL; | 3309 | return -EINVAL; |
| 3320 | } | 3310 | } |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index d0ebae9dde25..7a04959ba0ee 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -2119,10 +2119,7 @@ int r600_cp_start(struct radeon_device *rdev) | |||
| 2119 | } | 2119 | } |
| 2120 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); | 2120 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); |
| 2121 | radeon_ring_write(rdev, 0x1); | 2121 | radeon_ring_write(rdev, 0x1); |
| 2122 | if (rdev->family >= CHIP_CEDAR) { | 2122 | if (rdev->family >= CHIP_RV770) { |
| 2123 | radeon_ring_write(rdev, 0x0); | ||
| 2124 | radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1); | ||
| 2125 | } else if (rdev->family >= CHIP_RV770) { | ||
| 2126 | radeon_ring_write(rdev, 0x0); | 2123 | radeon_ring_write(rdev, 0x0); |
| 2127 | radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1); | 2124 | radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1); |
| 2128 | } else { | 2125 | } else { |
| @@ -2489,11 +2486,6 @@ int r600_resume(struct radeon_device *rdev) | |||
| 2489 | */ | 2486 | */ |
| 2490 | /* post card */ | 2487 | /* post card */ |
| 2491 | atom_asic_init(rdev->mode_info.atom_context); | 2488 | atom_asic_init(rdev->mode_info.atom_context); |
| 2492 | /* Initialize clocks */ | ||
| 2493 | r = radeon_clocks_init(rdev); | ||
| 2494 | if (r) { | ||
| 2495 | return r; | ||
| 2496 | } | ||
| 2497 | 2489 | ||
| 2498 | r = r600_startup(rdev); | 2490 | r = r600_startup(rdev); |
| 2499 | if (r) { | 2491 | if (r) { |
| @@ -2586,9 +2578,6 @@ int r600_init(struct radeon_device *rdev) | |||
| 2586 | radeon_surface_init(rdev); | 2578 | radeon_surface_init(rdev); |
| 2587 | /* Initialize clocks */ | 2579 | /* Initialize clocks */ |
| 2588 | radeon_get_clock_info(rdev->ddev); | 2580 | radeon_get_clock_info(rdev->ddev); |
| 2589 | r = radeon_clocks_init(rdev); | ||
| 2590 | if (r) | ||
| 2591 | return r; | ||
| 2592 | /* Fence driver */ | 2581 | /* Fence driver */ |
| 2593 | r = radeon_fence_driver_init(rdev); | 2582 | r = radeon_fence_driver_init(rdev); |
| 2594 | if (r) | 2583 | if (r) |
| @@ -2663,7 +2652,6 @@ void r600_fini(struct radeon_device *rdev) | |||
| 2663 | radeon_agp_fini(rdev); | 2652 | radeon_agp_fini(rdev); |
| 2664 | radeon_gem_fini(rdev); | 2653 | radeon_gem_fini(rdev); |
| 2665 | radeon_fence_driver_fini(rdev); | 2654 | radeon_fence_driver_fini(rdev); |
| 2666 | radeon_clocks_fini(rdev); | ||
| 2667 | radeon_bo_fini(rdev); | 2655 | radeon_bo_fini(rdev); |
| 2668 | radeon_atombios_fini(rdev); | 2656 | radeon_atombios_fini(rdev); |
| 2669 | kfree(rdev->bios); | 2657 | kfree(rdev->bios); |
| @@ -2741,7 +2729,7 @@ int r600_ib_test(struct radeon_device *rdev) | |||
| 2741 | if (i < rdev->usec_timeout) { | 2729 | if (i < rdev->usec_timeout) { |
| 2742 | DRM_INFO("ib test succeeded in %u usecs\n", i); | 2730 | DRM_INFO("ib test succeeded in %u usecs\n", i); |
| 2743 | } else { | 2731 | } else { |
| 2744 | DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n", | 2732 | DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", |
| 2745 | scratch, tmp); | 2733 | scratch, tmp); |
| 2746 | r = -EINVAL; | 2734 | r = -EINVAL; |
| 2747 | } | 2735 | } |
| @@ -3540,8 +3528,9 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | |||
| 3540 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 3528 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
| 3541 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 3529 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL |
| 3542 | */ | 3530 | */ |
| 3543 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | 3531 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
| 3544 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 3532 | rdev->vram_scratch.ptr) { |
| 3533 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | ||
| 3545 | u32 tmp; | 3534 | u32 tmp; |
| 3546 | 3535 | ||
| 3547 | WREG32(HDP_DEBUG1, 0); | 3536 | WREG32(HDP_DEBUG1, 0); |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index d13622ae74e9..9ceb2a1ce799 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
| @@ -1,3 +1,28 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2009 Advanced Micro Devices, Inc. | ||
| 3 | * Copyright 2009 Red Hat Inc. | ||
| 4 | * | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 6 | * copy of this software and associated documentation files (the "Software"), | ||
| 7 | * to deal in the Software without restriction, including without limitation | ||
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 10 | * Software is furnished to do so, subject to the following conditions: | ||
| 11 | * | ||
| 12 | * The above copyright notice and this permission notice (including the next | ||
| 13 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 14 | * Software. | ||
| 15 | * | ||
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 19 | * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 22 | * DEALINGS IN THE SOFTWARE. | ||
| 23 | * | ||
| 24 | */ | ||
| 25 | |||
| 1 | #include "drmP.h" | 26 | #include "drmP.h" |
| 2 | #include "drm.h" | 27 | #include "drm.h" |
| 3 | #include "radeon_drm.h" | 28 | #include "radeon_drm.h" |
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.h b/drivers/gpu/drm/radeon/r600_blit_shaders.h index fdc3b378cbb0..f437d36dd98c 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.h +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.h | |||
| @@ -1,3 +1,27 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2009 Advanced Micro Devices, Inc. | ||
| 3 | * Copyright 2009 Red Hat Inc. | ||
| 4 | * | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 6 | * copy of this software and associated documentation files (the "Software"), | ||
| 7 | * to deal in the Software without restriction, including without limitation | ||
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 10 | * Software is furnished to do so, subject to the following conditions: | ||
| 11 | * | ||
| 12 | * The above copyright notice and this permission notice (including the next | ||
| 13 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 14 | * Software. | ||
| 15 | * | ||
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 19 | * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 22 | * DEALINGS IN THE SOFTWARE. | ||
| 23 | * | ||
| 24 | */ | ||
| 1 | 25 | ||
| 2 | #ifndef R600_BLIT_SHADERS_H | 26 | #ifndef R600_BLIT_SHADERS_H |
| 3 | #define R600_BLIT_SHADERS_H | 27 | #define R600_BLIT_SHADERS_H |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index d8864949e387..250a3a918193 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
| @@ -1170,9 +1170,8 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i | |||
| 1170 | /* using get ib will give us the offset into the mipmap bo */ | 1170 | /* using get ib will give us the offset into the mipmap bo */ |
| 1171 | word0 = radeon_get_ib_value(p, idx + 3) << 8; | 1171 | word0 = radeon_get_ib_value(p, idx + 3) << 8; |
| 1172 | if ((mipmap_size + word0) > radeon_bo_size(mipmap)) { | 1172 | if ((mipmap_size + word0) > radeon_bo_size(mipmap)) { |
| 1173 | dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", | 1173 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", |
| 1174 | w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture)); | 1174 | w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));*/ |
| 1175 | return -EINVAL; | ||
| 1176 | } | 1175 | } |
| 1177 | return 0; | 1176 | return 0; |
| 1178 | } | 1177 | } |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3dfcfa3ca425..a168d644bf9e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -1013,6 +1013,11 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
| 1013 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, | 1013 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, |
| 1014 | struct drm_file *filp); | 1014 | struct drm_file *filp); |
| 1015 | 1015 | ||
| 1016 | /* VRAM scratch page for HDP bug */ | ||
| 1017 | struct r700_vram_scratch { | ||
| 1018 | struct radeon_bo *robj; | ||
| 1019 | volatile uint32_t *ptr; | ||
| 1020 | }; | ||
| 1016 | 1021 | ||
| 1017 | /* | 1022 | /* |
| 1018 | * Core structure, functions and helpers. | 1023 | * Core structure, functions and helpers. |
| @@ -1079,6 +1084,7 @@ struct radeon_device { | |||
| 1079 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ | 1084 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ |
| 1080 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ | 1085 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ |
| 1081 | struct r600_blit r600_blit; | 1086 | struct r600_blit r600_blit; |
| 1087 | struct r700_vram_scratch vram_scratch; | ||
| 1082 | int msi_enabled; /* msi enabled */ | 1088 | int msi_enabled; /* msi enabled */ |
| 1083 | struct r600_ih ih; /* r6/700 interrupt ring */ | 1089 | struct r600_ih ih; /* r6/700 interrupt ring */ |
| 1084 | struct workqueue_struct *wq; | 1090 | struct workqueue_struct *wq; |
| @@ -1333,8 +1339,6 @@ extern bool radeon_card_posted(struct radeon_device *rdev); | |||
| 1333 | extern void radeon_update_bandwidth_info(struct radeon_device *rdev); | 1339 | extern void radeon_update_bandwidth_info(struct radeon_device *rdev); |
| 1334 | extern void radeon_update_display_priority(struct radeon_device *rdev); | 1340 | extern void radeon_update_display_priority(struct radeon_device *rdev); |
| 1335 | extern bool radeon_boot_test_post_card(struct radeon_device *rdev); | 1341 | extern bool radeon_boot_test_post_card(struct radeon_device *rdev); |
| 1336 | extern int radeon_clocks_init(struct radeon_device *rdev); | ||
| 1337 | extern void radeon_clocks_fini(struct radeon_device *rdev); | ||
| 1338 | extern void radeon_scratch_init(struct radeon_device *rdev); | 1342 | extern void radeon_scratch_init(struct radeon_device *rdev); |
| 1339 | extern void radeon_surface_init(struct radeon_device *rdev); | 1343 | extern void radeon_surface_init(struct radeon_device *rdev); |
| 1340 | extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); | 1344 | extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index f40dfb77f9b1..bd2f33e5c91a 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
| @@ -156,7 +156,13 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | mode.mode = info.mode; | 158 | mode.mode = info.mode; |
| 159 | agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; | 159 | /* chips with the agp to pcie bridge don't have the AGP_STATUS register |
| 160 | * Just use the whatever mode the host sets up. | ||
| 161 | */ | ||
| 162 | if (rdev->family <= CHIP_RV350) | ||
| 163 | agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; | ||
| 164 | else | ||
| 165 | agp_status = mode.mode; | ||
| 160 | is_v3 = !!(agp_status & RADEON_AGPv3_MODE); | 166 | is_v3 = !!(agp_status & RADEON_AGPv3_MODE); |
| 161 | 167 | ||
| 162 | if (is_v3) { | 168 | if (is_v3) { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 646f96f97c77..25e1dd197791 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
| @@ -733,6 +733,7 @@ static struct radeon_asic evergreen_asic = { | |||
| 733 | .set_engine_clock = &radeon_atom_set_engine_clock, | 733 | .set_engine_clock = &radeon_atom_set_engine_clock, |
| 734 | .get_memory_clock = &radeon_atom_get_memory_clock, | 734 | .get_memory_clock = &radeon_atom_get_memory_clock, |
| 735 | .set_memory_clock = &radeon_atom_set_memory_clock, | 735 | .set_memory_clock = &radeon_atom_set_memory_clock, |
| 736 | .get_pcie_lanes = NULL, | ||
| 736 | .set_pcie_lanes = NULL, | 737 | .set_pcie_lanes = NULL, |
| 737 | .set_clock_gating = NULL, | 738 | .set_clock_gating = NULL, |
| 738 | .set_surface_reg = r600_set_surface_reg, | 739 | .set_surface_reg = r600_set_surface_reg, |
| @@ -857,21 +858,3 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
| 857 | return 0; | 858 | return 0; |
| 858 | } | 859 | } |
| 859 | 860 | ||
| 860 | /* | ||
| 861 | * Wrapper around modesetting bits. Move to radeon_clocks.c? | ||
| 862 | */ | ||
| 863 | int radeon_clocks_init(struct radeon_device *rdev) | ||
| 864 | { | ||
| 865 | int r; | ||
| 866 | |||
| 867 | r = radeon_static_clocks_init(rdev->ddev); | ||
| 868 | if (r) { | ||
| 869 | return r; | ||
| 870 | } | ||
| 871 | DRM_INFO("Clocks initialized !\n"); | ||
| 872 | return 0; | ||
| 873 | } | ||
| 874 | |||
| 875 | void radeon_clocks_fini(struct radeon_device *rdev) | ||
| 876 | { | ||
| 877 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 6d30868744ee..68932ba7b8a4 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -32,11 +32,11 @@ | |||
| 32 | 32 | ||
| 33 | /* from radeon_encoder.c */ | 33 | /* from radeon_encoder.c */ |
| 34 | extern uint32_t | 34 | extern uint32_t |
| 35 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, | 35 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, |
| 36 | uint8_t dac); | 36 | uint8_t dac); |
| 37 | extern void radeon_link_encoder_connector(struct drm_device *dev); | 37 | extern void radeon_link_encoder_connector(struct drm_device *dev); |
| 38 | extern void | 38 | extern void |
| 39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, | 39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, |
| 40 | uint32_t supported_device); | 40 | uint32_t supported_device); |
| 41 | 41 | ||
| 42 | /* from radeon_connector.c */ | 42 | /* from radeon_connector.c */ |
| @@ -46,14 +46,14 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 46 | uint32_t supported_device, | 46 | uint32_t supported_device, |
| 47 | int connector_type, | 47 | int connector_type, |
| 48 | struct radeon_i2c_bus_rec *i2c_bus, | 48 | struct radeon_i2c_bus_rec *i2c_bus, |
| 49 | bool linkb, uint32_t igp_lane_info, | 49 | uint32_t igp_lane_info, |
| 50 | uint16_t connector_object_id, | 50 | uint16_t connector_object_id, |
| 51 | struct radeon_hpd *hpd, | 51 | struct radeon_hpd *hpd, |
| 52 | struct radeon_router *router); | 52 | struct radeon_router *router); |
| 53 | 53 | ||
| 54 | /* from radeon_legacy_encoder.c */ | 54 | /* from radeon_legacy_encoder.c */ |
| 55 | extern void | 55 | extern void |
| 56 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, | 56 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, |
| 57 | uint32_t supported_device); | 57 | uint32_t supported_device); |
| 58 | 58 | ||
| 59 | union atom_supported_devices { | 59 | union atom_supported_devices { |
| @@ -85,6 +85,19 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev | |||
| 85 | for (i = 0; i < num_indices; i++) { | 85 | for (i = 0; i < num_indices; i++) { |
| 86 | gpio = &i2c_info->asGPIO_Info[i]; | 86 | gpio = &i2c_info->asGPIO_Info[i]; |
| 87 | 87 | ||
| 88 | /* some evergreen boards have bad data for this entry */ | ||
| 89 | if (ASIC_IS_DCE4(rdev)) { | ||
| 90 | if ((i == 7) && | ||
| 91 | (gpio->usClkMaskRegisterIndex == 0x1936) && | ||
| 92 | (gpio->sucI2cId.ucAccess == 0)) { | ||
| 93 | gpio->sucI2cId.ucAccess = 0x97; | ||
| 94 | gpio->ucDataMaskShift = 8; | ||
| 95 | gpio->ucDataEnShift = 8; | ||
| 96 | gpio->ucDataY_Shift = 8; | ||
| 97 | gpio->ucDataA_Shift = 8; | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 88 | if (gpio->sucI2cId.ucAccess == id) { | 101 | if (gpio->sucI2cId.ucAccess == id) { |
| 89 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 102 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
| 90 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | 103 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
| @@ -147,6 +160,20 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
| 147 | for (i = 0; i < num_indices; i++) { | 160 | for (i = 0; i < num_indices; i++) { |
| 148 | gpio = &i2c_info->asGPIO_Info[i]; | 161 | gpio = &i2c_info->asGPIO_Info[i]; |
| 149 | i2c.valid = false; | 162 | i2c.valid = false; |
| 163 | |||
| 164 | /* some evergreen boards have bad data for this entry */ | ||
| 165 | if (ASIC_IS_DCE4(rdev)) { | ||
| 166 | if ((i == 7) && | ||
| 167 | (gpio->usClkMaskRegisterIndex == 0x1936) && | ||
| 168 | (gpio->sucI2cId.ucAccess == 0)) { | ||
| 169 | gpio->sucI2cId.ucAccess = 0x97; | ||
| 170 | gpio->ucDataMaskShift = 8; | ||
| 171 | gpio->ucDataEnShift = 8; | ||
| 172 | gpio->ucDataY_Shift = 8; | ||
| 173 | gpio->ucDataA_Shift = 8; | ||
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 150 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 177 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
| 151 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | 178 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
| 152 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | 179 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; |
| @@ -226,6 +253,8 @@ static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device | |||
| 226 | struct radeon_hpd hpd; | 253 | struct radeon_hpd hpd; |
| 227 | u32 reg; | 254 | u32 reg; |
| 228 | 255 | ||
| 256 | memset(&hpd, 0, sizeof(struct radeon_hpd)); | ||
| 257 | |||
| 229 | if (ASIC_IS_DCE4(rdev)) | 258 | if (ASIC_IS_DCE4(rdev)) |
| 230 | reg = EVERGREEN_DC_GPIO_HPD_A; | 259 | reg = EVERGREEN_DC_GPIO_HPD_A; |
| 231 | else | 260 | else |
| @@ -288,6 +317,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
| 288 | *connector_type = DRM_MODE_CONNECTOR_DVID; | 317 | *connector_type = DRM_MODE_CONNECTOR_DVID; |
| 289 | } | 318 | } |
| 290 | 319 | ||
| 320 | /* MSI K9A2GM V2/V3 board has no HDMI or DVI */ | ||
| 321 | if ((dev->pdev->device == 0x796e) && | ||
| 322 | (dev->pdev->subsystem_vendor == 0x1462) && | ||
| 323 | (dev->pdev->subsystem_device == 0x7302)) { | ||
| 324 | if ((supported_device == ATOM_DEVICE_DFP2_SUPPORT) || | ||
| 325 | (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) | ||
| 326 | return false; | ||
| 327 | } | ||
| 328 | |||
| 291 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ | 329 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ |
| 292 | if ((dev->pdev->device == 0x7941) && | 330 | if ((dev->pdev->device == 0x7941) && |
| 293 | (dev->pdev->subsystem_vendor == 0x147b) && | 331 | (dev->pdev->subsystem_vendor == 0x147b) && |
| @@ -477,7 +515,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 477 | int i, j, k, path_size, device_support; | 515 | int i, j, k, path_size, device_support; |
| 478 | int connector_type; | 516 | int connector_type; |
| 479 | u16 igp_lane_info, conn_id, connector_object_id; | 517 | u16 igp_lane_info, conn_id, connector_object_id; |
| 480 | bool linkb; | ||
| 481 | struct radeon_i2c_bus_rec ddc_bus; | 518 | struct radeon_i2c_bus_rec ddc_bus; |
| 482 | struct radeon_router router; | 519 | struct radeon_router router; |
| 483 | struct radeon_gpio_rec gpio; | 520 | struct radeon_gpio_rec gpio; |
| @@ -510,7 +547,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 510 | addr += path_size; | 547 | addr += path_size; |
| 511 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; | 548 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; |
| 512 | path_size += le16_to_cpu(path->usSize); | 549 | path_size += le16_to_cpu(path->usSize); |
| 513 | linkb = false; | 550 | |
| 514 | if (device_support & le16_to_cpu(path->usDeviceTag)) { | 551 | if (device_support & le16_to_cpu(path->usDeviceTag)) { |
| 515 | uint8_t con_obj_id, con_obj_num, con_obj_type; | 552 | uint8_t con_obj_id, con_obj_num, con_obj_type; |
| 516 | 553 | ||
| @@ -601,13 +638,10 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 601 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; | 638 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; |
| 602 | 639 | ||
| 603 | if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { | 640 | if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { |
| 604 | if (grph_obj_num == 2) | 641 | u16 encoder_obj = le16_to_cpu(path->usGraphicObjIds[j]); |
| 605 | linkb = true; | ||
| 606 | else | ||
| 607 | linkb = false; | ||
| 608 | 642 | ||
| 609 | radeon_add_atom_encoder(dev, | 643 | radeon_add_atom_encoder(dev, |
| 610 | grph_obj_id, | 644 | encoder_obj, |
| 611 | le16_to_cpu | 645 | le16_to_cpu |
| 612 | (path-> | 646 | (path-> |
| 613 | usDeviceTag)); | 647 | usDeviceTag)); |
| @@ -744,7 +778,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 744 | le16_to_cpu(path-> | 778 | le16_to_cpu(path-> |
| 745 | usDeviceTag), | 779 | usDeviceTag), |
| 746 | connector_type, &ddc_bus, | 780 | connector_type, &ddc_bus, |
| 747 | linkb, igp_lane_info, | 781 | igp_lane_info, |
| 748 | connector_object_id, | 782 | connector_object_id, |
| 749 | &hpd, | 783 | &hpd, |
| 750 | &router); | 784 | &router); |
| @@ -933,13 +967,13 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 933 | 967 | ||
| 934 | if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) | 968 | if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) |
| 935 | radeon_add_atom_encoder(dev, | 969 | radeon_add_atom_encoder(dev, |
| 936 | radeon_get_encoder_id(dev, | 970 | radeon_get_encoder_enum(dev, |
| 937 | (1 << i), | 971 | (1 << i), |
| 938 | dac), | 972 | dac), |
| 939 | (1 << i)); | 973 | (1 << i)); |
| 940 | else | 974 | else |
| 941 | radeon_add_legacy_encoder(dev, | 975 | radeon_add_legacy_encoder(dev, |
| 942 | radeon_get_encoder_id(dev, | 976 | radeon_get_encoder_enum(dev, |
| 943 | (1 << i), | 977 | (1 << i), |
| 944 | dac), | 978 | dac), |
| 945 | (1 << i)); | 979 | (1 << i)); |
| @@ -996,7 +1030,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
| 996 | bios_connectors[i]. | 1030 | bios_connectors[i]. |
| 997 | connector_type, | 1031 | connector_type, |
| 998 | &bios_connectors[i].ddc_bus, | 1032 | &bios_connectors[i].ddc_bus, |
| 999 | false, 0, | 1033 | 0, |
| 1000 | connector_object_id, | 1034 | connector_object_id, |
| 1001 | &bios_connectors[i].hpd, | 1035 | &bios_connectors[i].hpd, |
| 1002 | &router); | 1036 | &router); |
| @@ -1183,7 +1217,7 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev) | |||
| 1183 | return true; | 1217 | return true; |
| 1184 | break; | 1218 | break; |
| 1185 | case 2: | 1219 | case 2: |
| 1186 | if (igp_info->info_2.ucMemoryType & 0x0f) | 1220 | if (igp_info->info_2.ulBootUpSidePortClock) |
| 1187 | return true; | 1221 | return true; |
| 1188 | break; | 1222 | break; |
| 1189 | default: | 1223 | default: |
| @@ -1305,6 +1339,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
| 1305 | union lvds_info *lvds_info; | 1339 | union lvds_info *lvds_info; |
| 1306 | uint8_t frev, crev; | 1340 | uint8_t frev, crev; |
| 1307 | struct radeon_encoder_atom_dig *lvds = NULL; | 1341 | struct radeon_encoder_atom_dig *lvds = NULL; |
| 1342 | int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
| 1308 | 1343 | ||
| 1309 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | 1344 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
| 1310 | &frev, &crev, &data_offset)) { | 1345 | &frev, &crev, &data_offset)) { |
| @@ -1368,6 +1403,12 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
| 1368 | } | 1403 | } |
| 1369 | 1404 | ||
| 1370 | encoder->native_mode = lvds->native_mode; | 1405 | encoder->native_mode = lvds->native_mode; |
| 1406 | |||
| 1407 | if (encoder_enum == 2) | ||
| 1408 | lvds->linkb = true; | ||
| 1409 | else | ||
| 1410 | lvds->linkb = false; | ||
| 1411 | |||
| 1371 | } | 1412 | } |
| 1372 | return lvds; | 1413 | return lvds; |
| 1373 | } | 1414 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index 14448a740ba6..5249af8931e6 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
| @@ -327,6 +327,14 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
| 327 | mpll->max_feedback_div = 0xff; | 327 | mpll->max_feedback_div = 0xff; |
| 328 | mpll->best_vco = 0; | 328 | mpll->best_vco = 0; |
| 329 | 329 | ||
| 330 | if (!rdev->clock.default_sclk) | ||
| 331 | rdev->clock.default_sclk = radeon_get_engine_clock(rdev); | ||
| 332 | if ((!rdev->clock.default_mclk) && rdev->asic->get_memory_clock) | ||
| 333 | rdev->clock.default_mclk = radeon_get_memory_clock(rdev); | ||
| 334 | |||
| 335 | rdev->pm.current_sclk = rdev->clock.default_sclk; | ||
| 336 | rdev->pm.current_mclk = rdev->clock.default_mclk; | ||
| 337 | |||
| 330 | } | 338 | } |
| 331 | 339 | ||
| 332 | /* 10 khz */ | 340 | /* 10 khz */ |
| @@ -897,53 +905,3 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
| 897 | } | 905 | } |
| 898 | } | 906 | } |
| 899 | 907 | ||
| 900 | static void radeon_apply_clock_quirks(struct radeon_device *rdev) | ||
| 901 | { | ||
| 902 | uint32_t tmp; | ||
| 903 | |||
| 904 | /* XXX make sure engine is idle */ | ||
| 905 | |||
| 906 | if (rdev->family < CHIP_RS600) { | ||
| 907 | tmp = RREG32_PLL(RADEON_SCLK_CNTL); | ||
| 908 | if (ASIC_IS_R300(rdev) || ASIC_IS_RV100(rdev)) | ||
| 909 | tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP; | ||
| 910 | if ((rdev->family == CHIP_RV250) | ||
| 911 | || (rdev->family == CHIP_RV280)) | ||
| 912 | tmp |= | ||
| 913 | RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_DISP2; | ||
| 914 | if ((rdev->family == CHIP_RV350) | ||
| 915 | || (rdev->family == CHIP_RV380)) | ||
| 916 | tmp |= R300_SCLK_FORCE_VAP; | ||
| 917 | if (rdev->family == CHIP_R420) | ||
| 918 | tmp |= R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX; | ||
| 919 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); | ||
| 920 | } else if (rdev->family < CHIP_R600) { | ||
| 921 | tmp = RREG32_PLL(AVIVO_CP_DYN_CNTL); | ||
| 922 | tmp |= AVIVO_CP_FORCEON; | ||
| 923 | WREG32_PLL(AVIVO_CP_DYN_CNTL, tmp); | ||
| 924 | |||
| 925 | tmp = RREG32_PLL(AVIVO_E2_DYN_CNTL); | ||
| 926 | tmp |= AVIVO_E2_FORCEON; | ||
| 927 | WREG32_PLL(AVIVO_E2_DYN_CNTL, tmp); | ||
| 928 | |||
| 929 | tmp = RREG32_PLL(AVIVO_IDCT_DYN_CNTL); | ||
| 930 | tmp |= AVIVO_IDCT_FORCEON; | ||
| 931 | WREG32_PLL(AVIVO_IDCT_DYN_CNTL, tmp); | ||
| 932 | } | ||
| 933 | } | ||
| 934 | |||
| 935 | int radeon_static_clocks_init(struct drm_device *dev) | ||
| 936 | { | ||
| 937 | struct radeon_device *rdev = dev->dev_private; | ||
| 938 | |||
| 939 | /* XXX make sure engine is idle */ | ||
| 940 | |||
| 941 | if (radeon_dynclks != -1) { | ||
| 942 | if (radeon_dynclks) { | ||
| 943 | if (rdev->asic->set_clock_gating) | ||
| 944 | radeon_set_clock_gating(rdev, 1); | ||
| 945 | } | ||
| 946 | } | ||
| 947 | radeon_apply_clock_quirks(rdev); | ||
| 948 | return 0; | ||
| 949 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 885dcfac1838..a04b7a6ad95f 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -39,8 +39,8 @@ | |||
| 39 | 39 | ||
| 40 | /* from radeon_encoder.c */ | 40 | /* from radeon_encoder.c */ |
| 41 | extern uint32_t | 41 | extern uint32_t |
| 42 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, | 42 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, |
| 43 | uint8_t dac); | 43 | uint8_t dac); |
| 44 | extern void radeon_link_encoder_connector(struct drm_device *dev); | 44 | extern void radeon_link_encoder_connector(struct drm_device *dev); |
| 45 | 45 | ||
| 46 | /* from radeon_connector.c */ | 46 | /* from radeon_connector.c */ |
| @@ -55,7 +55,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 55 | 55 | ||
| 56 | /* from radeon_legacy_encoder.c */ | 56 | /* from radeon_legacy_encoder.c */ |
| 57 | extern void | 57 | extern void |
| 58 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, | 58 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, |
| 59 | uint32_t supported_device); | 59 | uint32_t supported_device); |
| 60 | 60 | ||
| 61 | /* old legacy ATI BIOS routines */ | 61 | /* old legacy ATI BIOS routines */ |
| @@ -1485,6 +1485,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1485 | /* PowerMac8,1 ? */ | 1485 | /* PowerMac8,1 ? */ |
| 1486 | /* imac g5 isight */ | 1486 | /* imac g5 isight */ |
| 1487 | rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; | 1487 | rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; |
| 1488 | } else if ((rdev->pdev->device == 0x4a48) && | ||
| 1489 | (rdev->pdev->subsystem_vendor == 0x1002) && | ||
| 1490 | (rdev->pdev->subsystem_device == 0x4a48)) { | ||
| 1491 | /* Mac X800 */ | ||
| 1492 | rdev->mode_info.connector_table = CT_MAC_X800; | ||
| 1488 | } else | 1493 | } else |
| 1489 | #endif /* CONFIG_PPC_PMAC */ | 1494 | #endif /* CONFIG_PPC_PMAC */ |
| 1490 | #ifdef CONFIG_PPC64 | 1495 | #ifdef CONFIG_PPC64 |
| @@ -1505,7 +1510,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1505 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1510 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
| 1506 | hpd.hpd = RADEON_HPD_NONE; | 1511 | hpd.hpd = RADEON_HPD_NONE; |
| 1507 | radeon_add_legacy_encoder(dev, | 1512 | radeon_add_legacy_encoder(dev, |
| 1508 | radeon_get_encoder_id(dev, | 1513 | radeon_get_encoder_enum(dev, |
| 1509 | ATOM_DEVICE_CRT1_SUPPORT, | 1514 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1510 | 1), | 1515 | 1), |
| 1511 | ATOM_DEVICE_CRT1_SUPPORT); | 1516 | ATOM_DEVICE_CRT1_SUPPORT); |
| @@ -1520,7 +1525,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1520 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); | 1525 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); |
| 1521 | hpd.hpd = RADEON_HPD_NONE; | 1526 | hpd.hpd = RADEON_HPD_NONE; |
| 1522 | radeon_add_legacy_encoder(dev, | 1527 | radeon_add_legacy_encoder(dev, |
| 1523 | radeon_get_encoder_id(dev, | 1528 | radeon_get_encoder_enum(dev, |
| 1524 | ATOM_DEVICE_LCD1_SUPPORT, | 1529 | ATOM_DEVICE_LCD1_SUPPORT, |
| 1525 | 0), | 1530 | 0), |
| 1526 | ATOM_DEVICE_LCD1_SUPPORT); | 1531 | ATOM_DEVICE_LCD1_SUPPORT); |
| @@ -1535,7 +1540,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1535 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1540 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
| 1536 | hpd.hpd = RADEON_HPD_NONE; | 1541 | hpd.hpd = RADEON_HPD_NONE; |
| 1537 | radeon_add_legacy_encoder(dev, | 1542 | radeon_add_legacy_encoder(dev, |
| 1538 | radeon_get_encoder_id(dev, | 1543 | radeon_get_encoder_enum(dev, |
| 1539 | ATOM_DEVICE_CRT1_SUPPORT, | 1544 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1540 | 1), | 1545 | 1), |
| 1541 | ATOM_DEVICE_CRT1_SUPPORT); | 1546 | ATOM_DEVICE_CRT1_SUPPORT); |
| @@ -1550,12 +1555,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1550 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1555 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
| 1551 | hpd.hpd = RADEON_HPD_1; | 1556 | hpd.hpd = RADEON_HPD_1; |
| 1552 | radeon_add_legacy_encoder(dev, | 1557 | radeon_add_legacy_encoder(dev, |
| 1553 | radeon_get_encoder_id(dev, | 1558 | radeon_get_encoder_enum(dev, |
| 1554 | ATOM_DEVICE_DFP1_SUPPORT, | 1559 | ATOM_DEVICE_DFP1_SUPPORT, |
| 1555 | 0), | 1560 | 0), |
| 1556 | ATOM_DEVICE_DFP1_SUPPORT); | 1561 | ATOM_DEVICE_DFP1_SUPPORT); |
| 1557 | radeon_add_legacy_encoder(dev, | 1562 | radeon_add_legacy_encoder(dev, |
| 1558 | radeon_get_encoder_id(dev, | 1563 | radeon_get_encoder_enum(dev, |
| 1559 | ATOM_DEVICE_CRT2_SUPPORT, | 1564 | ATOM_DEVICE_CRT2_SUPPORT, |
| 1560 | 2), | 1565 | 2), |
| 1561 | ATOM_DEVICE_CRT2_SUPPORT); | 1566 | ATOM_DEVICE_CRT2_SUPPORT); |
| @@ -1571,7 +1576,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1571 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1576 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
| 1572 | hpd.hpd = RADEON_HPD_NONE; | 1577 | hpd.hpd = RADEON_HPD_NONE; |
| 1573 | radeon_add_legacy_encoder(dev, | 1578 | radeon_add_legacy_encoder(dev, |
| 1574 | radeon_get_encoder_id(dev, | 1579 | radeon_get_encoder_enum(dev, |
| 1575 | ATOM_DEVICE_CRT1_SUPPORT, | 1580 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1576 | 1), | 1581 | 1), |
| 1577 | ATOM_DEVICE_CRT1_SUPPORT); | 1582 | ATOM_DEVICE_CRT1_SUPPORT); |
| @@ -1588,7 +1593,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1588 | ddc_i2c.valid = false; | 1593 | ddc_i2c.valid = false; |
| 1589 | hpd.hpd = RADEON_HPD_NONE; | 1594 | hpd.hpd = RADEON_HPD_NONE; |
| 1590 | radeon_add_legacy_encoder(dev, | 1595 | radeon_add_legacy_encoder(dev, |
| 1591 | radeon_get_encoder_id(dev, | 1596 | radeon_get_encoder_enum(dev, |
| 1592 | ATOM_DEVICE_TV1_SUPPORT, | 1597 | ATOM_DEVICE_TV1_SUPPORT, |
| 1593 | 2), | 1598 | 2), |
| 1594 | ATOM_DEVICE_TV1_SUPPORT); | 1599 | ATOM_DEVICE_TV1_SUPPORT); |
| @@ -1607,7 +1612,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1607 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1612 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
| 1608 | hpd.hpd = RADEON_HPD_NONE; | 1613 | hpd.hpd = RADEON_HPD_NONE; |
| 1609 | radeon_add_legacy_encoder(dev, | 1614 | radeon_add_legacy_encoder(dev, |
| 1610 | radeon_get_encoder_id(dev, | 1615 | radeon_get_encoder_enum(dev, |
| 1611 | ATOM_DEVICE_LCD1_SUPPORT, | 1616 | ATOM_DEVICE_LCD1_SUPPORT, |
| 1612 | 0), | 1617 | 0), |
| 1613 | ATOM_DEVICE_LCD1_SUPPORT); | 1618 | ATOM_DEVICE_LCD1_SUPPORT); |
| @@ -1619,7 +1624,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1619 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1624 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
| 1620 | hpd.hpd = RADEON_HPD_NONE; | 1625 | hpd.hpd = RADEON_HPD_NONE; |
| 1621 | radeon_add_legacy_encoder(dev, | 1626 | radeon_add_legacy_encoder(dev, |
| 1622 | radeon_get_encoder_id(dev, | 1627 | radeon_get_encoder_enum(dev, |
| 1623 | ATOM_DEVICE_CRT2_SUPPORT, | 1628 | ATOM_DEVICE_CRT2_SUPPORT, |
| 1624 | 2), | 1629 | 2), |
| 1625 | ATOM_DEVICE_CRT2_SUPPORT); | 1630 | ATOM_DEVICE_CRT2_SUPPORT); |
| @@ -1631,7 +1636,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1631 | ddc_i2c.valid = false; | 1636 | ddc_i2c.valid = false; |
| 1632 | hpd.hpd = RADEON_HPD_NONE; | 1637 | hpd.hpd = RADEON_HPD_NONE; |
| 1633 | radeon_add_legacy_encoder(dev, | 1638 | radeon_add_legacy_encoder(dev, |
| 1634 | radeon_get_encoder_id(dev, | 1639 | radeon_get_encoder_enum(dev, |
| 1635 | ATOM_DEVICE_TV1_SUPPORT, | 1640 | ATOM_DEVICE_TV1_SUPPORT, |
| 1636 | 2), | 1641 | 2), |
| 1637 | ATOM_DEVICE_TV1_SUPPORT); | 1642 | ATOM_DEVICE_TV1_SUPPORT); |
| @@ -1648,7 +1653,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1648 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1653 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
| 1649 | hpd.hpd = RADEON_HPD_NONE; | 1654 | hpd.hpd = RADEON_HPD_NONE; |
| 1650 | radeon_add_legacy_encoder(dev, | 1655 | radeon_add_legacy_encoder(dev, |
| 1651 | radeon_get_encoder_id(dev, | 1656 | radeon_get_encoder_enum(dev, |
| 1652 | ATOM_DEVICE_LCD1_SUPPORT, | 1657 | ATOM_DEVICE_LCD1_SUPPORT, |
| 1653 | 0), | 1658 | 0), |
| 1654 | ATOM_DEVICE_LCD1_SUPPORT); | 1659 | ATOM_DEVICE_LCD1_SUPPORT); |
| @@ -1660,12 +1665,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1660 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1665 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
| 1661 | hpd.hpd = RADEON_HPD_2; /* ??? */ | 1666 | hpd.hpd = RADEON_HPD_2; /* ??? */ |
| 1662 | radeon_add_legacy_encoder(dev, | 1667 | radeon_add_legacy_encoder(dev, |
| 1663 | radeon_get_encoder_id(dev, | 1668 | radeon_get_encoder_enum(dev, |
| 1664 | ATOM_DEVICE_DFP2_SUPPORT, | 1669 | ATOM_DEVICE_DFP2_SUPPORT, |
| 1665 | 0), | 1670 | 0), |
| 1666 | ATOM_DEVICE_DFP2_SUPPORT); | 1671 | ATOM_DEVICE_DFP2_SUPPORT); |
| 1667 | radeon_add_legacy_encoder(dev, | 1672 | radeon_add_legacy_encoder(dev, |
| 1668 | radeon_get_encoder_id(dev, | 1673 | radeon_get_encoder_enum(dev, |
| 1669 | ATOM_DEVICE_CRT1_SUPPORT, | 1674 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1670 | 1), | 1675 | 1), |
| 1671 | ATOM_DEVICE_CRT1_SUPPORT); | 1676 | ATOM_DEVICE_CRT1_SUPPORT); |
| @@ -1680,7 +1685,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1680 | ddc_i2c.valid = false; | 1685 | ddc_i2c.valid = false; |
| 1681 | hpd.hpd = RADEON_HPD_NONE; | 1686 | hpd.hpd = RADEON_HPD_NONE; |
| 1682 | radeon_add_legacy_encoder(dev, | 1687 | radeon_add_legacy_encoder(dev, |
| 1683 | radeon_get_encoder_id(dev, | 1688 | radeon_get_encoder_enum(dev, |
| 1684 | ATOM_DEVICE_TV1_SUPPORT, | 1689 | ATOM_DEVICE_TV1_SUPPORT, |
| 1685 | 2), | 1690 | 2), |
| 1686 | ATOM_DEVICE_TV1_SUPPORT); | 1691 | ATOM_DEVICE_TV1_SUPPORT); |
| @@ -1697,7 +1702,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1697 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1702 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
| 1698 | hpd.hpd = RADEON_HPD_NONE; | 1703 | hpd.hpd = RADEON_HPD_NONE; |
| 1699 | radeon_add_legacy_encoder(dev, | 1704 | radeon_add_legacy_encoder(dev, |
| 1700 | radeon_get_encoder_id(dev, | 1705 | radeon_get_encoder_enum(dev, |
| 1701 | ATOM_DEVICE_LCD1_SUPPORT, | 1706 | ATOM_DEVICE_LCD1_SUPPORT, |
| 1702 | 0), | 1707 | 0), |
| 1703 | ATOM_DEVICE_LCD1_SUPPORT); | 1708 | ATOM_DEVICE_LCD1_SUPPORT); |
| @@ -1709,12 +1714,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1709 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1714 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
| 1710 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1715 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
| 1711 | radeon_add_legacy_encoder(dev, | 1716 | radeon_add_legacy_encoder(dev, |
| 1712 | radeon_get_encoder_id(dev, | 1717 | radeon_get_encoder_enum(dev, |
| 1713 | ATOM_DEVICE_DFP1_SUPPORT, | 1718 | ATOM_DEVICE_DFP1_SUPPORT, |
| 1714 | 0), | 1719 | 0), |
| 1715 | ATOM_DEVICE_DFP1_SUPPORT); | 1720 | ATOM_DEVICE_DFP1_SUPPORT); |
| 1716 | radeon_add_legacy_encoder(dev, | 1721 | radeon_add_legacy_encoder(dev, |
| 1717 | radeon_get_encoder_id(dev, | 1722 | radeon_get_encoder_enum(dev, |
| 1718 | ATOM_DEVICE_CRT1_SUPPORT, | 1723 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1719 | 1), | 1724 | 1), |
| 1720 | ATOM_DEVICE_CRT1_SUPPORT); | 1725 | ATOM_DEVICE_CRT1_SUPPORT); |
| @@ -1728,7 +1733,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1728 | ddc_i2c.valid = false; | 1733 | ddc_i2c.valid = false; |
| 1729 | hpd.hpd = RADEON_HPD_NONE; | 1734 | hpd.hpd = RADEON_HPD_NONE; |
| 1730 | radeon_add_legacy_encoder(dev, | 1735 | radeon_add_legacy_encoder(dev, |
| 1731 | radeon_get_encoder_id(dev, | 1736 | radeon_get_encoder_enum(dev, |
| 1732 | ATOM_DEVICE_TV1_SUPPORT, | 1737 | ATOM_DEVICE_TV1_SUPPORT, |
| 1733 | 2), | 1738 | 2), |
| 1734 | ATOM_DEVICE_TV1_SUPPORT); | 1739 | ATOM_DEVICE_TV1_SUPPORT); |
| @@ -1745,7 +1750,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1745 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1750 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
| 1746 | hpd.hpd = RADEON_HPD_NONE; | 1751 | hpd.hpd = RADEON_HPD_NONE; |
| 1747 | radeon_add_legacy_encoder(dev, | 1752 | radeon_add_legacy_encoder(dev, |
| 1748 | radeon_get_encoder_id(dev, | 1753 | radeon_get_encoder_enum(dev, |
| 1749 | ATOM_DEVICE_LCD1_SUPPORT, | 1754 | ATOM_DEVICE_LCD1_SUPPORT, |
| 1750 | 0), | 1755 | 0), |
| 1751 | ATOM_DEVICE_LCD1_SUPPORT); | 1756 | ATOM_DEVICE_LCD1_SUPPORT); |
| @@ -1757,7 +1762,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1757 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1762 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
| 1758 | hpd.hpd = RADEON_HPD_NONE; | 1763 | hpd.hpd = RADEON_HPD_NONE; |
| 1759 | radeon_add_legacy_encoder(dev, | 1764 | radeon_add_legacy_encoder(dev, |
| 1760 | radeon_get_encoder_id(dev, | 1765 | radeon_get_encoder_enum(dev, |
| 1761 | ATOM_DEVICE_CRT1_SUPPORT, | 1766 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1762 | 1), | 1767 | 1), |
| 1763 | ATOM_DEVICE_CRT1_SUPPORT); | 1768 | ATOM_DEVICE_CRT1_SUPPORT); |
| @@ -1769,7 +1774,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1769 | ddc_i2c.valid = false; | 1774 | ddc_i2c.valid = false; |
| 1770 | hpd.hpd = RADEON_HPD_NONE; | 1775 | hpd.hpd = RADEON_HPD_NONE; |
| 1771 | radeon_add_legacy_encoder(dev, | 1776 | radeon_add_legacy_encoder(dev, |
| 1772 | radeon_get_encoder_id(dev, | 1777 | radeon_get_encoder_enum(dev, |
| 1773 | ATOM_DEVICE_TV1_SUPPORT, | 1778 | ATOM_DEVICE_TV1_SUPPORT, |
| 1774 | 2), | 1779 | 2), |
| 1775 | ATOM_DEVICE_TV1_SUPPORT); | 1780 | ATOM_DEVICE_TV1_SUPPORT); |
| @@ -1786,12 +1791,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1786 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1791 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
| 1787 | hpd.hpd = RADEON_HPD_2; /* ??? */ | 1792 | hpd.hpd = RADEON_HPD_2; /* ??? */ |
| 1788 | radeon_add_legacy_encoder(dev, | 1793 | radeon_add_legacy_encoder(dev, |
| 1789 | radeon_get_encoder_id(dev, | 1794 | radeon_get_encoder_enum(dev, |
| 1790 | ATOM_DEVICE_DFP2_SUPPORT, | 1795 | ATOM_DEVICE_DFP2_SUPPORT, |
| 1791 | 0), | 1796 | 0), |
| 1792 | ATOM_DEVICE_DFP2_SUPPORT); | 1797 | ATOM_DEVICE_DFP2_SUPPORT); |
| 1793 | radeon_add_legacy_encoder(dev, | 1798 | radeon_add_legacy_encoder(dev, |
| 1794 | radeon_get_encoder_id(dev, | 1799 | radeon_get_encoder_enum(dev, |
| 1795 | ATOM_DEVICE_CRT2_SUPPORT, | 1800 | ATOM_DEVICE_CRT2_SUPPORT, |
| 1796 | 2), | 1801 | 2), |
| 1797 | ATOM_DEVICE_CRT2_SUPPORT); | 1802 | ATOM_DEVICE_CRT2_SUPPORT); |
| @@ -1806,7 +1811,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1806 | ddc_i2c.valid = false; | 1811 | ddc_i2c.valid = false; |
| 1807 | hpd.hpd = RADEON_HPD_NONE; | 1812 | hpd.hpd = RADEON_HPD_NONE; |
| 1808 | radeon_add_legacy_encoder(dev, | 1813 | radeon_add_legacy_encoder(dev, |
| 1809 | radeon_get_encoder_id(dev, | 1814 | radeon_get_encoder_enum(dev, |
| 1810 | ATOM_DEVICE_TV1_SUPPORT, | 1815 | ATOM_DEVICE_TV1_SUPPORT, |
| 1811 | 2), | 1816 | 2), |
| 1812 | ATOM_DEVICE_TV1_SUPPORT); | 1817 | ATOM_DEVICE_TV1_SUPPORT); |
| @@ -1823,12 +1828,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1823 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1828 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
| 1824 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1829 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
| 1825 | radeon_add_legacy_encoder(dev, | 1830 | radeon_add_legacy_encoder(dev, |
| 1826 | radeon_get_encoder_id(dev, | 1831 | radeon_get_encoder_enum(dev, |
| 1827 | ATOM_DEVICE_DFP1_SUPPORT, | 1832 | ATOM_DEVICE_DFP1_SUPPORT, |
| 1828 | 0), | 1833 | 0), |
| 1829 | ATOM_DEVICE_DFP1_SUPPORT); | 1834 | ATOM_DEVICE_DFP1_SUPPORT); |
| 1830 | radeon_add_legacy_encoder(dev, | 1835 | radeon_add_legacy_encoder(dev, |
| 1831 | radeon_get_encoder_id(dev, | 1836 | radeon_get_encoder_enum(dev, |
| 1832 | ATOM_DEVICE_CRT2_SUPPORT, | 1837 | ATOM_DEVICE_CRT2_SUPPORT, |
| 1833 | 2), | 1838 | 2), |
| 1834 | ATOM_DEVICE_CRT2_SUPPORT); | 1839 | ATOM_DEVICE_CRT2_SUPPORT); |
| @@ -1842,7 +1847,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1842 | ddc_i2c.valid = false; | 1847 | ddc_i2c.valid = false; |
| 1843 | hpd.hpd = RADEON_HPD_NONE; | 1848 | hpd.hpd = RADEON_HPD_NONE; |
| 1844 | radeon_add_legacy_encoder(dev, | 1849 | radeon_add_legacy_encoder(dev, |
| 1845 | radeon_get_encoder_id(dev, | 1850 | radeon_get_encoder_enum(dev, |
| 1846 | ATOM_DEVICE_TV1_SUPPORT, | 1851 | ATOM_DEVICE_TV1_SUPPORT, |
| 1847 | 2), | 1852 | 2), |
| 1848 | ATOM_DEVICE_TV1_SUPPORT); | 1853 | ATOM_DEVICE_TV1_SUPPORT); |
| @@ -1859,7 +1864,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1859 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); | 1864 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); |
| 1860 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1865 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
| 1861 | radeon_add_legacy_encoder(dev, | 1866 | radeon_add_legacy_encoder(dev, |
| 1862 | radeon_get_encoder_id(dev, | 1867 | radeon_get_encoder_enum(dev, |
| 1863 | ATOM_DEVICE_DFP1_SUPPORT, | 1868 | ATOM_DEVICE_DFP1_SUPPORT, |
| 1864 | 0), | 1869 | 0), |
| 1865 | ATOM_DEVICE_DFP1_SUPPORT); | 1870 | ATOM_DEVICE_DFP1_SUPPORT); |
| @@ -1871,7 +1876,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1871 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1876 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
| 1872 | hpd.hpd = RADEON_HPD_NONE; | 1877 | hpd.hpd = RADEON_HPD_NONE; |
| 1873 | radeon_add_legacy_encoder(dev, | 1878 | radeon_add_legacy_encoder(dev, |
| 1874 | radeon_get_encoder_id(dev, | 1879 | radeon_get_encoder_enum(dev, |
| 1875 | ATOM_DEVICE_CRT2_SUPPORT, | 1880 | ATOM_DEVICE_CRT2_SUPPORT, |
| 1876 | 2), | 1881 | 2), |
| 1877 | ATOM_DEVICE_CRT2_SUPPORT); | 1882 | ATOM_DEVICE_CRT2_SUPPORT); |
| @@ -1883,7 +1888,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1883 | ddc_i2c.valid = false; | 1888 | ddc_i2c.valid = false; |
| 1884 | hpd.hpd = RADEON_HPD_NONE; | 1889 | hpd.hpd = RADEON_HPD_NONE; |
| 1885 | radeon_add_legacy_encoder(dev, | 1890 | radeon_add_legacy_encoder(dev, |
| 1886 | radeon_get_encoder_id(dev, | 1891 | radeon_get_encoder_enum(dev, |
| 1887 | ATOM_DEVICE_TV1_SUPPORT, | 1892 | ATOM_DEVICE_TV1_SUPPORT, |
| 1888 | 2), | 1893 | 2), |
| 1889 | ATOM_DEVICE_TV1_SUPPORT); | 1894 | ATOM_DEVICE_TV1_SUPPORT); |
| @@ -1900,7 +1905,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1900 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1905 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
| 1901 | hpd.hpd = RADEON_HPD_NONE; | 1906 | hpd.hpd = RADEON_HPD_NONE; |
| 1902 | radeon_add_legacy_encoder(dev, | 1907 | radeon_add_legacy_encoder(dev, |
| 1903 | radeon_get_encoder_id(dev, | 1908 | radeon_get_encoder_enum(dev, |
| 1904 | ATOM_DEVICE_CRT1_SUPPORT, | 1909 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1905 | 1), | 1910 | 1), |
| 1906 | ATOM_DEVICE_CRT1_SUPPORT); | 1911 | ATOM_DEVICE_CRT1_SUPPORT); |
| @@ -1912,7 +1917,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1912 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1917 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
| 1913 | hpd.hpd = RADEON_HPD_NONE; | 1918 | hpd.hpd = RADEON_HPD_NONE; |
| 1914 | radeon_add_legacy_encoder(dev, | 1919 | radeon_add_legacy_encoder(dev, |
| 1915 | radeon_get_encoder_id(dev, | 1920 | radeon_get_encoder_enum(dev, |
| 1916 | ATOM_DEVICE_CRT2_SUPPORT, | 1921 | ATOM_DEVICE_CRT2_SUPPORT, |
| 1917 | 2), | 1922 | 2), |
| 1918 | ATOM_DEVICE_CRT2_SUPPORT); | 1923 | ATOM_DEVICE_CRT2_SUPPORT); |
| @@ -1924,7 +1929,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1924 | ddc_i2c.valid = false; | 1929 | ddc_i2c.valid = false; |
| 1925 | hpd.hpd = RADEON_HPD_NONE; | 1930 | hpd.hpd = RADEON_HPD_NONE; |
| 1926 | radeon_add_legacy_encoder(dev, | 1931 | radeon_add_legacy_encoder(dev, |
| 1927 | radeon_get_encoder_id(dev, | 1932 | radeon_get_encoder_enum(dev, |
| 1928 | ATOM_DEVICE_TV1_SUPPORT, | 1933 | ATOM_DEVICE_TV1_SUPPORT, |
| 1929 | 2), | 1934 | 2), |
| 1930 | ATOM_DEVICE_TV1_SUPPORT); | 1935 | ATOM_DEVICE_TV1_SUPPORT); |
| @@ -1941,7 +1946,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1941 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1946 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
| 1942 | hpd.hpd = RADEON_HPD_NONE; | 1947 | hpd.hpd = RADEON_HPD_NONE; |
| 1943 | radeon_add_legacy_encoder(dev, | 1948 | radeon_add_legacy_encoder(dev, |
| 1944 | radeon_get_encoder_id(dev, | 1949 | radeon_get_encoder_enum(dev, |
| 1945 | ATOM_DEVICE_CRT1_SUPPORT, | 1950 | ATOM_DEVICE_CRT1_SUPPORT, |
| 1946 | 1), | 1951 | 1), |
| 1947 | ATOM_DEVICE_CRT1_SUPPORT); | 1952 | ATOM_DEVICE_CRT1_SUPPORT); |
| @@ -1952,7 +1957,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1952 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1957 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
| 1953 | hpd.hpd = RADEON_HPD_NONE; | 1958 | hpd.hpd = RADEON_HPD_NONE; |
| 1954 | radeon_add_legacy_encoder(dev, | 1959 | radeon_add_legacy_encoder(dev, |
| 1955 | radeon_get_encoder_id(dev, | 1960 | radeon_get_encoder_enum(dev, |
| 1956 | ATOM_DEVICE_CRT2_SUPPORT, | 1961 | ATOM_DEVICE_CRT2_SUPPORT, |
| 1957 | 2), | 1962 | 2), |
| 1958 | ATOM_DEVICE_CRT2_SUPPORT); | 1963 | ATOM_DEVICE_CRT2_SUPPORT); |
| @@ -1961,6 +1966,48 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
| 1961 | CONNECTOR_OBJECT_ID_VGA, | 1966 | CONNECTOR_OBJECT_ID_VGA, |
| 1962 | &hpd); | 1967 | &hpd); |
| 1963 | break; | 1968 | break; |
| 1969 | case CT_MAC_X800: | ||
| 1970 | DRM_INFO("Connector Table: %d (mac x800)\n", | ||
| 1971 | rdev->mode_info.connector_table); | ||
| 1972 | /* DVI - primary dac, internal tmds */ | ||
| 1973 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | ||
| 1974 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
| 1975 | radeon_add_legacy_encoder(dev, | ||
| 1976 | radeon_get_encoder_enum(dev, | ||
| 1977 | ATOM_DEVICE_DFP1_SUPPORT, | ||
| 1978 | 0), | ||
| 1979 | ATOM_DEVICE_DFP1_SUPPORT); | ||
| 1980 | radeon_add_legacy_encoder(dev, | ||
| 1981 | radeon_get_encoder_enum(dev, | ||
| 1982 | ATOM_DEVICE_CRT1_SUPPORT, | ||
| 1983 | 1), | ||
| 1984 | ATOM_DEVICE_CRT1_SUPPORT); | ||
| 1985 | radeon_add_legacy_connector(dev, 0, | ||
| 1986 | ATOM_DEVICE_DFP1_SUPPORT | | ||
| 1987 | ATOM_DEVICE_CRT1_SUPPORT, | ||
| 1988 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | ||
| 1989 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, | ||
| 1990 | &hpd); | ||
| 1991 | /* DVI - tv dac, dvo */ | ||
| 1992 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); | ||
| 1993 | hpd.hpd = RADEON_HPD_2; /* ??? */ | ||
| 1994 | radeon_add_legacy_encoder(dev, | ||
| 1995 | radeon_get_encoder_enum(dev, | ||
| 1996 | ATOM_DEVICE_DFP2_SUPPORT, | ||
| 1997 | 0), | ||
| 1998 | ATOM_DEVICE_DFP2_SUPPORT); | ||
| 1999 | radeon_add_legacy_encoder(dev, | ||
| 2000 | radeon_get_encoder_enum(dev, | ||
| 2001 | ATOM_DEVICE_CRT2_SUPPORT, | ||
| 2002 | 2), | ||
| 2003 | ATOM_DEVICE_CRT2_SUPPORT); | ||
| 2004 | radeon_add_legacy_connector(dev, 1, | ||
| 2005 | ATOM_DEVICE_DFP2_SUPPORT | | ||
| 2006 | ATOM_DEVICE_CRT2_SUPPORT, | ||
| 2007 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | ||
| 2008 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, | ||
| 2009 | &hpd); | ||
| 2010 | break; | ||
| 1964 | default: | 2011 | default: |
| 1965 | DRM_INFO("Connector table: %d (invalid)\n", | 2012 | DRM_INFO("Connector table: %d (invalid)\n", |
| 1966 | rdev->mode_info.connector_table); | 2013 | rdev->mode_info.connector_table); |
| @@ -2109,7 +2156,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2109 | else | 2156 | else |
| 2110 | devices = ATOM_DEVICE_DFP1_SUPPORT; | 2157 | devices = ATOM_DEVICE_DFP1_SUPPORT; |
| 2111 | radeon_add_legacy_encoder(dev, | 2158 | radeon_add_legacy_encoder(dev, |
| 2112 | radeon_get_encoder_id | 2159 | radeon_get_encoder_enum |
| 2113 | (dev, devices, 0), | 2160 | (dev, devices, 0), |
| 2114 | devices); | 2161 | devices); |
| 2115 | radeon_add_legacy_connector(dev, i, devices, | 2162 | radeon_add_legacy_connector(dev, i, devices, |
| @@ -2123,7 +2170,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2123 | if (tmp & 0x1) { | 2170 | if (tmp & 0x1) { |
| 2124 | devices = ATOM_DEVICE_CRT2_SUPPORT; | 2171 | devices = ATOM_DEVICE_CRT2_SUPPORT; |
| 2125 | radeon_add_legacy_encoder(dev, | 2172 | radeon_add_legacy_encoder(dev, |
| 2126 | radeon_get_encoder_id | 2173 | radeon_get_encoder_enum |
| 2127 | (dev, | 2174 | (dev, |
| 2128 | ATOM_DEVICE_CRT2_SUPPORT, | 2175 | ATOM_DEVICE_CRT2_SUPPORT, |
| 2129 | 2), | 2176 | 2), |
| @@ -2131,7 +2178,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2131 | } else { | 2178 | } else { |
| 2132 | devices = ATOM_DEVICE_CRT1_SUPPORT; | 2179 | devices = ATOM_DEVICE_CRT1_SUPPORT; |
| 2133 | radeon_add_legacy_encoder(dev, | 2180 | radeon_add_legacy_encoder(dev, |
| 2134 | radeon_get_encoder_id | 2181 | radeon_get_encoder_enum |
| 2135 | (dev, | 2182 | (dev, |
| 2136 | ATOM_DEVICE_CRT1_SUPPORT, | 2183 | ATOM_DEVICE_CRT1_SUPPORT, |
| 2137 | 1), | 2184 | 1), |
| @@ -2151,7 +2198,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2151 | if (tmp & 0x1) { | 2198 | if (tmp & 0x1) { |
| 2152 | devices |= ATOM_DEVICE_CRT2_SUPPORT; | 2199 | devices |= ATOM_DEVICE_CRT2_SUPPORT; |
| 2153 | radeon_add_legacy_encoder(dev, | 2200 | radeon_add_legacy_encoder(dev, |
| 2154 | radeon_get_encoder_id | 2201 | radeon_get_encoder_enum |
| 2155 | (dev, | 2202 | (dev, |
| 2156 | ATOM_DEVICE_CRT2_SUPPORT, | 2203 | ATOM_DEVICE_CRT2_SUPPORT, |
| 2157 | 2), | 2204 | 2), |
| @@ -2159,7 +2206,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2159 | } else { | 2206 | } else { |
| 2160 | devices |= ATOM_DEVICE_CRT1_SUPPORT; | 2207 | devices |= ATOM_DEVICE_CRT1_SUPPORT; |
| 2161 | radeon_add_legacy_encoder(dev, | 2208 | radeon_add_legacy_encoder(dev, |
| 2162 | radeon_get_encoder_id | 2209 | radeon_get_encoder_enum |
| 2163 | (dev, | 2210 | (dev, |
| 2164 | ATOM_DEVICE_CRT1_SUPPORT, | 2211 | ATOM_DEVICE_CRT1_SUPPORT, |
| 2165 | 1), | 2212 | 1), |
| @@ -2168,7 +2215,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2168 | if ((tmp >> 4) & 0x1) { | 2215 | if ((tmp >> 4) & 0x1) { |
| 2169 | devices |= ATOM_DEVICE_DFP2_SUPPORT; | 2216 | devices |= ATOM_DEVICE_DFP2_SUPPORT; |
| 2170 | radeon_add_legacy_encoder(dev, | 2217 | radeon_add_legacy_encoder(dev, |
| 2171 | radeon_get_encoder_id | 2218 | radeon_get_encoder_enum |
| 2172 | (dev, | 2219 | (dev, |
| 2173 | ATOM_DEVICE_DFP2_SUPPORT, | 2220 | ATOM_DEVICE_DFP2_SUPPORT, |
| 2174 | 0), | 2221 | 0), |
| @@ -2177,7 +2224,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2177 | } else { | 2224 | } else { |
| 2178 | devices |= ATOM_DEVICE_DFP1_SUPPORT; | 2225 | devices |= ATOM_DEVICE_DFP1_SUPPORT; |
| 2179 | radeon_add_legacy_encoder(dev, | 2226 | radeon_add_legacy_encoder(dev, |
| 2180 | radeon_get_encoder_id | 2227 | radeon_get_encoder_enum |
| 2181 | (dev, | 2228 | (dev, |
| 2182 | ATOM_DEVICE_DFP1_SUPPORT, | 2229 | ATOM_DEVICE_DFP1_SUPPORT, |
| 2183 | 0), | 2230 | 0), |
| @@ -2202,7 +2249,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2202 | connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | 2249 | connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
| 2203 | } | 2250 | } |
| 2204 | radeon_add_legacy_encoder(dev, | 2251 | radeon_add_legacy_encoder(dev, |
| 2205 | radeon_get_encoder_id | 2252 | radeon_get_encoder_enum |
| 2206 | (dev, devices, 0), | 2253 | (dev, devices, 0), |
| 2207 | devices); | 2254 | devices); |
| 2208 | radeon_add_legacy_connector(dev, i, devices, | 2255 | radeon_add_legacy_connector(dev, i, devices, |
| @@ -2215,7 +2262,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2215 | case CONNECTOR_CTV_LEGACY: | 2262 | case CONNECTOR_CTV_LEGACY: |
| 2216 | case CONNECTOR_STV_LEGACY: | 2263 | case CONNECTOR_STV_LEGACY: |
| 2217 | radeon_add_legacy_encoder(dev, | 2264 | radeon_add_legacy_encoder(dev, |
| 2218 | radeon_get_encoder_id | 2265 | radeon_get_encoder_enum |
| 2219 | (dev, | 2266 | (dev, |
| 2220 | ATOM_DEVICE_TV1_SUPPORT, | 2267 | ATOM_DEVICE_TV1_SUPPORT, |
| 2221 | 2), | 2268 | 2), |
| @@ -2242,12 +2289,12 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2242 | DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); | 2289 | DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); |
| 2243 | 2290 | ||
| 2244 | radeon_add_legacy_encoder(dev, | 2291 | radeon_add_legacy_encoder(dev, |
| 2245 | radeon_get_encoder_id(dev, | 2292 | radeon_get_encoder_enum(dev, |
| 2246 | ATOM_DEVICE_CRT1_SUPPORT, | 2293 | ATOM_DEVICE_CRT1_SUPPORT, |
| 2247 | 1), | 2294 | 1), |
| 2248 | ATOM_DEVICE_CRT1_SUPPORT); | 2295 | ATOM_DEVICE_CRT1_SUPPORT); |
| 2249 | radeon_add_legacy_encoder(dev, | 2296 | radeon_add_legacy_encoder(dev, |
| 2250 | radeon_get_encoder_id(dev, | 2297 | radeon_get_encoder_enum(dev, |
| 2251 | ATOM_DEVICE_DFP1_SUPPORT, | 2298 | ATOM_DEVICE_DFP1_SUPPORT, |
| 2252 | 0), | 2299 | 0), |
| 2253 | ATOM_DEVICE_DFP1_SUPPORT); | 2300 | ATOM_DEVICE_DFP1_SUPPORT); |
| @@ -2268,7 +2315,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2268 | DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); | 2315 | DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); |
| 2269 | if (crt_info) { | 2316 | if (crt_info) { |
| 2270 | radeon_add_legacy_encoder(dev, | 2317 | radeon_add_legacy_encoder(dev, |
| 2271 | radeon_get_encoder_id(dev, | 2318 | radeon_get_encoder_enum(dev, |
| 2272 | ATOM_DEVICE_CRT1_SUPPORT, | 2319 | ATOM_DEVICE_CRT1_SUPPORT, |
| 2273 | 1), | 2320 | 1), |
| 2274 | ATOM_DEVICE_CRT1_SUPPORT); | 2321 | ATOM_DEVICE_CRT1_SUPPORT); |
| @@ -2297,7 +2344,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2297 | COMBIOS_LCD_DDC_INFO_TABLE); | 2344 | COMBIOS_LCD_DDC_INFO_TABLE); |
| 2298 | 2345 | ||
| 2299 | radeon_add_legacy_encoder(dev, | 2346 | radeon_add_legacy_encoder(dev, |
| 2300 | radeon_get_encoder_id(dev, | 2347 | radeon_get_encoder_enum(dev, |
| 2301 | ATOM_DEVICE_LCD1_SUPPORT, | 2348 | ATOM_DEVICE_LCD1_SUPPORT, |
| 2302 | 0), | 2349 | 0), |
| 2303 | ATOM_DEVICE_LCD1_SUPPORT); | 2350 | ATOM_DEVICE_LCD1_SUPPORT); |
| @@ -2351,7 +2398,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2351 | hpd.hpd = RADEON_HPD_NONE; | 2398 | hpd.hpd = RADEON_HPD_NONE; |
| 2352 | ddc_i2c.valid = false; | 2399 | ddc_i2c.valid = false; |
| 2353 | radeon_add_legacy_encoder(dev, | 2400 | radeon_add_legacy_encoder(dev, |
| 2354 | radeon_get_encoder_id | 2401 | radeon_get_encoder_enum |
| 2355 | (dev, | 2402 | (dev, |
| 2356 | ATOM_DEVICE_TV1_SUPPORT, | 2403 | ATOM_DEVICE_TV1_SUPPORT, |
| 2357 | 2), | 2404 | 2), |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 47c4b276d30c..ecc1a8fafbfd 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -481,7 +481,8 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector, | |||
| 481 | return MODE_OK; | 481 | return MODE_OK; |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) | 484 | static enum drm_connector_status |
| 485 | radeon_lvds_detect(struct drm_connector *connector, bool force) | ||
| 485 | { | 486 | { |
| 486 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 487 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 487 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | 488 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
| @@ -594,7 +595,8 @@ static int radeon_vga_mode_valid(struct drm_connector *connector, | |||
| 594 | return MODE_OK; | 595 | return MODE_OK; |
| 595 | } | 596 | } |
| 596 | 597 | ||
| 597 | static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector) | 598 | static enum drm_connector_status |
| 599 | radeon_vga_detect(struct drm_connector *connector, bool force) | ||
| 598 | { | 600 | { |
| 599 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 601 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 600 | struct drm_encoder *encoder; | 602 | struct drm_encoder *encoder; |
| @@ -691,7 +693,8 @@ static int radeon_tv_mode_valid(struct drm_connector *connector, | |||
| 691 | return MODE_OK; | 693 | return MODE_OK; |
| 692 | } | 694 | } |
| 693 | 695 | ||
| 694 | static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector) | 696 | static enum drm_connector_status |
| 697 | radeon_tv_detect(struct drm_connector *connector, bool force) | ||
| 695 | { | 698 | { |
| 696 | struct drm_encoder *encoder; | 699 | struct drm_encoder *encoder; |
| 697 | struct drm_encoder_helper_funcs *encoder_funcs; | 700 | struct drm_encoder_helper_funcs *encoder_funcs; |
| @@ -748,7 +751,8 @@ static int radeon_dvi_get_modes(struct drm_connector *connector) | |||
| 748 | * we have to check if this analog encoder is shared with anyone else (TV) | 751 | * we have to check if this analog encoder is shared with anyone else (TV) |
| 749 | * if its shared we have to set the other connector to disconnected. | 752 | * if its shared we have to set the other connector to disconnected. |
| 750 | */ | 753 | */ |
| 751 | static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) | 754 | static enum drm_connector_status |
| 755 | radeon_dvi_detect(struct drm_connector *connector, bool force) | ||
| 752 | { | 756 | { |
| 753 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 757 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 754 | struct drm_encoder *encoder = NULL; | 758 | struct drm_encoder *encoder = NULL; |
| @@ -972,32 +976,35 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
| 972 | return ret; | 976 | return ret; |
| 973 | } | 977 | } |
| 974 | 978 | ||
| 975 | static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector) | 979 | static enum drm_connector_status |
| 980 | radeon_dp_detect(struct drm_connector *connector, bool force) | ||
| 976 | { | 981 | { |
| 977 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 982 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 978 | enum drm_connector_status ret = connector_status_disconnected; | 983 | enum drm_connector_status ret = connector_status_disconnected; |
| 979 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | 984 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; |
| 980 | u8 sink_type; | ||
| 981 | 985 | ||
| 982 | if (radeon_connector->edid) { | 986 | if (radeon_connector->edid) { |
| 983 | kfree(radeon_connector->edid); | 987 | kfree(radeon_connector->edid); |
| 984 | radeon_connector->edid = NULL; | 988 | radeon_connector->edid = NULL; |
| 985 | } | 989 | } |
| 986 | 990 | ||
| 987 | sink_type = radeon_dp_getsinktype(radeon_connector); | 991 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
| 988 | if ((sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 992 | /* eDP is always DP */ |
| 989 | (sink_type == CONNECTOR_OBJECT_ID_eDP)) { | 993 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; |
| 990 | if (radeon_dp_getdpcd(radeon_connector)) { | 994 | if (radeon_dp_getdpcd(radeon_connector)) |
| 991 | radeon_dig_connector->dp_sink_type = sink_type; | ||
| 992 | ret = connector_status_connected; | 995 | ret = connector_status_connected; |
| 993 | } | ||
| 994 | } else { | 996 | } else { |
| 995 | if (radeon_ddc_probe(radeon_connector)) { | 997 | radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); |
| 996 | radeon_dig_connector->dp_sink_type = sink_type; | 998 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { |
| 997 | ret = connector_status_connected; | 999 | if (radeon_dp_getdpcd(radeon_connector)) |
| 1000 | ret = connector_status_connected; | ||
| 1001 | } else { | ||
| 1002 | if (radeon_ddc_probe(radeon_connector)) | ||
| 1003 | ret = connector_status_connected; | ||
| 998 | } | 1004 | } |
| 999 | } | 1005 | } |
| 1000 | 1006 | ||
| 1007 | radeon_connector_update_scratch_regs(connector, ret); | ||
| 1001 | return ret; | 1008 | return ret; |
| 1002 | } | 1009 | } |
| 1003 | 1010 | ||
| @@ -1037,7 +1044,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1037 | uint32_t supported_device, | 1044 | uint32_t supported_device, |
| 1038 | int connector_type, | 1045 | int connector_type, |
| 1039 | struct radeon_i2c_bus_rec *i2c_bus, | 1046 | struct radeon_i2c_bus_rec *i2c_bus, |
| 1040 | bool linkb, | ||
| 1041 | uint32_t igp_lane_info, | 1047 | uint32_t igp_lane_info, |
| 1042 | uint16_t connector_object_id, | 1048 | uint16_t connector_object_id, |
| 1043 | struct radeon_hpd *hpd, | 1049 | struct radeon_hpd *hpd, |
| @@ -1050,10 +1056,16 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1050 | uint32_t subpixel_order = SubPixelNone; | 1056 | uint32_t subpixel_order = SubPixelNone; |
| 1051 | bool shared_ddc = false; | 1057 | bool shared_ddc = false; |
| 1052 | 1058 | ||
| 1053 | /* fixme - tv/cv/din */ | ||
| 1054 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) | 1059 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
| 1055 | return; | 1060 | return; |
| 1056 | 1061 | ||
| 1062 | /* if the user selected tv=0 don't try and add the connector */ | ||
| 1063 | if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) || | ||
| 1064 | (connector_type == DRM_MODE_CONNECTOR_Composite) || | ||
| 1065 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) && | ||
| 1066 | (radeon_tv == 0)) | ||
| 1067 | return; | ||
| 1068 | |||
| 1057 | /* see if we already added it */ | 1069 | /* see if we already added it */ |
| 1058 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1070 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 1059 | radeon_connector = to_radeon_connector(connector); | 1071 | radeon_connector = to_radeon_connector(connector); |
| @@ -1128,7 +1140,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1128 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1140 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
| 1129 | if (!radeon_dig_connector) | 1141 | if (!radeon_dig_connector) |
| 1130 | goto failed; | 1142 | goto failed; |
| 1131 | radeon_dig_connector->linkb = linkb; | ||
| 1132 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1143 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
| 1133 | radeon_connector->con_priv = radeon_dig_connector; | 1144 | radeon_connector->con_priv = radeon_dig_connector; |
| 1134 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1145 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
| @@ -1158,7 +1169,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1158 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1169 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
| 1159 | if (!radeon_dig_connector) | 1170 | if (!radeon_dig_connector) |
| 1160 | goto failed; | 1171 | goto failed; |
| 1161 | radeon_dig_connector->linkb = linkb; | ||
| 1162 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1172 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
| 1163 | radeon_connector->con_priv = radeon_dig_connector; | 1173 | radeon_connector->con_priv = radeon_dig_connector; |
| 1164 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1174 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
| @@ -1182,7 +1192,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1182 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1192 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
| 1183 | if (!radeon_dig_connector) | 1193 | if (!radeon_dig_connector) |
| 1184 | goto failed; | 1194 | goto failed; |
| 1185 | radeon_dig_connector->linkb = linkb; | ||
| 1186 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1195 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
| 1187 | radeon_connector->con_priv = radeon_dig_connector; | 1196 | radeon_connector->con_priv = radeon_dig_connector; |
| 1188 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); | 1197 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); |
| @@ -1211,25 +1220,22 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 1211 | case DRM_MODE_CONNECTOR_SVIDEO: | 1220 | case DRM_MODE_CONNECTOR_SVIDEO: |
| 1212 | case DRM_MODE_CONNECTOR_Composite: | 1221 | case DRM_MODE_CONNECTOR_Composite: |
| 1213 | case DRM_MODE_CONNECTOR_9PinDIN: | 1222 | case DRM_MODE_CONNECTOR_9PinDIN: |
| 1214 | if (radeon_tv == 1) { | 1223 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); |
| 1215 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); | 1224 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); |
| 1216 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); | 1225 | radeon_connector->dac_load_detect = true; |
| 1217 | radeon_connector->dac_load_detect = true; | 1226 | drm_connector_attach_property(&radeon_connector->base, |
| 1218 | drm_connector_attach_property(&radeon_connector->base, | 1227 | rdev->mode_info.load_detect_property, |
| 1219 | rdev->mode_info.load_detect_property, | 1228 | 1); |
| 1220 | 1); | 1229 | drm_connector_attach_property(&radeon_connector->base, |
| 1221 | drm_connector_attach_property(&radeon_connector->base, | 1230 | rdev->mode_info.tv_std_property, |
| 1222 | rdev->mode_info.tv_std_property, | 1231 | radeon_atombios_get_tv_info(rdev)); |
| 1223 | radeon_atombios_get_tv_info(rdev)); | 1232 | /* no HPD on analog connectors */ |
| 1224 | /* no HPD on analog connectors */ | 1233 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
| 1225 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
| 1226 | } | ||
| 1227 | break; | 1234 | break; |
| 1228 | case DRM_MODE_CONNECTOR_LVDS: | 1235 | case DRM_MODE_CONNECTOR_LVDS: |
| 1229 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1236 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
| 1230 | if (!radeon_dig_connector) | 1237 | if (!radeon_dig_connector) |
| 1231 | goto failed; | 1238 | goto failed; |
| 1232 | radeon_dig_connector->linkb = linkb; | ||
| 1233 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1239 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
| 1234 | radeon_connector->con_priv = radeon_dig_connector; | 1240 | radeon_connector->con_priv = radeon_dig_connector; |
| 1235 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 1241 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
| @@ -1275,10 +1281,16 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 1275 | struct radeon_connector *radeon_connector; | 1281 | struct radeon_connector *radeon_connector; |
| 1276 | uint32_t subpixel_order = SubPixelNone; | 1282 | uint32_t subpixel_order = SubPixelNone; |
| 1277 | 1283 | ||
| 1278 | /* fixme - tv/cv/din */ | ||
| 1279 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) | 1284 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
| 1280 | return; | 1285 | return; |
| 1281 | 1286 | ||
| 1287 | /* if the user selected tv=0 don't try and add the connector */ | ||
| 1288 | if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) || | ||
| 1289 | (connector_type == DRM_MODE_CONNECTOR_Composite) || | ||
| 1290 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) && | ||
| 1291 | (radeon_tv == 0)) | ||
| 1292 | return; | ||
| 1293 | |||
| 1282 | /* see if we already added it */ | 1294 | /* see if we already added it */ |
| 1283 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1295 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 1284 | radeon_connector = to_radeon_connector(connector); | 1296 | radeon_connector = to_radeon_connector(connector); |
| @@ -1350,26 +1362,24 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 1350 | case DRM_MODE_CONNECTOR_SVIDEO: | 1362 | case DRM_MODE_CONNECTOR_SVIDEO: |
| 1351 | case DRM_MODE_CONNECTOR_Composite: | 1363 | case DRM_MODE_CONNECTOR_Composite: |
| 1352 | case DRM_MODE_CONNECTOR_9PinDIN: | 1364 | case DRM_MODE_CONNECTOR_9PinDIN: |
| 1353 | if (radeon_tv == 1) { | 1365 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); |
| 1354 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); | 1366 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); |
| 1355 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); | 1367 | radeon_connector->dac_load_detect = true; |
| 1356 | radeon_connector->dac_load_detect = true; | 1368 | /* RS400,RC410,RS480 chipset seems to report a lot |
| 1357 | /* RS400,RC410,RS480 chipset seems to report a lot | 1369 | * of false positive on load detect, we haven't yet |
| 1358 | * of false positive on load detect, we haven't yet | 1370 | * found a way to make load detect reliable on those |
| 1359 | * found a way to make load detect reliable on those | 1371 | * chipset, thus just disable it for TV. |
| 1360 | * chipset, thus just disable it for TV. | 1372 | */ |
| 1361 | */ | 1373 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) |
| 1362 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) | 1374 | radeon_connector->dac_load_detect = false; |
| 1363 | radeon_connector->dac_load_detect = false; | 1375 | drm_connector_attach_property(&radeon_connector->base, |
| 1364 | drm_connector_attach_property(&radeon_connector->base, | 1376 | rdev->mode_info.load_detect_property, |
| 1365 | rdev->mode_info.load_detect_property, | 1377 | radeon_connector->dac_load_detect); |
| 1366 | radeon_connector->dac_load_detect); | 1378 | drm_connector_attach_property(&radeon_connector->base, |
| 1367 | drm_connector_attach_property(&radeon_connector->base, | 1379 | rdev->mode_info.tv_std_property, |
| 1368 | rdev->mode_info.tv_std_property, | 1380 | radeon_combios_get_tv_info(rdev)); |
| 1369 | radeon_combios_get_tv_info(rdev)); | 1381 | /* no HPD on analog connectors */ |
| 1370 | /* no HPD on analog connectors */ | 1382 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
| 1371 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
| 1372 | } | ||
| 1373 | break; | 1383 | break; |
| 1374 | case DRM_MODE_CONNECTOR_LVDS: | 1384 | case DRM_MODE_CONNECTOR_LVDS: |
| 1375 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 1385 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 4f7a170d1566..256d204a6d24 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -199,7 +199,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
| 199 | mc->mc_vram_size = mc->aper_size; | 199 | mc->mc_vram_size = mc->aper_size; |
| 200 | } | 200 | } |
| 201 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 201 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
| 202 | if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_end <= mc->gtt_end) { | 202 | if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_start <= mc->gtt_end) { |
| 203 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); | 203 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); |
| 204 | mc->real_vram_size = mc->aper_size; | 204 | mc->real_vram_size = mc->aper_size; |
| 205 | mc->mc_vram_size = mc->aper_size; | 205 | mc->mc_vram_size = mc->aper_size; |
| @@ -293,30 +293,20 @@ bool radeon_card_posted(struct radeon_device *rdev) | |||
| 293 | void radeon_update_bandwidth_info(struct radeon_device *rdev) | 293 | void radeon_update_bandwidth_info(struct radeon_device *rdev) |
| 294 | { | 294 | { |
| 295 | fixed20_12 a; | 295 | fixed20_12 a; |
| 296 | u32 sclk, mclk; | 296 | u32 sclk = rdev->pm.current_sclk; |
| 297 | u32 mclk = rdev->pm.current_mclk; | ||
| 297 | 298 | ||
| 298 | if (rdev->flags & RADEON_IS_IGP) { | 299 | /* sclk/mclk in Mhz */ |
| 299 | sclk = radeon_get_engine_clock(rdev); | 300 | a.full = dfixed_const(100); |
| 300 | mclk = rdev->clock.default_mclk; | 301 | rdev->pm.sclk.full = dfixed_const(sclk); |
| 301 | 302 | rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); | |
| 302 | a.full = dfixed_const(100); | 303 | rdev->pm.mclk.full = dfixed_const(mclk); |
| 303 | rdev->pm.sclk.full = dfixed_const(sclk); | 304 | rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); |
| 304 | rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); | ||
| 305 | rdev->pm.mclk.full = dfixed_const(mclk); | ||
| 306 | rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); | ||
| 307 | 305 | ||
| 306 | if (rdev->flags & RADEON_IS_IGP) { | ||
| 308 | a.full = dfixed_const(16); | 307 | a.full = dfixed_const(16); |
| 309 | /* core_bandwidth = sclk(Mhz) * 16 */ | 308 | /* core_bandwidth = sclk(Mhz) * 16 */ |
| 310 | rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a); | 309 | rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a); |
| 311 | } else { | ||
| 312 | sclk = radeon_get_engine_clock(rdev); | ||
| 313 | mclk = radeon_get_memory_clock(rdev); | ||
| 314 | |||
| 315 | a.full = dfixed_const(100); | ||
| 316 | rdev->pm.sclk.full = dfixed_const(sclk); | ||
| 317 | rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); | ||
| 318 | rdev->pm.mclk.full = dfixed_const(mclk); | ||
| 319 | rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); | ||
| 320 | } | 310 | } |
| 321 | } | 311 | } |
| 322 | 312 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 5764f4d3b4f1..b92d2f2fcbed 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -349,6 +349,8 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
| 349 | DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]); | 349 | DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]); |
| 350 | if (devices & ATOM_DEVICE_DFP5_SUPPORT) | 350 | if (devices & ATOM_DEVICE_DFP5_SUPPORT) |
| 351 | DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]); | 351 | DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]); |
| 352 | if (devices & ATOM_DEVICE_DFP6_SUPPORT) | ||
| 353 | DRM_INFO(" DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]); | ||
| 352 | if (devices & ATOM_DEVICE_TV1_SUPPORT) | 354 | if (devices & ATOM_DEVICE_TV1_SUPPORT) |
| 353 | DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]); | 355 | DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]); |
| 354 | if (devices & ATOM_DEVICE_CV_SUPPORT) | 356 | if (devices & ATOM_DEVICE_CV_SUPPORT) |
| @@ -841,8 +843,9 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) | |||
| 841 | { | 843 | { |
| 842 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); | 844 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); |
| 843 | 845 | ||
| 844 | if (radeon_fb->obj) | 846 | if (radeon_fb->obj) { |
| 845 | drm_gem_object_unreference_unlocked(radeon_fb->obj); | 847 | drm_gem_object_unreference_unlocked(radeon_fb->obj); |
| 848 | } | ||
| 846 | drm_framebuffer_cleanup(fb); | 849 | drm_framebuffer_cleanup(fb); |
| 847 | kfree(radeon_fb); | 850 | kfree(radeon_fb); |
| 848 | } | 851 | } |
| @@ -1094,6 +1097,18 @@ void radeon_modeset_fini(struct radeon_device *rdev) | |||
| 1094 | radeon_i2c_fini(rdev); | 1097 | radeon_i2c_fini(rdev); |
| 1095 | } | 1098 | } |
| 1096 | 1099 | ||
| 1100 | static bool is_hdtv_mode(struct drm_display_mode *mode) | ||
| 1101 | { | ||
| 1102 | /* try and guess if this is a tv or a monitor */ | ||
| 1103 | if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */ | ||
| 1104 | (mode->vdisplay == 576) || /* 576p */ | ||
| 1105 | (mode->vdisplay == 720) || /* 720p */ | ||
| 1106 | (mode->vdisplay == 1080)) /* 1080p */ | ||
| 1107 | return true; | ||
| 1108 | else | ||
| 1109 | return false; | ||
| 1110 | } | ||
| 1111 | |||
| 1097 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 1112 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
| 1098 | struct drm_display_mode *mode, | 1113 | struct drm_display_mode *mode, |
| 1099 | struct drm_display_mode *adjusted_mode) | 1114 | struct drm_display_mode *adjusted_mode) |
| @@ -1128,20 +1143,22 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
| 1128 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; | 1143 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; |
| 1129 | else | 1144 | else |
| 1130 | radeon_crtc->rmx_type = RMX_OFF; | 1145 | radeon_crtc->rmx_type = RMX_OFF; |
| 1131 | src_v = crtc->mode.vdisplay; | ||
| 1132 | dst_v = radeon_crtc->native_mode.vdisplay; | ||
| 1133 | src_h = crtc->mode.hdisplay; | ||
| 1134 | dst_h = radeon_crtc->native_mode.vdisplay; | ||
| 1135 | /* copy native mode */ | 1146 | /* copy native mode */ |
| 1136 | memcpy(&radeon_crtc->native_mode, | 1147 | memcpy(&radeon_crtc->native_mode, |
| 1137 | &radeon_encoder->native_mode, | 1148 | &radeon_encoder->native_mode, |
| 1138 | sizeof(struct drm_display_mode)); | 1149 | sizeof(struct drm_display_mode)); |
| 1150 | src_v = crtc->mode.vdisplay; | ||
| 1151 | dst_v = radeon_crtc->native_mode.vdisplay; | ||
| 1152 | src_h = crtc->mode.hdisplay; | ||
| 1153 | dst_h = radeon_crtc->native_mode.hdisplay; | ||
| 1139 | 1154 | ||
| 1140 | /* fix up for overscan on hdmi */ | 1155 | /* fix up for overscan on hdmi */ |
| 1141 | if (ASIC_IS_AVIVO(rdev) && | 1156 | if (ASIC_IS_AVIVO(rdev) && |
| 1157 | (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) && | ||
| 1142 | ((radeon_encoder->underscan_type == UNDERSCAN_ON) || | 1158 | ((radeon_encoder->underscan_type == UNDERSCAN_ON) || |
| 1143 | ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && | 1159 | ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && |
| 1144 | drm_detect_hdmi_monitor(radeon_connector->edid)))) { | 1160 | drm_detect_hdmi_monitor(radeon_connector->edid) && |
| 1161 | is_hdtv_mode(mode)))) { | ||
| 1145 | radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; | 1162 | radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; |
| 1146 | radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; | 1163 | radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; |
| 1147 | radeon_crtc->rmx_type = RMX_FULL; | 1164 | radeon_crtc->rmx_type = RMX_FULL; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 263c8098d7dd..2c293e8304d6 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
| @@ -81,7 +81,7 @@ void radeon_setup_encoder_clones(struct drm_device *dev) | |||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | uint32_t | 83 | uint32_t |
| 84 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) | 84 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac) |
| 85 | { | 85 | { |
| 86 | struct radeon_device *rdev = dev->dev_private; | 86 | struct radeon_device *rdev = dev->dev_private; |
| 87 | uint32_t ret = 0; | 87 | uint32_t ret = 0; |
| @@ -97,59 +97,59 @@ radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t | |||
| 97 | if ((rdev->family == CHIP_RS300) || | 97 | if ((rdev->family == CHIP_RS300) || |
| 98 | (rdev->family == CHIP_RS400) || | 98 | (rdev->family == CHIP_RS400) || |
| 99 | (rdev->family == CHIP_RS480)) | 99 | (rdev->family == CHIP_RS480)) |
| 100 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; | 100 | ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; |
| 101 | else if (ASIC_IS_AVIVO(rdev)) | 101 | else if (ASIC_IS_AVIVO(rdev)) |
| 102 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; | 102 | ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1; |
| 103 | else | 103 | else |
| 104 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC1; | 104 | ret = ENCODER_INTERNAL_DAC1_ENUM_ID1; |
| 105 | break; | 105 | break; |
| 106 | case 2: /* dac b */ | 106 | case 2: /* dac b */ |
| 107 | if (ASIC_IS_AVIVO(rdev)) | 107 | if (ASIC_IS_AVIVO(rdev)) |
| 108 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; | 108 | ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1; |
| 109 | else { | 109 | else { |
| 110 | /*if (rdev->family == CHIP_R200) | 110 | /*if (rdev->family == CHIP_R200) |
| 111 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 111 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
| 112 | else*/ | 112 | else*/ |
| 113 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; | 113 | ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; |
| 114 | } | 114 | } |
| 115 | break; | 115 | break; |
| 116 | case 3: /* external dac */ | 116 | case 3: /* external dac */ |
| 117 | if (ASIC_IS_AVIVO(rdev)) | 117 | if (ASIC_IS_AVIVO(rdev)) |
| 118 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; | 118 | ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; |
| 119 | else | 119 | else |
| 120 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 120 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
| 121 | break; | 121 | break; |
| 122 | } | 122 | } |
| 123 | break; | 123 | break; |
| 124 | case ATOM_DEVICE_LCD1_SUPPORT: | 124 | case ATOM_DEVICE_LCD1_SUPPORT: |
| 125 | if (ASIC_IS_AVIVO(rdev)) | 125 | if (ASIC_IS_AVIVO(rdev)) |
| 126 | ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; | 126 | ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; |
| 127 | else | 127 | else |
| 128 | ret = ENCODER_OBJECT_ID_INTERNAL_LVDS; | 128 | ret = ENCODER_INTERNAL_LVDS_ENUM_ID1; |
| 129 | break; | 129 | break; |
| 130 | case ATOM_DEVICE_DFP1_SUPPORT: | 130 | case ATOM_DEVICE_DFP1_SUPPORT: |
| 131 | if ((rdev->family == CHIP_RS300) || | 131 | if ((rdev->family == CHIP_RS300) || |
| 132 | (rdev->family == CHIP_RS400) || | 132 | (rdev->family == CHIP_RS400) || |
| 133 | (rdev->family == CHIP_RS480)) | 133 | (rdev->family == CHIP_RS480)) |
| 134 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 134 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
| 135 | else if (ASIC_IS_AVIVO(rdev)) | 135 | else if (ASIC_IS_AVIVO(rdev)) |
| 136 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1; | 136 | ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1; |
| 137 | else | 137 | else |
| 138 | ret = ENCODER_OBJECT_ID_INTERNAL_TMDS1; | 138 | ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1; |
| 139 | break; | 139 | break; |
| 140 | case ATOM_DEVICE_LCD2_SUPPORT: | 140 | case ATOM_DEVICE_LCD2_SUPPORT: |
| 141 | case ATOM_DEVICE_DFP2_SUPPORT: | 141 | case ATOM_DEVICE_DFP2_SUPPORT: |
| 142 | if ((rdev->family == CHIP_RS600) || | 142 | if ((rdev->family == CHIP_RS600) || |
| 143 | (rdev->family == CHIP_RS690) || | 143 | (rdev->family == CHIP_RS690) || |
| 144 | (rdev->family == CHIP_RS740)) | 144 | (rdev->family == CHIP_RS740)) |
| 145 | ret = ENCODER_OBJECT_ID_INTERNAL_DDI; | 145 | ret = ENCODER_INTERNAL_DDI_ENUM_ID1; |
| 146 | else if (ASIC_IS_AVIVO(rdev)) | 146 | else if (ASIC_IS_AVIVO(rdev)) |
| 147 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; | 147 | ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; |
| 148 | else | 148 | else |
| 149 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 149 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
| 150 | break; | 150 | break; |
| 151 | case ATOM_DEVICE_DFP3_SUPPORT: | 151 | case ATOM_DEVICE_DFP3_SUPPORT: |
| 152 | ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; | 152 | ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; |
| 153 | break; | 153 | break; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| @@ -228,32 +228,6 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
| 228 | return NULL; | 228 | return NULL; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | static struct radeon_connector_atom_dig * | ||
| 232 | radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder) | ||
| 233 | { | ||
| 234 | struct drm_device *dev = encoder->dev; | ||
| 235 | struct radeon_device *rdev = dev->dev_private; | ||
| 236 | struct drm_connector *connector; | ||
| 237 | struct radeon_connector *radeon_connector; | ||
| 238 | struct radeon_connector_atom_dig *dig_connector; | ||
| 239 | |||
| 240 | if (!rdev->is_atom_bios) | ||
| 241 | return NULL; | ||
| 242 | |||
| 243 | connector = radeon_get_connector_for_encoder(encoder); | ||
| 244 | if (!connector) | ||
| 245 | return NULL; | ||
| 246 | |||
| 247 | radeon_connector = to_radeon_connector(connector); | ||
| 248 | |||
| 249 | if (!radeon_connector->con_priv) | ||
| 250 | return NULL; | ||
| 251 | |||
| 252 | dig_connector = radeon_connector->con_priv; | ||
| 253 | |||
| 254 | return dig_connector; | ||
| 255 | } | ||
| 256 | |||
| 257 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | 231 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, |
| 258 | struct drm_display_mode *adjusted_mode) | 232 | struct drm_display_mode *adjusted_mode) |
| 259 | { | 233 | { |
| @@ -512,14 +486,12 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
| 512 | struct radeon_device *rdev = dev->dev_private; | 486 | struct radeon_device *rdev = dev->dev_private; |
| 513 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 487 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 514 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 488 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 515 | struct radeon_connector_atom_dig *dig_connector = | ||
| 516 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
| 517 | union lvds_encoder_control args; | 489 | union lvds_encoder_control args; |
| 518 | int index = 0; | 490 | int index = 0; |
| 519 | int hdmi_detected = 0; | 491 | int hdmi_detected = 0; |
| 520 | uint8_t frev, crev; | 492 | uint8_t frev, crev; |
| 521 | 493 | ||
| 522 | if (!dig || !dig_connector) | 494 | if (!dig) |
| 523 | return; | 495 | return; |
| 524 | 496 | ||
| 525 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | 497 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) |
| @@ -562,7 +534,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
| 562 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) | 534 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) |
| 563 | args.v1.ucMisc |= (1 << 1); | 535 | args.v1.ucMisc |= (1 << 1); |
| 564 | } else { | 536 | } else { |
| 565 | if (dig_connector->linkb) | 537 | if (dig->linkb) |
| 566 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 538 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
| 567 | if (radeon_encoder->pixel_clock > 165000) | 539 | if (radeon_encoder->pixel_clock > 165000) |
| 568 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 540 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
| @@ -601,7 +573,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
| 601 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; | 573 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; |
| 602 | } | 574 | } |
| 603 | } else { | 575 | } else { |
| 604 | if (dig_connector->linkb) | 576 | if (dig->linkb) |
| 605 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 577 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
| 606 | if (radeon_encoder->pixel_clock > 165000) | 578 | if (radeon_encoder->pixel_clock > 165000) |
| 607 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 579 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
| @@ -623,6 +595,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
| 623 | int | 595 | int |
| 624 | atombios_get_encoder_mode(struct drm_encoder *encoder) | 596 | atombios_get_encoder_mode(struct drm_encoder *encoder) |
| 625 | { | 597 | { |
| 598 | struct drm_device *dev = encoder->dev; | ||
| 599 | struct radeon_device *rdev = dev->dev_private; | ||
| 626 | struct drm_connector *connector; | 600 | struct drm_connector *connector; |
| 627 | struct radeon_connector *radeon_connector; | 601 | struct radeon_connector *radeon_connector; |
| 628 | struct radeon_connector_atom_dig *dig_connector; | 602 | struct radeon_connector_atom_dig *dig_connector; |
| @@ -636,9 +610,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 636 | switch (connector->connector_type) { | 610 | switch (connector->connector_type) { |
| 637 | case DRM_MODE_CONNECTOR_DVII: | 611 | case DRM_MODE_CONNECTOR_DVII: |
| 638 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | 612 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
| 639 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 613 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
| 640 | return ATOM_ENCODER_MODE_HDMI; | 614 | /* fix me */ |
| 641 | else if (radeon_connector->use_digital) | 615 | if (ASIC_IS_DCE4(rdev)) |
| 616 | return ATOM_ENCODER_MODE_DVI; | ||
| 617 | else | ||
| 618 | return ATOM_ENCODER_MODE_HDMI; | ||
| 619 | } else if (radeon_connector->use_digital) | ||
| 642 | return ATOM_ENCODER_MODE_DVI; | 620 | return ATOM_ENCODER_MODE_DVI; |
| 643 | else | 621 | else |
| 644 | return ATOM_ENCODER_MODE_CRT; | 622 | return ATOM_ENCODER_MODE_CRT; |
| @@ -646,9 +624,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 646 | case DRM_MODE_CONNECTOR_DVID: | 624 | case DRM_MODE_CONNECTOR_DVID: |
| 647 | case DRM_MODE_CONNECTOR_HDMIA: | 625 | case DRM_MODE_CONNECTOR_HDMIA: |
| 648 | default: | 626 | default: |
| 649 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 627 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
| 650 | return ATOM_ENCODER_MODE_HDMI; | 628 | /* fix me */ |
| 651 | else | 629 | if (ASIC_IS_DCE4(rdev)) |
| 630 | return ATOM_ENCODER_MODE_DVI; | ||
| 631 | else | ||
| 632 | return ATOM_ENCODER_MODE_HDMI; | ||
| 633 | } else | ||
| 652 | return ATOM_ENCODER_MODE_DVI; | 634 | return ATOM_ENCODER_MODE_DVI; |
| 653 | break; | 635 | break; |
| 654 | case DRM_MODE_CONNECTOR_LVDS: | 636 | case DRM_MODE_CONNECTOR_LVDS: |
| @@ -660,9 +642,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 660 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 642 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
| 661 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | 643 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
| 662 | return ATOM_ENCODER_MODE_DP; | 644 | return ATOM_ENCODER_MODE_DP; |
| 663 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 645 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
| 664 | return ATOM_ENCODER_MODE_HDMI; | 646 | /* fix me */ |
| 665 | else | 647 | if (ASIC_IS_DCE4(rdev)) |
| 648 | return ATOM_ENCODER_MODE_DVI; | ||
| 649 | else | ||
| 650 | return ATOM_ENCODER_MODE_HDMI; | ||
| 651 | } else | ||
| 666 | return ATOM_ENCODER_MODE_DVI; | 652 | return ATOM_ENCODER_MODE_DVI; |
| 667 | break; | 653 | break; |
| 668 | case DRM_MODE_CONNECTOR_DVIA: | 654 | case DRM_MODE_CONNECTOR_DVIA: |
| @@ -729,13 +715,24 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
| 729 | struct radeon_device *rdev = dev->dev_private; | 715 | struct radeon_device *rdev = dev->dev_private; |
| 730 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 716 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 731 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 717 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 732 | struct radeon_connector_atom_dig *dig_connector = | 718 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 733 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
| 734 | union dig_encoder_control args; | 719 | union dig_encoder_control args; |
| 735 | int index = 0; | 720 | int index = 0; |
| 736 | uint8_t frev, crev; | 721 | uint8_t frev, crev; |
| 722 | int dp_clock = 0; | ||
| 723 | int dp_lane_count = 0; | ||
| 724 | |||
| 725 | if (connector) { | ||
| 726 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 727 | struct radeon_connector_atom_dig *dig_connector = | ||
| 728 | radeon_connector->con_priv; | ||
| 737 | 729 | ||
| 738 | if (!dig || !dig_connector) | 730 | dp_clock = dig_connector->dp_clock; |
| 731 | dp_lane_count = dig_connector->dp_lane_count; | ||
| 732 | } | ||
| 733 | |||
| 734 | /* no dig encoder assigned */ | ||
| 735 | if (dig->dig_encoder == -1) | ||
| 739 | return; | 736 | return; |
| 740 | 737 | ||
| 741 | memset(&args, 0, sizeof(args)); | 738 | memset(&args, 0, sizeof(args)); |
| @@ -757,9 +754,9 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
| 757 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | 754 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); |
| 758 | 755 | ||
| 759 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | 756 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { |
| 760 | if (dig_connector->dp_clock == 270000) | 757 | if (dp_clock == 270000) |
| 761 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | 758 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
| 762 | args.v1.ucLaneNum = dig_connector->dp_lane_count; | 759 | args.v1.ucLaneNum = dp_lane_count; |
| 763 | } else if (radeon_encoder->pixel_clock > 165000) | 760 | } else if (radeon_encoder->pixel_clock > 165000) |
| 764 | args.v1.ucLaneNum = 8; | 761 | args.v1.ucLaneNum = 8; |
| 765 | else | 762 | else |
| @@ -781,7 +778,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
| 781 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | 778 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; |
| 782 | break; | 779 | break; |
| 783 | } | 780 | } |
| 784 | if (dig_connector->linkb) | 781 | if (dig->linkb) |
| 785 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | 782 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; |
| 786 | else | 783 | else |
| 787 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | 784 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; |
| @@ -804,38 +801,47 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 804 | struct radeon_device *rdev = dev->dev_private; | 801 | struct radeon_device *rdev = dev->dev_private; |
| 805 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 802 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 806 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 803 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 807 | struct radeon_connector_atom_dig *dig_connector = | 804 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 808 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
| 809 | struct drm_connector *connector; | ||
| 810 | struct radeon_connector *radeon_connector; | ||
| 811 | union dig_transmitter_control args; | 805 | union dig_transmitter_control args; |
| 812 | int index = 0; | 806 | int index = 0; |
| 813 | uint8_t frev, crev; | 807 | uint8_t frev, crev; |
| 814 | bool is_dp = false; | 808 | bool is_dp = false; |
| 815 | int pll_id = 0; | 809 | int pll_id = 0; |
| 810 | int dp_clock = 0; | ||
| 811 | int dp_lane_count = 0; | ||
| 812 | int connector_object_id = 0; | ||
| 813 | int igp_lane_info = 0; | ||
| 816 | 814 | ||
| 817 | if (!dig || !dig_connector) | 815 | if (connector) { |
| 818 | return; | 816 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 817 | struct radeon_connector_atom_dig *dig_connector = | ||
| 818 | radeon_connector->con_priv; | ||
| 819 | 819 | ||
| 820 | connector = radeon_get_connector_for_encoder(encoder); | 820 | dp_clock = dig_connector->dp_clock; |
| 821 | radeon_connector = to_radeon_connector(connector); | 821 | dp_lane_count = dig_connector->dp_lane_count; |
| 822 | connector_object_id = | ||
| 823 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
| 824 | igp_lane_info = dig_connector->igp_lane_info; | ||
| 825 | } | ||
| 826 | |||
| 827 | /* no dig encoder assigned */ | ||
| 828 | if (dig->dig_encoder == -1) | ||
| 829 | return; | ||
| 822 | 830 | ||
| 823 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) | 831 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) |
| 824 | is_dp = true; | 832 | is_dp = true; |
| 825 | 833 | ||
| 826 | memset(&args, 0, sizeof(args)); | 834 | memset(&args, 0, sizeof(args)); |
| 827 | 835 | ||
| 828 | if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev)) | 836 | switch (radeon_encoder->encoder_id) { |
| 837 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 838 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 839 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 829 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | 840 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); |
| 830 | else { | 841 | break; |
| 831 | switch (radeon_encoder->encoder_id) { | 842 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
| 832 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 843 | index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl); |
| 833 | index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl); | 844 | break; |
| 834 | break; | ||
| 835 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 836 | index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl); | ||
| 837 | break; | ||
| 838 | } | ||
| 839 | } | 845 | } |
| 840 | 846 | ||
| 841 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | 847 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
| @@ -843,14 +849,14 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 843 | 849 | ||
| 844 | args.v1.ucAction = action; | 850 | args.v1.ucAction = action; |
| 845 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | 851 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { |
| 846 | args.v1.usInitInfo = radeon_connector->connector_object_id; | 852 | args.v1.usInitInfo = connector_object_id; |
| 847 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | 853 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { |
| 848 | args.v1.asMode.ucLaneSel = lane_num; | 854 | args.v1.asMode.ucLaneSel = lane_num; |
| 849 | args.v1.asMode.ucLaneSet = lane_set; | 855 | args.v1.asMode.ucLaneSet = lane_set; |
| 850 | } else { | 856 | } else { |
| 851 | if (is_dp) | 857 | if (is_dp) |
| 852 | args.v1.usPixelClock = | 858 | args.v1.usPixelClock = |
| 853 | cpu_to_le16(dig_connector->dp_clock / 10); | 859 | cpu_to_le16(dp_clock / 10); |
| 854 | else if (radeon_encoder->pixel_clock > 165000) | 860 | else if (radeon_encoder->pixel_clock > 165000) |
| 855 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 861 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
| 856 | else | 862 | else |
| @@ -858,13 +864,13 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 858 | } | 864 | } |
| 859 | if (ASIC_IS_DCE4(rdev)) { | 865 | if (ASIC_IS_DCE4(rdev)) { |
| 860 | if (is_dp) | 866 | if (is_dp) |
| 861 | args.v3.ucLaneNum = dig_connector->dp_lane_count; | 867 | args.v3.ucLaneNum = dp_lane_count; |
| 862 | else if (radeon_encoder->pixel_clock > 165000) | 868 | else if (radeon_encoder->pixel_clock > 165000) |
| 863 | args.v3.ucLaneNum = 8; | 869 | args.v3.ucLaneNum = 8; |
| 864 | else | 870 | else |
| 865 | args.v3.ucLaneNum = 4; | 871 | args.v3.ucLaneNum = 4; |
| 866 | 872 | ||
| 867 | if (dig_connector->linkb) { | 873 | if (dig->linkb) { |
| 868 | args.v3.acConfig.ucLinkSel = 1; | 874 | args.v3.acConfig.ucLinkSel = 1; |
| 869 | args.v3.acConfig.ucEncoderSel = 1; | 875 | args.v3.acConfig.ucEncoderSel = 1; |
| 870 | } | 876 | } |
| @@ -904,7 +910,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 904 | } | 910 | } |
| 905 | } else if (ASIC_IS_DCE32(rdev)) { | 911 | } else if (ASIC_IS_DCE32(rdev)) { |
| 906 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; | 912 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; |
| 907 | if (dig_connector->linkb) | 913 | if (dig->linkb) |
| 908 | args.v2.acConfig.ucLinkSel = 1; | 914 | args.v2.acConfig.ucLinkSel = 1; |
| 909 | 915 | ||
| 910 | switch (radeon_encoder->encoder_id) { | 916 | switch (radeon_encoder->encoder_id) { |
| @@ -938,23 +944,23 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 938 | if ((rdev->flags & RADEON_IS_IGP) && | 944 | if ((rdev->flags & RADEON_IS_IGP) && |
| 939 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | 945 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { |
| 940 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | 946 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { |
| 941 | if (dig_connector->igp_lane_info & 0x1) | 947 | if (igp_lane_info & 0x1) |
| 942 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 948 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
| 943 | else if (dig_connector->igp_lane_info & 0x2) | 949 | else if (igp_lane_info & 0x2) |
| 944 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; | 950 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; |
| 945 | else if (dig_connector->igp_lane_info & 0x4) | 951 | else if (igp_lane_info & 0x4) |
| 946 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; | 952 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; |
| 947 | else if (dig_connector->igp_lane_info & 0x8) | 953 | else if (igp_lane_info & 0x8) |
| 948 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | 954 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; |
| 949 | } else { | 955 | } else { |
| 950 | if (dig_connector->igp_lane_info & 0x3) | 956 | if (igp_lane_info & 0x3) |
| 951 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | 957 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; |
| 952 | else if (dig_connector->igp_lane_info & 0xc) | 958 | else if (igp_lane_info & 0xc) |
| 953 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | 959 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; |
| 954 | } | 960 | } |
| 955 | } | 961 | } |
| 956 | 962 | ||
| 957 | if (dig_connector->linkb) | 963 | if (dig->linkb) |
| 958 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | 964 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; |
| 959 | else | 965 | else |
| 960 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | 966 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; |
| @@ -1072,8 +1078,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 1072 | if (is_dig) { | 1078 | if (is_dig) { |
| 1073 | switch (mode) { | 1079 | switch (mode) { |
| 1074 | case DRM_MODE_DPMS_ON: | 1080 | case DRM_MODE_DPMS_ON: |
| 1075 | if (!ASIC_IS_DCE4(rdev)) | 1081 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
| 1076 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
| 1077 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1082 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
| 1078 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1083 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 1079 | 1084 | ||
| @@ -1085,8 +1090,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 1085 | case DRM_MODE_DPMS_STANDBY: | 1090 | case DRM_MODE_DPMS_STANDBY: |
| 1086 | case DRM_MODE_DPMS_SUSPEND: | 1091 | case DRM_MODE_DPMS_SUSPEND: |
| 1087 | case DRM_MODE_DPMS_OFF: | 1092 | case DRM_MODE_DPMS_OFF: |
| 1088 | if (!ASIC_IS_DCE4(rdev)) | 1093 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
| 1089 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
| 1090 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1094 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
| 1091 | if (ASIC_IS_DCE4(rdev)) | 1095 | if (ASIC_IS_DCE4(rdev)) |
| 1092 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); | 1096 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); |
| @@ -1290,24 +1294,22 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
| 1290 | uint32_t dig_enc_in_use = 0; | 1294 | uint32_t dig_enc_in_use = 0; |
| 1291 | 1295 | ||
| 1292 | if (ASIC_IS_DCE4(rdev)) { | 1296 | if (ASIC_IS_DCE4(rdev)) { |
| 1293 | struct radeon_connector_atom_dig *dig_connector = | 1297 | dig = radeon_encoder->enc_priv; |
| 1294 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
| 1295 | |||
| 1296 | switch (radeon_encoder->encoder_id) { | 1298 | switch (radeon_encoder->encoder_id) { |
| 1297 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 1299 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
| 1298 | if (dig_connector->linkb) | 1300 | if (dig->linkb) |
| 1299 | return 1; | 1301 | return 1; |
| 1300 | else | 1302 | else |
| 1301 | return 0; | 1303 | return 0; |
| 1302 | break; | 1304 | break; |
| 1303 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1305 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 1304 | if (dig_connector->linkb) | 1306 | if (dig->linkb) |
| 1305 | return 3; | 1307 | return 3; |
| 1306 | else | 1308 | else |
| 1307 | return 2; | 1309 | return 2; |
| 1308 | break; | 1310 | break; |
| 1309 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1311 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 1310 | if (dig_connector->linkb) | 1312 | if (dig->linkb) |
| 1311 | return 5; | 1313 | return 5; |
| 1312 | else | 1314 | else |
| 1313 | return 4; | 1315 | return 4; |
| @@ -1641,6 +1643,7 @@ radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | |||
| 1641 | struct radeon_encoder_atom_dig * | 1643 | struct radeon_encoder_atom_dig * |
| 1642 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | 1644 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) |
| 1643 | { | 1645 | { |
| 1646 | int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
| 1644 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); | 1647 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); |
| 1645 | 1648 | ||
| 1646 | if (!dig) | 1649 | if (!dig) |
| @@ -1650,11 +1653,16 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | |||
| 1650 | dig->coherent_mode = true; | 1653 | dig->coherent_mode = true; |
| 1651 | dig->dig_encoder = -1; | 1654 | dig->dig_encoder = -1; |
| 1652 | 1655 | ||
| 1656 | if (encoder_enum == 2) | ||
| 1657 | dig->linkb = true; | ||
| 1658 | else | ||
| 1659 | dig->linkb = false; | ||
| 1660 | |||
| 1653 | return dig; | 1661 | return dig; |
| 1654 | } | 1662 | } |
| 1655 | 1663 | ||
| 1656 | void | 1664 | void |
| 1657 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) | 1665 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) |
| 1658 | { | 1666 | { |
| 1659 | struct radeon_device *rdev = dev->dev_private; | 1667 | struct radeon_device *rdev = dev->dev_private; |
| 1660 | struct drm_encoder *encoder; | 1668 | struct drm_encoder *encoder; |
| @@ -1663,7 +1671,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
| 1663 | /* see if we already added it */ | 1671 | /* see if we already added it */ |
| 1664 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1672 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 1665 | radeon_encoder = to_radeon_encoder(encoder); | 1673 | radeon_encoder = to_radeon_encoder(encoder); |
| 1666 | if (radeon_encoder->encoder_id == encoder_id) { | 1674 | if (radeon_encoder->encoder_enum == encoder_enum) { |
| 1667 | radeon_encoder->devices |= supported_device; | 1675 | radeon_encoder->devices |= supported_device; |
| 1668 | return; | 1676 | return; |
| 1669 | } | 1677 | } |
| @@ -1691,7 +1699,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
| 1691 | 1699 | ||
| 1692 | radeon_encoder->enc_priv = NULL; | 1700 | radeon_encoder->enc_priv = NULL; |
| 1693 | 1701 | ||
| 1694 | radeon_encoder->encoder_id = encoder_id; | 1702 | radeon_encoder->encoder_enum = encoder_enum; |
| 1703 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
| 1695 | radeon_encoder->devices = supported_device; | 1704 | radeon_encoder->devices = supported_device; |
| 1696 | radeon_encoder->rmx_type = RMX_OFF; | 1705 | radeon_encoder->rmx_type = RMX_OFF; |
| 1697 | radeon_encoder->underscan_type = UNDERSCAN_OFF; | 1706 | radeon_encoder->underscan_type = UNDERSCAN_OFF; |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index dbf86962bdd1..40b0c087b592 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
| @@ -94,6 +94,7 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) | |||
| 94 | ret = radeon_bo_reserve(rbo, false); | 94 | ret = radeon_bo_reserve(rbo, false); |
| 95 | if (likely(ret == 0)) { | 95 | if (likely(ret == 0)) { |
| 96 | radeon_bo_kunmap(rbo); | 96 | radeon_bo_kunmap(rbo); |
| 97 | radeon_bo_unpin(rbo); | ||
| 97 | radeon_bo_unreserve(rbo); | 98 | radeon_bo_unreserve(rbo); |
| 98 | } | 99 | } |
| 99 | drm_gem_object_unreference_unlocked(gobj); | 100 | drm_gem_object_unreference_unlocked(gobj); |
| @@ -118,7 +119,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, | |||
| 118 | aligned_size = ALIGN(size, PAGE_SIZE); | 119 | aligned_size = ALIGN(size, PAGE_SIZE); |
| 119 | ret = radeon_gem_object_create(rdev, aligned_size, 0, | 120 | ret = radeon_gem_object_create(rdev, aligned_size, 0, |
| 120 | RADEON_GEM_DOMAIN_VRAM, | 121 | RADEON_GEM_DOMAIN_VRAM, |
| 121 | false, ttm_bo_type_kernel, | 122 | false, true, |
| 122 | &gobj); | 123 | &gobj); |
| 123 | if (ret) { | 124 | if (ret) { |
| 124 | printk(KERN_ERR "failed to allocate framebuffer (%d)\n", | 125 | printk(KERN_ERR "failed to allocate framebuffer (%d)\n", |
| @@ -325,8 +326,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb | |||
| 325 | { | 326 | { |
| 326 | struct fb_info *info; | 327 | struct fb_info *info; |
| 327 | struct radeon_framebuffer *rfb = &rfbdev->rfb; | 328 | struct radeon_framebuffer *rfb = &rfbdev->rfb; |
| 328 | struct radeon_bo *rbo; | ||
| 329 | int r; | ||
| 330 | 329 | ||
| 331 | if (rfbdev->helper.fbdev) { | 330 | if (rfbdev->helper.fbdev) { |
| 332 | info = rfbdev->helper.fbdev; | 331 | info = rfbdev->helper.fbdev; |
| @@ -338,14 +337,8 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb | |||
| 338 | } | 337 | } |
| 339 | 338 | ||
| 340 | if (rfb->obj) { | 339 | if (rfb->obj) { |
| 341 | rbo = rfb->obj->driver_private; | 340 | radeonfb_destroy_pinned_object(rfb->obj); |
| 342 | r = radeon_bo_reserve(rbo, false); | 341 | rfb->obj = NULL; |
| 343 | if (likely(r == 0)) { | ||
| 344 | radeon_bo_kunmap(rbo); | ||
| 345 | radeon_bo_unpin(rbo); | ||
| 346 | radeon_bo_unreserve(rbo); | ||
| 347 | } | ||
| 348 | drm_gem_object_unreference_unlocked(rfb->obj); | ||
| 349 | } | 342 | } |
| 350 | drm_fb_helper_fini(&rfbdev->helper); | 343 | drm_fb_helper_fini(&rfbdev->helper); |
| 351 | drm_framebuffer_cleanup(&rfb->base); | 344 | drm_framebuffer_cleanup(&rfb->base); |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index c578f265b24c..d1e595d91723 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
| @@ -201,11 +201,11 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, | |||
| 201 | return r; | 201 | return r; |
| 202 | } | 202 | } |
| 203 | r = drm_gem_handle_create(filp, gobj, &handle); | 203 | r = drm_gem_handle_create(filp, gobj, &handle); |
| 204 | /* drop reference from allocate - handle holds it now */ | ||
| 205 | drm_gem_object_unreference_unlocked(gobj); | ||
| 204 | if (r) { | 206 | if (r) { |
| 205 | drm_gem_object_unreference_unlocked(gobj); | ||
| 206 | return r; | 207 | return r; |
| 207 | } | 208 | } |
| 208 | drm_gem_object_handle_unreference_unlocked(gobj); | ||
| 209 | args->handle = handle; | 209 | args->handle = handle; |
| 210 | return 0; | 210 | return 0; |
| 211 | } | 211 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index bfd2ce5f5372..6a13ee38a5b9 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
| @@ -99,6 +99,13 @@ static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) | |||
| 99 | } | 99 | } |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | /* switch the pads to ddc mode */ | ||
| 103 | if (ASIC_IS_DCE3(rdev) && rec->hw_capable) { | ||
| 104 | temp = RREG32(rec->mask_clk_reg); | ||
| 105 | temp &= ~(1 << 16); | ||
| 106 | WREG32(rec->mask_clk_reg, temp); | ||
| 107 | } | ||
| 108 | |||
| 102 | /* clear the output pin values */ | 109 | /* clear the output pin values */ |
| 103 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; | 110 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; |
| 104 | WREG32(rec->a_clk_reg, temp); | 111 | WREG32(rec->a_clk_reg, temp); |
| @@ -206,7 +213,7 @@ static void post_xfer(struct i2c_adapter *i2c_adap) | |||
| 206 | 213 | ||
| 207 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) | 214 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) |
| 208 | { | 215 | { |
| 209 | u32 sclk = radeon_get_engine_clock(rdev); | 216 | u32 sclk = rdev->pm.current_sclk; |
| 210 | u32 prescale = 0; | 217 | u32 prescale = 0; |
| 211 | u32 nm; | 218 | u32 nm; |
| 212 | u8 n, m, loop; | 219 | u8 n, m, loop; |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 059bfa4098d7..a108c7ed14f5 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
| @@ -121,11 +121,12 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
| 121 | * chips. Disable MSI on them for now. | 121 | * chips. Disable MSI on them for now. |
| 122 | */ | 122 | */ |
| 123 | if ((rdev->family >= CHIP_RV380) && | 123 | if ((rdev->family >= CHIP_RV380) && |
| 124 | (!(rdev->flags & RADEON_IS_IGP))) { | 124 | (!(rdev->flags & RADEON_IS_IGP)) && |
| 125 | (!(rdev->flags & RADEON_IS_AGP))) { | ||
| 125 | int ret = pci_enable_msi(rdev->pdev); | 126 | int ret = pci_enable_msi(rdev->pdev); |
| 126 | if (!ret) { | 127 | if (!ret) { |
| 127 | rdev->msi_enabled = 1; | 128 | rdev->msi_enabled = 1; |
| 128 | DRM_INFO("radeon: using MSI.\n"); | 129 | dev_info(rdev->dev, "radeon: using MSI.\n"); |
| 129 | } | 130 | } |
| 130 | } | 131 | } |
| 131 | rdev->irq.installed = true; | 132 | rdev->irq.installed = true; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index b1c8ace5f080..8fbbe1c6ebbd 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -161,6 +161,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 161 | DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); | 161 | DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); |
| 162 | return -EINVAL; | 162 | return -EINVAL; |
| 163 | } | 163 | } |
| 164 | break; | ||
| 164 | case RADEON_INFO_WANT_HYPERZ: | 165 | case RADEON_INFO_WANT_HYPERZ: |
| 165 | /* The "value" here is both an input and output parameter. | 166 | /* The "value" here is both an input and output parameter. |
| 166 | * If the input value is 1, filp requests hyper-z access. | 167 | * If the input value is 1, filp requests hyper-z access. |
| @@ -202,6 +203,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 202 | */ | 203 | */ |
| 203 | int radeon_driver_firstopen_kms(struct drm_device *dev) | 204 | int radeon_driver_firstopen_kms(struct drm_device *dev) |
| 204 | { | 205 | { |
| 206 | struct radeon_device *rdev = dev->dev_private; | ||
| 207 | |||
| 208 | if (rdev->powered_down) | ||
| 209 | return -EINVAL; | ||
| 205 | return 0; | 210 | return 0; |
| 206 | } | 211 | } |
| 207 | 212 | ||
| @@ -323,45 +328,45 @@ KMS_INVALID_IOCTL(radeon_surface_free_kms) | |||
| 323 | 328 | ||
| 324 | 329 | ||
| 325 | struct drm_ioctl_desc radeon_ioctls_kms[] = { | 330 | struct drm_ioctl_desc radeon_ioctls_kms[] = { |
| 326 | DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 331 | DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 327 | DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 332 | DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 328 | DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 333 | DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 329 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 334 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 330 | DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH), | 335 | DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH), |
| 331 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH), | 336 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH), |
| 332 | DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH), | 337 | DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH), |
| 333 | DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH), | 338 | DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH), |
| 334 | DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH), | 339 | DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH), |
| 335 | DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH), | 340 | DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH), |
| 336 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH), | 341 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH), |
| 337 | DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH), | 342 | DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH), |
| 338 | DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH), | 343 | DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH), |
| 339 | DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH), | 344 | DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH), |
| 340 | DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 345 | DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 341 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH), | 346 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH), |
| 342 | DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH), | 347 | DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH), |
| 343 | DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH), | 348 | DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH), |
| 344 | DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH), | 349 | DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH), |
| 345 | DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH), | 350 | DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH), |
| 346 | DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free_kms, DRM_AUTH), | 351 | DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free_kms, DRM_AUTH), |
| 347 | DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 352 | DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 348 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH), | 353 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH), |
| 349 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH), | 354 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH), |
| 350 | DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH), | 355 | DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH), |
| 351 | DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH), | 356 | DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH), |
| 352 | DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH), | 357 | DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH), |
| 353 | /* KMS */ | 358 | /* KMS */ |
| 354 | DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED), | 359 | DRM_IOCTL_DEF_DRV(RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 355 | DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED), | 360 | DRM_IOCTL_DEF_DRV(RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 356 | DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED), | 361 | DRM_IOCTL_DEF_DRV(RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 357 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED), | 362 | DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 358 | DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED), | 363 | DRM_IOCTL_DEF_DRV(RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 359 | DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED), | 364 | DRM_IOCTL_DEF_DRV(RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 360 | DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED), | 365 | DRM_IOCTL_DEF_DRV(RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 361 | DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED), | 366 | DRM_IOCTL_DEF_DRV(RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 362 | DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED), | 367 | DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 363 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), | 368 | DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 364 | DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), | 369 | DRM_IOCTL_DEF_DRV(RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 365 | DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), | 370 | DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), |
| 366 | }; | 371 | }; |
| 367 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); | 372 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 989df519a1e4..305049afde15 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
| @@ -272,7 +272,7 @@ static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div, | |||
| 272 | if (!ref_div) | 272 | if (!ref_div) |
| 273 | return 1; | 273 | return 1; |
| 274 | 274 | ||
| 275 | vcoFreq = ((unsigned)ref_freq & fb_div) / ref_div; | 275 | vcoFreq = ((unsigned)ref_freq * fb_div) / ref_div; |
| 276 | 276 | ||
| 277 | /* | 277 | /* |
| 278 | * This is horribly crude: the VCO frequency range is divided into | 278 | * This is horribly crude: the VCO frequency range is divided into |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index b8149cbc0c70..0b8397000f4c 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
| @@ -1345,7 +1345,7 @@ static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct ra | |||
| 1345 | } | 1345 | } |
| 1346 | 1346 | ||
| 1347 | void | 1347 | void |
| 1348 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) | 1348 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) |
| 1349 | { | 1349 | { |
| 1350 | struct radeon_device *rdev = dev->dev_private; | 1350 | struct radeon_device *rdev = dev->dev_private; |
| 1351 | struct drm_encoder *encoder; | 1351 | struct drm_encoder *encoder; |
| @@ -1354,7 +1354,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
| 1354 | /* see if we already added it */ | 1354 | /* see if we already added it */ |
| 1355 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1355 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 1356 | radeon_encoder = to_radeon_encoder(encoder); | 1356 | radeon_encoder = to_radeon_encoder(encoder); |
| 1357 | if (radeon_encoder->encoder_id == encoder_id) { | 1357 | if (radeon_encoder->encoder_enum == encoder_enum) { |
| 1358 | radeon_encoder->devices |= supported_device; | 1358 | radeon_encoder->devices |= supported_device; |
| 1359 | return; | 1359 | return; |
| 1360 | } | 1360 | } |
| @@ -1374,7 +1374,8 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
| 1374 | 1374 | ||
| 1375 | radeon_encoder->enc_priv = NULL; | 1375 | radeon_encoder->enc_priv = NULL; |
| 1376 | 1376 | ||
| 1377 | radeon_encoder->encoder_id = encoder_id; | 1377 | radeon_encoder->encoder_enum = encoder_enum; |
| 1378 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
| 1378 | radeon_encoder->devices = supported_device; | 1379 | radeon_encoder->devices = supported_device; |
| 1379 | radeon_encoder->rmx_type = RMX_OFF; | 1380 | radeon_encoder->rmx_type = RMX_OFF; |
| 1380 | 1381 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 5bbc086b9267..17a6602b5885 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -204,7 +204,7 @@ struct radeon_i2c_chan { | |||
| 204 | 204 | ||
| 205 | /* mostly for macs, but really any system without connector tables */ | 205 | /* mostly for macs, but really any system without connector tables */ |
| 206 | enum radeon_connector_table { | 206 | enum radeon_connector_table { |
| 207 | CT_NONE, | 207 | CT_NONE = 0, |
| 208 | CT_GENERIC, | 208 | CT_GENERIC, |
| 209 | CT_IBOOK, | 209 | CT_IBOOK, |
| 210 | CT_POWERBOOK_EXTERNAL, | 210 | CT_POWERBOOK_EXTERNAL, |
| @@ -215,6 +215,7 @@ enum radeon_connector_table { | |||
| 215 | CT_IMAC_G5_ISIGHT, | 215 | CT_IMAC_G5_ISIGHT, |
| 216 | CT_EMAC, | 216 | CT_EMAC, |
| 217 | CT_RN50_POWER, | 217 | CT_RN50_POWER, |
| 218 | CT_MAC_X800, | ||
| 218 | }; | 219 | }; |
| 219 | 220 | ||
| 220 | enum radeon_dvo_chip { | 221 | enum radeon_dvo_chip { |
| @@ -342,6 +343,7 @@ struct radeon_atom_ss { | |||
| 342 | }; | 343 | }; |
| 343 | 344 | ||
| 344 | struct radeon_encoder_atom_dig { | 345 | struct radeon_encoder_atom_dig { |
| 346 | bool linkb; | ||
| 345 | /* atom dig */ | 347 | /* atom dig */ |
| 346 | bool coherent_mode; | 348 | bool coherent_mode; |
| 347 | int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */ | 349 | int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */ |
| @@ -360,6 +362,7 @@ struct radeon_encoder_atom_dac { | |||
| 360 | 362 | ||
| 361 | struct radeon_encoder { | 363 | struct radeon_encoder { |
| 362 | struct drm_encoder base; | 364 | struct drm_encoder base; |
| 365 | uint32_t encoder_enum; | ||
| 363 | uint32_t encoder_id; | 366 | uint32_t encoder_id; |
| 364 | uint32_t devices; | 367 | uint32_t devices; |
| 365 | uint32_t active_device; | 368 | uint32_t active_device; |
| @@ -378,7 +381,6 @@ struct radeon_encoder { | |||
| 378 | 381 | ||
| 379 | struct radeon_connector_atom_dig { | 382 | struct radeon_connector_atom_dig { |
| 380 | uint32_t igp_lane_info; | 383 | uint32_t igp_lane_info; |
| 381 | bool linkb; | ||
| 382 | /* displayport */ | 384 | /* displayport */ |
| 383 | struct radeon_i2c_chan *dp_i2c_bus; | 385 | struct radeon_i2c_chan *dp_i2c_bus; |
| 384 | u8 dpcd[8]; | 386 | u8 dpcd[8]; |
| @@ -599,7 +601,6 @@ extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct d | |||
| 599 | void radeon_enc_destroy(struct drm_encoder *encoder); | 601 | void radeon_enc_destroy(struct drm_encoder *encoder); |
| 600 | void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); | 602 | void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); |
| 601 | void radeon_combios_asic_init(struct drm_device *dev); | 603 | void radeon_combios_asic_init(struct drm_device *dev); |
| 602 | extern int radeon_static_clocks_init(struct drm_device *dev); | ||
| 603 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 604 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
| 604 | struct drm_display_mode *mode, | 605 | struct drm_display_mode *mode, |
| 605 | struct drm_display_mode *adjusted_mode); | 606 | struct drm_display_mode *adjusted_mode); |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 58038f5cab38..f87efec76236 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
| @@ -226,6 +226,11 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) | |||
| 226 | { | 226 | { |
| 227 | int i; | 227 | int i; |
| 228 | 228 | ||
| 229 | /* no need to take locks, etc. if nothing's going to change */ | ||
| 230 | if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && | ||
| 231 | (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) | ||
| 232 | return; | ||
| 233 | |||
| 229 | mutex_lock(&rdev->ddev->struct_mutex); | 234 | mutex_lock(&rdev->ddev->struct_mutex); |
| 230 | mutex_lock(&rdev->vram_mutex); | 235 | mutex_lock(&rdev->vram_mutex); |
| 231 | mutex_lock(&rdev->cp.mutex); | 236 | mutex_lock(&rdev->cp.mutex); |
| @@ -632,8 +637,6 @@ void radeon_pm_fini(struct radeon_device *rdev) | |||
| 632 | } | 637 | } |
| 633 | 638 | ||
| 634 | radeon_hwmon_fini(rdev); | 639 | radeon_hwmon_fini(rdev); |
| 635 | if (rdev->pm.i2c_bus) | ||
| 636 | radeon_i2c_destroy(rdev->pm.i2c_bus); | ||
| 637 | } | 640 | } |
| 638 | 641 | ||
| 639 | void radeon_pm_compute_clocks(struct radeon_device *rdev) | 642 | void radeon_pm_compute_clocks(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index b3ba44c0a818..4ae5a3d1074e 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
| @@ -3228,34 +3228,34 @@ void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | |||
| 3228 | } | 3228 | } |
| 3229 | 3229 | ||
| 3230 | struct drm_ioctl_desc radeon_ioctls[] = { | 3230 | struct drm_ioctl_desc radeon_ioctls[] = { |
| 3231 | DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3231 | DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 3232 | DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3232 | DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 3233 | DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3233 | DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 3234 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3234 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 3235 | DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), | 3235 | DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), |
| 3236 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), | 3236 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), |
| 3237 | DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset, DRM_AUTH), | 3237 | DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset, DRM_AUTH), |
| 3238 | DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), | 3238 | DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), |
| 3239 | DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap, DRM_AUTH), | 3239 | DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap, DRM_AUTH), |
| 3240 | DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), | 3240 | DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), |
| 3241 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), | 3241 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), |
| 3242 | DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH), | 3242 | DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices, DRM_AUTH), |
| 3243 | DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), | 3243 | DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), |
| 3244 | DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), | 3244 | DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), |
| 3245 | DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3245 | DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 3246 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), | 3246 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), |
| 3247 | DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), | 3247 | DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), |
| 3248 | DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), | 3248 | DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), |
| 3249 | DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip, DRM_AUTH), | 3249 | DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip, DRM_AUTH), |
| 3250 | DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), | 3250 | DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), |
| 3251 | DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free, DRM_AUTH), | 3251 | DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free, DRM_AUTH), |
| 3252 | DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3252 | DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 3253 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), | 3253 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), |
| 3254 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), | 3254 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), |
| 3255 | DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), | 3255 | DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), |
| 3256 | DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), | 3256 | DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), |
| 3257 | DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), | 3257 | DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), |
| 3258 | DRM_IOCTL_DEF(DRM_RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) | 3258 | DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) |
| 3259 | }; | 3259 | }; |
| 3260 | 3260 | ||
| 3261 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); | 3261 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index f1c796810117..bfa59db374d2 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -905,6 +905,54 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
| 905 | 905 | ||
| 906 | } | 906 | } |
| 907 | 907 | ||
| 908 | static int rv770_vram_scratch_init(struct radeon_device *rdev) | ||
| 909 | { | ||
| 910 | int r; | ||
| 911 | u64 gpu_addr; | ||
| 912 | |||
| 913 | if (rdev->vram_scratch.robj == NULL) { | ||
| 914 | r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, | ||
| 915 | true, RADEON_GEM_DOMAIN_VRAM, | ||
| 916 | &rdev->vram_scratch.robj); | ||
| 917 | if (r) { | ||
| 918 | return r; | ||
| 919 | } | ||
| 920 | } | ||
| 921 | |||
| 922 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
| 923 | if (unlikely(r != 0)) | ||
| 924 | return r; | ||
| 925 | r = radeon_bo_pin(rdev->vram_scratch.robj, | ||
| 926 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); | ||
| 927 | if (r) { | ||
| 928 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
| 929 | return r; | ||
| 930 | } | ||
| 931 | r = radeon_bo_kmap(rdev->vram_scratch.robj, | ||
| 932 | (void **)&rdev->vram_scratch.ptr); | ||
| 933 | if (r) | ||
| 934 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
| 935 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
| 936 | |||
| 937 | return r; | ||
| 938 | } | ||
| 939 | |||
| 940 | static void rv770_vram_scratch_fini(struct radeon_device *rdev) | ||
| 941 | { | ||
| 942 | int r; | ||
| 943 | |||
| 944 | if (rdev->vram_scratch.robj == NULL) { | ||
| 945 | return; | ||
| 946 | } | ||
| 947 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
| 948 | if (likely(r == 0)) { | ||
| 949 | radeon_bo_kunmap(rdev->vram_scratch.robj); | ||
| 950 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
| 951 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
| 952 | } | ||
| 953 | radeon_bo_unref(&rdev->vram_scratch.robj); | ||
| 954 | } | ||
| 955 | |||
| 908 | int rv770_mc_init(struct radeon_device *rdev) | 956 | int rv770_mc_init(struct radeon_device *rdev) |
| 909 | { | 957 | { |
| 910 | u32 tmp; | 958 | u32 tmp; |
| @@ -970,6 +1018,9 @@ static int rv770_startup(struct radeon_device *rdev) | |||
| 970 | if (r) | 1018 | if (r) |
| 971 | return r; | 1019 | return r; |
| 972 | } | 1020 | } |
| 1021 | r = rv770_vram_scratch_init(rdev); | ||
| 1022 | if (r) | ||
| 1023 | return r; | ||
| 973 | rv770_gpu_init(rdev); | 1024 | rv770_gpu_init(rdev); |
| 974 | r = r600_blit_init(rdev); | 1025 | r = r600_blit_init(rdev); |
| 975 | if (r) { | 1026 | if (r) { |
| @@ -1023,11 +1074,6 @@ int rv770_resume(struct radeon_device *rdev) | |||
| 1023 | */ | 1074 | */ |
| 1024 | /* post card */ | 1075 | /* post card */ |
| 1025 | atom_asic_init(rdev->mode_info.atom_context); | 1076 | atom_asic_init(rdev->mode_info.atom_context); |
| 1026 | /* Initialize clocks */ | ||
| 1027 | r = radeon_clocks_init(rdev); | ||
| 1028 | if (r) { | ||
| 1029 | return r; | ||
| 1030 | } | ||
| 1031 | 1077 | ||
| 1032 | r = rv770_startup(rdev); | 1078 | r = rv770_startup(rdev); |
| 1033 | if (r) { | 1079 | if (r) { |
| @@ -1118,9 +1164,6 @@ int rv770_init(struct radeon_device *rdev) | |||
| 1118 | radeon_surface_init(rdev); | 1164 | radeon_surface_init(rdev); |
| 1119 | /* Initialize clocks */ | 1165 | /* Initialize clocks */ |
| 1120 | radeon_get_clock_info(rdev->ddev); | 1166 | radeon_get_clock_info(rdev->ddev); |
| 1121 | r = radeon_clocks_init(rdev); | ||
| 1122 | if (r) | ||
| 1123 | return r; | ||
| 1124 | /* Fence driver */ | 1167 | /* Fence driver */ |
| 1125 | r = radeon_fence_driver_init(rdev); | 1168 | r = radeon_fence_driver_init(rdev); |
| 1126 | if (r) | 1169 | if (r) |
| @@ -1195,9 +1238,9 @@ void rv770_fini(struct radeon_device *rdev) | |||
| 1195 | r600_irq_fini(rdev); | 1238 | r600_irq_fini(rdev); |
| 1196 | radeon_irq_kms_fini(rdev); | 1239 | radeon_irq_kms_fini(rdev); |
| 1197 | rv770_pcie_gart_fini(rdev); | 1240 | rv770_pcie_gart_fini(rdev); |
| 1241 | rv770_vram_scratch_fini(rdev); | ||
| 1198 | radeon_gem_fini(rdev); | 1242 | radeon_gem_fini(rdev); |
| 1199 | radeon_fence_driver_fini(rdev); | 1243 | radeon_fence_driver_fini(rdev); |
| 1200 | radeon_clocks_fini(rdev); | ||
| 1201 | radeon_agp_fini(rdev); | 1244 | radeon_agp_fini(rdev); |
| 1202 | radeon_bo_fini(rdev); | 1245 | radeon_bo_fini(rdev); |
| 1203 | radeon_atombios_fini(rdev); | 1246 | radeon_atombios_fini(rdev); |
diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c index 976dc8d25280..bf5f83ea14fe 100644 --- a/drivers/gpu/drm/savage/savage_bci.c +++ b/drivers/gpu/drm/savage/savage_bci.c | |||
| @@ -1082,10 +1082,10 @@ void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) | |||
| 1082 | } | 1082 | } |
| 1083 | 1083 | ||
| 1084 | struct drm_ioctl_desc savage_ioctls[] = { | 1084 | struct drm_ioctl_desc savage_ioctls[] = { |
| 1085 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1085 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1086 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), | 1086 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), |
| 1087 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), | 1087 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), |
| 1088 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), | 1088 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), |
| 1089 | }; | 1089 | }; |
| 1090 | 1090 | ||
| 1091 | int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); | 1091 | int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); |
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index 07d0f2979cac..7fe2b63412ce 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c | |||
| @@ -320,12 +320,12 @@ void sis_reclaim_buffers_locked(struct drm_device *dev, | |||
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | struct drm_ioctl_desc sis_ioctls[] = { | 322 | struct drm_ioctl_desc sis_ioctls[] = { |
| 323 | DRM_IOCTL_DEF(DRM_SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH), | 323 | DRM_IOCTL_DEF_DRV(SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH), |
| 324 | DRM_IOCTL_DEF(DRM_SIS_FB_FREE, sis_drm_free, DRM_AUTH), | 324 | DRM_IOCTL_DEF_DRV(SIS_FB_FREE, sis_drm_free, DRM_AUTH), |
| 325 | DRM_IOCTL_DEF(DRM_SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), | 325 | DRM_IOCTL_DEF_DRV(SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), |
| 326 | DRM_IOCTL_DEF(DRM_SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH), | 326 | DRM_IOCTL_DEF_DRV(SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH), |
| 327 | DRM_IOCTL_DEF(DRM_SIS_AGP_FREE, sis_drm_free, DRM_AUTH), | 327 | DRM_IOCTL_DEF_DRV(SIS_AGP_FREE, sis_drm_free, DRM_AUTH), |
| 328 | DRM_IOCTL_DEF(DRM_SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), | 328 | DRM_IOCTL_DEF_DRV(SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), |
| 329 | }; | 329 | }; |
| 330 | 330 | ||
| 331 | int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); | 331 | int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index cb4cf7ef4d1e..db809e034cc4 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
| @@ -442,6 +442,43 @@ out_err: | |||
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | /** | 444 | /** |
| 445 | * Call bo::reserved and with the lru lock held. | ||
| 446 | * Will release GPU memory type usage on destruction. | ||
| 447 | * This is the place to put in driver specific hooks. | ||
| 448 | * Will release the bo::reserved lock and the | ||
| 449 | * lru lock on exit. | ||
| 450 | */ | ||
| 451 | |||
| 452 | static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) | ||
| 453 | { | ||
| 454 | struct ttm_bo_global *glob = bo->glob; | ||
| 455 | |||
| 456 | if (bo->ttm) { | ||
| 457 | |||
| 458 | /** | ||
| 459 | * Release the lru_lock, since we don't want to have | ||
| 460 | * an atomic requirement on ttm_tt[unbind|destroy]. | ||
| 461 | */ | ||
| 462 | |||
| 463 | spin_unlock(&glob->lru_lock); | ||
| 464 | ttm_tt_unbind(bo->ttm); | ||
| 465 | ttm_tt_destroy(bo->ttm); | ||
| 466 | bo->ttm = NULL; | ||
| 467 | spin_lock(&glob->lru_lock); | ||
| 468 | } | ||
| 469 | |||
| 470 | if (bo->mem.mm_node) { | ||
| 471 | drm_mm_put_block(bo->mem.mm_node); | ||
| 472 | bo->mem.mm_node = NULL; | ||
| 473 | } | ||
| 474 | |||
| 475 | atomic_set(&bo->reserved, 0); | ||
| 476 | wake_up_all(&bo->event_queue); | ||
| 477 | spin_unlock(&glob->lru_lock); | ||
| 478 | } | ||
| 479 | |||
| 480 | |||
| 481 | /** | ||
| 445 | * If bo idle, remove from delayed- and lru lists, and unref. | 482 | * If bo idle, remove from delayed- and lru lists, and unref. |
| 446 | * If not idle, and already on delayed list, do nothing. | 483 | * If not idle, and already on delayed list, do nothing. |
| 447 | * If not idle, and not on delayed list, put on delayed list, | 484 | * If not idle, and not on delayed list, put on delayed list, |
| @@ -456,6 +493,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) | |||
| 456 | int ret; | 493 | int ret; |
| 457 | 494 | ||
| 458 | spin_lock(&bo->lock); | 495 | spin_lock(&bo->lock); |
| 496 | retry: | ||
| 459 | (void) ttm_bo_wait(bo, false, false, !remove_all); | 497 | (void) ttm_bo_wait(bo, false, false, !remove_all); |
| 460 | 498 | ||
| 461 | if (!bo->sync_obj) { | 499 | if (!bo->sync_obj) { |
| @@ -464,31 +502,52 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) | |||
| 464 | spin_unlock(&bo->lock); | 502 | spin_unlock(&bo->lock); |
| 465 | 503 | ||
| 466 | spin_lock(&glob->lru_lock); | 504 | spin_lock(&glob->lru_lock); |
| 467 | put_count = ttm_bo_del_from_lru(bo); | 505 | ret = ttm_bo_reserve_locked(bo, false, !remove_all, false, 0); |
| 506 | |||
| 507 | /** | ||
| 508 | * Someone else has the object reserved. Bail and retry. | ||
| 509 | */ | ||
| 468 | 510 | ||
| 469 | ret = ttm_bo_reserve_locked(bo, false, false, false, 0); | 511 | if (unlikely(ret == -EBUSY)) { |
| 470 | BUG_ON(ret); | 512 | spin_unlock(&glob->lru_lock); |
| 471 | if (bo->ttm) | 513 | spin_lock(&bo->lock); |
| 472 | ttm_tt_unbind(bo->ttm); | 514 | goto requeue; |
| 515 | } | ||
| 516 | |||
| 517 | /** | ||
| 518 | * We can re-check for sync object without taking | ||
| 519 | * the bo::lock since setting the sync object requires | ||
| 520 | * also bo::reserved. A busy object at this point may | ||
| 521 | * be caused by another thread starting an accelerated | ||
| 522 | * eviction. | ||
| 523 | */ | ||
| 524 | |||
| 525 | if (unlikely(bo->sync_obj)) { | ||
| 526 | atomic_set(&bo->reserved, 0); | ||
| 527 | wake_up_all(&bo->event_queue); | ||
| 528 | spin_unlock(&glob->lru_lock); | ||
| 529 | spin_lock(&bo->lock); | ||
| 530 | if (remove_all) | ||
| 531 | goto retry; | ||
| 532 | else | ||
| 533 | goto requeue; | ||
| 534 | } | ||
| 535 | |||
| 536 | put_count = ttm_bo_del_from_lru(bo); | ||
| 473 | 537 | ||
| 474 | if (!list_empty(&bo->ddestroy)) { | 538 | if (!list_empty(&bo->ddestroy)) { |
| 475 | list_del_init(&bo->ddestroy); | 539 | list_del_init(&bo->ddestroy); |
| 476 | ++put_count; | 540 | ++put_count; |
| 477 | } | 541 | } |
| 478 | if (bo->mem.mm_node) { | ||
| 479 | drm_mm_put_block(bo->mem.mm_node); | ||
| 480 | bo->mem.mm_node = NULL; | ||
| 481 | } | ||
| 482 | spin_unlock(&glob->lru_lock); | ||
| 483 | 542 | ||
| 484 | atomic_set(&bo->reserved, 0); | 543 | ttm_bo_cleanup_memtype_use(bo); |
| 485 | 544 | ||
| 486 | while (put_count--) | 545 | while (put_count--) |
| 487 | kref_put(&bo->list_kref, ttm_bo_ref_bug); | 546 | kref_put(&bo->list_kref, ttm_bo_ref_bug); |
| 488 | 547 | ||
| 489 | return 0; | 548 | return 0; |
| 490 | } | 549 | } |
| 491 | 550 | requeue: | |
| 492 | spin_lock(&glob->lru_lock); | 551 | spin_lock(&glob->lru_lock); |
| 493 | if (list_empty(&bo->ddestroy)) { | 552 | if (list_empty(&bo->ddestroy)) { |
| 494 | void *sync_obj = bo->sync_obj; | 553 | void *sync_obj = bo->sync_obj; |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 7cffb3e04232..3451a82adba7 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
| @@ -351,6 +351,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, | |||
| 351 | INIT_LIST_HEAD(&fbo->lru); | 351 | INIT_LIST_HEAD(&fbo->lru); |
| 352 | INIT_LIST_HEAD(&fbo->swap); | 352 | INIT_LIST_HEAD(&fbo->swap); |
| 353 | fbo->vm_node = NULL; | 353 | fbo->vm_node = NULL; |
| 354 | atomic_set(&fbo->cpu_writers, 0); | ||
| 354 | 355 | ||
| 355 | fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); | 356 | fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); |
| 356 | kref_init(&fbo->list_kref); | 357 | kref_init(&fbo->list_kref); |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index ca904799f018..b1e02fffd3cc 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
| @@ -69,7 +69,7 @@ struct ttm_page_pool { | |||
| 69 | spinlock_t lock; | 69 | spinlock_t lock; |
| 70 | bool fill_lock; | 70 | bool fill_lock; |
| 71 | struct list_head list; | 71 | struct list_head list; |
| 72 | int gfp_flags; | 72 | gfp_t gfp_flags; |
| 73 | unsigned npages; | 73 | unsigned npages; |
| 74 | char *name; | 74 | char *name; |
| 75 | unsigned long nfrees; | 75 | unsigned long nfrees; |
| @@ -475,7 +475,7 @@ static void ttm_handle_caching_state_failure(struct list_head *pages, | |||
| 475 | * This function is reentrant if caller updates count depending on number of | 475 | * This function is reentrant if caller updates count depending on number of |
| 476 | * pages returned in pages array. | 476 | * pages returned in pages array. |
| 477 | */ | 477 | */ |
| 478 | static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags, | 478 | static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, |
| 479 | int ttm_flags, enum ttm_caching_state cstate, unsigned count) | 479 | int ttm_flags, enum ttm_caching_state cstate, unsigned count) |
| 480 | { | 480 | { |
| 481 | struct page **caching_array; | 481 | struct page **caching_array; |
| @@ -666,7 +666,7 @@ int ttm_get_pages(struct list_head *pages, int flags, | |||
| 666 | { | 666 | { |
| 667 | struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); | 667 | struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); |
| 668 | struct page *p = NULL; | 668 | struct page *p = NULL; |
| 669 | int gfp_flags = GFP_USER; | 669 | gfp_t gfp_flags = GFP_USER; |
| 670 | int r; | 670 | int r; |
| 671 | 671 | ||
| 672 | /* set zero flag for page allocation if required */ | 672 | /* set zero flag for page allocation if required */ |
| @@ -818,7 +818,7 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages) | |||
| 818 | return 0; | 818 | return 0; |
| 819 | } | 819 | } |
| 820 | 820 | ||
| 821 | void ttm_page_alloc_fini() | 821 | void ttm_page_alloc_fini(void) |
| 822 | { | 822 | { |
| 823 | int i; | 823 | int i; |
| 824 | 824 | ||
diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c index 68dda74a50ae..cc0ffa9abd00 100644 --- a/drivers/gpu/drm/via/via_dma.c +++ b/drivers/gpu/drm/via/via_dma.c | |||
| @@ -722,20 +722,20 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * | |||
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | struct drm_ioctl_desc via_ioctls[] = { | 724 | struct drm_ioctl_desc via_ioctls[] = { |
| 725 | DRM_IOCTL_DEF(DRM_VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), | 725 | DRM_IOCTL_DEF_DRV(VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), |
| 726 | DRM_IOCTL_DEF(DRM_VIA_FREEMEM, via_mem_free, DRM_AUTH), | 726 | DRM_IOCTL_DEF_DRV(VIA_FREEMEM, via_mem_free, DRM_AUTH), |
| 727 | DRM_IOCTL_DEF(DRM_VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER), | 727 | DRM_IOCTL_DEF_DRV(VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER), |
| 728 | DRM_IOCTL_DEF(DRM_VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER), | 728 | DRM_IOCTL_DEF_DRV(VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER), |
| 729 | DRM_IOCTL_DEF(DRM_VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER), | 729 | DRM_IOCTL_DEF_DRV(VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER), |
| 730 | DRM_IOCTL_DEF(DRM_VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH), | 730 | DRM_IOCTL_DEF_DRV(VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH), |
| 731 | DRM_IOCTL_DEF(DRM_VIA_DMA_INIT, via_dma_init, DRM_AUTH), | 731 | DRM_IOCTL_DEF_DRV(VIA_DMA_INIT, via_dma_init, DRM_AUTH), |
| 732 | DRM_IOCTL_DEF(DRM_VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH), | 732 | DRM_IOCTL_DEF_DRV(VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH), |
| 733 | DRM_IOCTL_DEF(DRM_VIA_FLUSH, via_flush_ioctl, DRM_AUTH), | 733 | DRM_IOCTL_DEF_DRV(VIA_FLUSH, via_flush_ioctl, DRM_AUTH), |
| 734 | DRM_IOCTL_DEF(DRM_VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH), | 734 | DRM_IOCTL_DEF_DRV(VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH), |
| 735 | DRM_IOCTL_DEF(DRM_VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH), | 735 | DRM_IOCTL_DEF_DRV(VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH), |
| 736 | DRM_IOCTL_DEF(DRM_VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH), | 736 | DRM_IOCTL_DEF_DRV(VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH), |
| 737 | DRM_IOCTL_DEF(DRM_VIA_DMA_BLIT, via_dma_blit, DRM_AUTH), | 737 | DRM_IOCTL_DEF_DRV(VIA_DMA_BLIT, via_dma_blit, DRM_AUTH), |
| 738 | DRM_IOCTL_DEF(DRM_VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) | 738 | DRM_IOCTL_DEF_DRV(VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) |
| 739 | }; | 739 | }; |
| 740 | 740 | ||
| 741 | int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); | 741 | int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 9dd395b90216..a96ed6d9d010 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
| @@ -99,47 +99,47 @@ | |||
| 99 | */ | 99 | */ |
| 100 | 100 | ||
| 101 | #define VMW_IOCTL_DEF(ioctl, func, flags) \ | 101 | #define VMW_IOCTL_DEF(ioctl, func, flags) \ |
| 102 | [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func} | 102 | [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = {DRM_##ioctl, flags, func, DRM_IOCTL_##ioctl} |
| 103 | 103 | ||
| 104 | /** | 104 | /** |
| 105 | * Ioctl definitions. | 105 | * Ioctl definitions. |
| 106 | */ | 106 | */ |
| 107 | 107 | ||
| 108 | static struct drm_ioctl_desc vmw_ioctls[] = { | 108 | static struct drm_ioctl_desc vmw_ioctls[] = { |
| 109 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl, | 109 | VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl, |
| 110 | DRM_AUTH | DRM_UNLOCKED), | 110 | DRM_AUTH | DRM_UNLOCKED), |
| 111 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, | 111 | VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, |
| 112 | DRM_AUTH | DRM_UNLOCKED), | 112 | DRM_AUTH | DRM_UNLOCKED), |
| 113 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, | 113 | VMW_IOCTL_DEF(VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, |
| 114 | DRM_AUTH | DRM_UNLOCKED), | 114 | DRM_AUTH | DRM_UNLOCKED), |
| 115 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS, | 115 | VMW_IOCTL_DEF(VMW_CURSOR_BYPASS, |
| 116 | vmw_kms_cursor_bypass_ioctl, | 116 | vmw_kms_cursor_bypass_ioctl, |
| 117 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 117 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
| 118 | 118 | ||
| 119 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl, | 119 | VMW_IOCTL_DEF(VMW_CONTROL_STREAM, vmw_overlay_ioctl, |
| 120 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 120 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
| 121 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, | 121 | VMW_IOCTL_DEF(VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, |
| 122 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 122 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
| 123 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl, | 123 | VMW_IOCTL_DEF(VMW_UNREF_STREAM, vmw_stream_unref_ioctl, |
| 124 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 124 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
| 125 | 125 | ||
| 126 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl, | 126 | VMW_IOCTL_DEF(VMW_CREATE_CONTEXT, vmw_context_define_ioctl, |
| 127 | DRM_AUTH | DRM_UNLOCKED), | 127 | DRM_AUTH | DRM_UNLOCKED), |
| 128 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, | 128 | VMW_IOCTL_DEF(VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, |
| 129 | DRM_AUTH | DRM_UNLOCKED), | 129 | DRM_AUTH | DRM_UNLOCKED), |
| 130 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl, | 130 | VMW_IOCTL_DEF(VMW_CREATE_SURFACE, vmw_surface_define_ioctl, |
| 131 | DRM_AUTH | DRM_UNLOCKED), | 131 | DRM_AUTH | DRM_UNLOCKED), |
| 132 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, | 132 | VMW_IOCTL_DEF(VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, |
| 133 | DRM_AUTH | DRM_UNLOCKED), | 133 | DRM_AUTH | DRM_UNLOCKED), |
| 134 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl, | 134 | VMW_IOCTL_DEF(VMW_REF_SURFACE, vmw_surface_reference_ioctl, |
| 135 | DRM_AUTH | DRM_UNLOCKED), | 135 | DRM_AUTH | DRM_UNLOCKED), |
| 136 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl, | 136 | VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl, |
| 137 | DRM_AUTH | DRM_UNLOCKED), | 137 | DRM_AUTH | DRM_UNLOCKED), |
| 138 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, | 138 | VMW_IOCTL_DEF(VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, |
| 139 | DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), | 139 | DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), |
| 140 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl, | 140 | VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_wait_ioctl, |
| 141 | DRM_AUTH | DRM_UNLOCKED), | 141 | DRM_AUTH | DRM_UNLOCKED), |
| 142 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, | 142 | VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, |
| 143 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED) | 143 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED) |
| 144 | }; | 144 | }; |
| 145 | 145 | ||
| @@ -148,13 +148,16 @@ static struct pci_device_id vmw_pci_id_list[] = { | |||
| 148 | {0, 0, 0} | 148 | {0, 0, 0} |
| 149 | }; | 149 | }; |
| 150 | 150 | ||
| 151 | static char *vmw_devname = "vmwgfx"; | 151 | static int enable_fbdev; |
| 152 | 152 | ||
| 153 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); | 153 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); |
| 154 | static void vmw_master_init(struct vmw_master *); | 154 | static void vmw_master_init(struct vmw_master *); |
| 155 | static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, | 155 | static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, |
| 156 | void *ptr); | 156 | void *ptr); |
| 157 | 157 | ||
| 158 | MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev"); | ||
| 159 | module_param_named(enable_fbdev, enable_fbdev, int, 0600); | ||
| 160 | |||
| 158 | static void vmw_print_capabilities(uint32_t capabilities) | 161 | static void vmw_print_capabilities(uint32_t capabilities) |
| 159 | { | 162 | { |
| 160 | DRM_INFO("Capabilities:\n"); | 163 | DRM_INFO("Capabilities:\n"); |
| @@ -192,8 +195,6 @@ static int vmw_request_device(struct vmw_private *dev_priv) | |||
| 192 | { | 195 | { |
| 193 | int ret; | 196 | int ret; |
| 194 | 197 | ||
| 195 | vmw_kms_save_vga(dev_priv); | ||
| 196 | |||
| 197 | ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); | 198 | ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); |
| 198 | if (unlikely(ret != 0)) { | 199 | if (unlikely(ret != 0)) { |
| 199 | DRM_ERROR("Unable to initialize FIFO.\n"); | 200 | DRM_ERROR("Unable to initialize FIFO.\n"); |
| @@ -206,9 +207,35 @@ static int vmw_request_device(struct vmw_private *dev_priv) | |||
| 206 | static void vmw_release_device(struct vmw_private *dev_priv) | 207 | static void vmw_release_device(struct vmw_private *dev_priv) |
| 207 | { | 208 | { |
| 208 | vmw_fifo_release(dev_priv, &dev_priv->fifo); | 209 | vmw_fifo_release(dev_priv, &dev_priv->fifo); |
| 209 | vmw_kms_restore_vga(dev_priv); | ||
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | int vmw_3d_resource_inc(struct vmw_private *dev_priv) | ||
| 213 | { | ||
| 214 | int ret = 0; | ||
| 215 | |||
| 216 | mutex_lock(&dev_priv->release_mutex); | ||
| 217 | if (unlikely(dev_priv->num_3d_resources++ == 0)) { | ||
| 218 | ret = vmw_request_device(dev_priv); | ||
| 219 | if (unlikely(ret != 0)) | ||
| 220 | --dev_priv->num_3d_resources; | ||
| 221 | } | ||
| 222 | mutex_unlock(&dev_priv->release_mutex); | ||
| 223 | return ret; | ||
| 224 | } | ||
| 225 | |||
| 226 | |||
| 227 | void vmw_3d_resource_dec(struct vmw_private *dev_priv) | ||
| 228 | { | ||
| 229 | int32_t n3d; | ||
| 230 | |||
| 231 | mutex_lock(&dev_priv->release_mutex); | ||
| 232 | if (unlikely(--dev_priv->num_3d_resources == 0)) | ||
| 233 | vmw_release_device(dev_priv); | ||
| 234 | n3d = (int32_t) dev_priv->num_3d_resources; | ||
| 235 | mutex_unlock(&dev_priv->release_mutex); | ||
| 236 | |||
| 237 | BUG_ON(n3d < 0); | ||
| 238 | } | ||
| 212 | 239 | ||
| 213 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | 240 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) |
| 214 | { | 241 | { |
| @@ -228,6 +255,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 228 | dev_priv->last_read_sequence = (uint32_t) -100; | 255 | dev_priv->last_read_sequence = (uint32_t) -100; |
| 229 | mutex_init(&dev_priv->hw_mutex); | 256 | mutex_init(&dev_priv->hw_mutex); |
| 230 | mutex_init(&dev_priv->cmdbuf_mutex); | 257 | mutex_init(&dev_priv->cmdbuf_mutex); |
| 258 | mutex_init(&dev_priv->release_mutex); | ||
| 231 | rwlock_init(&dev_priv->resource_lock); | 259 | rwlock_init(&dev_priv->resource_lock); |
| 232 | idr_init(&dev_priv->context_idr); | 260 | idr_init(&dev_priv->context_idr); |
| 233 | idr_init(&dev_priv->surface_idr); | 261 | idr_init(&dev_priv->surface_idr); |
| @@ -244,6 +272,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 244 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); | 272 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); |
| 245 | dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); | 273 | dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); |
| 246 | 274 | ||
| 275 | dev_priv->enable_fb = enable_fbdev; | ||
| 276 | |||
| 247 | mutex_lock(&dev_priv->hw_mutex); | 277 | mutex_lock(&dev_priv->hw_mutex); |
| 248 | 278 | ||
| 249 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | 279 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); |
| @@ -343,17 +373,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 343 | 373 | ||
| 344 | dev->dev_private = dev_priv; | 374 | dev->dev_private = dev_priv; |
| 345 | 375 | ||
| 346 | if (!dev->devname) | ||
| 347 | dev->devname = vmw_devname; | ||
| 348 | |||
| 349 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | ||
| 350 | ret = drm_irq_install(dev); | ||
| 351 | if (unlikely(ret != 0)) { | ||
| 352 | DRM_ERROR("Failed installing irq: %d\n", ret); | ||
| 353 | goto out_no_irq; | ||
| 354 | } | ||
| 355 | } | ||
| 356 | |||
| 357 | ret = pci_request_regions(dev->pdev, "vmwgfx probe"); | 376 | ret = pci_request_regions(dev->pdev, "vmwgfx probe"); |
| 358 | dev_priv->stealth = (ret != 0); | 377 | dev_priv->stealth = (ret != 0); |
| 359 | if (dev_priv->stealth) { | 378 | if (dev_priv->stealth) { |
| @@ -369,26 +388,52 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 369 | goto out_no_device; | 388 | goto out_no_device; |
| 370 | } | 389 | } |
| 371 | } | 390 | } |
| 372 | ret = vmw_request_device(dev_priv); | 391 | ret = vmw_kms_init(dev_priv); |
| 373 | if (unlikely(ret != 0)) | 392 | if (unlikely(ret != 0)) |
| 374 | goto out_no_device; | 393 | goto out_no_kms; |
| 375 | vmw_kms_init(dev_priv); | ||
| 376 | vmw_overlay_init(dev_priv); | 394 | vmw_overlay_init(dev_priv); |
| 377 | vmw_fb_init(dev_priv); | 395 | if (dev_priv->enable_fb) { |
| 396 | ret = vmw_3d_resource_inc(dev_priv); | ||
| 397 | if (unlikely(ret != 0)) | ||
| 398 | goto out_no_fifo; | ||
| 399 | vmw_kms_save_vga(dev_priv); | ||
| 400 | vmw_fb_init(dev_priv); | ||
| 401 | DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? | ||
| 402 | "Detected device 3D availability.\n" : | ||
| 403 | "Detected no device 3D availability.\n"); | ||
| 404 | } else { | ||
| 405 | DRM_INFO("Delayed 3D detection since we're not " | ||
| 406 | "running the device in SVGA mode yet.\n"); | ||
| 407 | } | ||
| 408 | |||
| 409 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | ||
| 410 | ret = drm_irq_install(dev); | ||
| 411 | if (unlikely(ret != 0)) { | ||
| 412 | DRM_ERROR("Failed installing irq: %d\n", ret); | ||
| 413 | goto out_no_irq; | ||
| 414 | } | ||
| 415 | } | ||
| 378 | 416 | ||
| 379 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; | 417 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; |
| 380 | register_pm_notifier(&dev_priv->pm_nb); | 418 | register_pm_notifier(&dev_priv->pm_nb); |
| 381 | 419 | ||
| 382 | DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n"); | ||
| 383 | |||
| 384 | return 0; | 420 | return 0; |
| 385 | 421 | ||
| 386 | out_no_device: | ||
| 387 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
| 388 | drm_irq_uninstall(dev_priv->dev); | ||
| 389 | if (dev->devname == vmw_devname) | ||
| 390 | dev->devname = NULL; | ||
| 391 | out_no_irq: | 422 | out_no_irq: |
| 423 | if (dev_priv->enable_fb) { | ||
| 424 | vmw_fb_close(dev_priv); | ||
| 425 | vmw_kms_restore_vga(dev_priv); | ||
| 426 | vmw_3d_resource_dec(dev_priv); | ||
| 427 | } | ||
| 428 | out_no_fifo: | ||
| 429 | vmw_overlay_close(dev_priv); | ||
| 430 | vmw_kms_close(dev_priv); | ||
| 431 | out_no_kms: | ||
| 432 | if (dev_priv->stealth) | ||
| 433 | pci_release_region(dev->pdev, 2); | ||
| 434 | else | ||
| 435 | pci_release_regions(dev->pdev); | ||
| 436 | out_no_device: | ||
| 392 | ttm_object_device_release(&dev_priv->tdev); | 437 | ttm_object_device_release(&dev_priv->tdev); |
| 393 | out_err4: | 438 | out_err4: |
| 394 | iounmap(dev_priv->mmio_virt); | 439 | iounmap(dev_priv->mmio_virt); |
| @@ -415,19 +460,20 @@ static int vmw_driver_unload(struct drm_device *dev) | |||
| 415 | 460 | ||
| 416 | unregister_pm_notifier(&dev_priv->pm_nb); | 461 | unregister_pm_notifier(&dev_priv->pm_nb); |
| 417 | 462 | ||
| 418 | vmw_fb_close(dev_priv); | 463 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) |
| 464 | drm_irq_uninstall(dev_priv->dev); | ||
| 465 | if (dev_priv->enable_fb) { | ||
| 466 | vmw_fb_close(dev_priv); | ||
| 467 | vmw_kms_restore_vga(dev_priv); | ||
| 468 | vmw_3d_resource_dec(dev_priv); | ||
| 469 | } | ||
| 419 | vmw_kms_close(dev_priv); | 470 | vmw_kms_close(dev_priv); |
| 420 | vmw_overlay_close(dev_priv); | 471 | vmw_overlay_close(dev_priv); |
| 421 | vmw_release_device(dev_priv); | ||
| 422 | if (dev_priv->stealth) | 472 | if (dev_priv->stealth) |
| 423 | pci_release_region(dev->pdev, 2); | 473 | pci_release_region(dev->pdev, 2); |
| 424 | else | 474 | else |
| 425 | pci_release_regions(dev->pdev); | 475 | pci_release_regions(dev->pdev); |
| 426 | 476 | ||
| 427 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
| 428 | drm_irq_uninstall(dev_priv->dev); | ||
| 429 | if (dev->devname == vmw_devname) | ||
| 430 | dev->devname = NULL; | ||
| 431 | ttm_object_device_release(&dev_priv->tdev); | 477 | ttm_object_device_release(&dev_priv->tdev); |
| 432 | iounmap(dev_priv->mmio_virt); | 478 | iounmap(dev_priv->mmio_virt); |
| 433 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, | 479 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, |
| @@ -500,7 +546,7 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
| 500 | struct drm_ioctl_desc *ioctl = | 546 | struct drm_ioctl_desc *ioctl = |
| 501 | &vmw_ioctls[nr - DRM_COMMAND_BASE]; | 547 | &vmw_ioctls[nr - DRM_COMMAND_BASE]; |
| 502 | 548 | ||
| 503 | if (unlikely(ioctl->cmd != cmd)) { | 549 | if (unlikely(ioctl->cmd_drv != cmd)) { |
| 504 | DRM_ERROR("Invalid command format, ioctl %d\n", | 550 | DRM_ERROR("Invalid command format, ioctl %d\n", |
| 505 | nr - DRM_COMMAND_BASE); | 551 | nr - DRM_COMMAND_BASE); |
| 506 | return -EINVAL; | 552 | return -EINVAL; |
| @@ -589,6 +635,16 @@ static int vmw_master_set(struct drm_device *dev, | |||
| 589 | struct vmw_master *vmaster = vmw_master(file_priv->master); | 635 | struct vmw_master *vmaster = vmw_master(file_priv->master); |
| 590 | int ret = 0; | 636 | int ret = 0; |
| 591 | 637 | ||
| 638 | if (!dev_priv->enable_fb) { | ||
| 639 | ret = vmw_3d_resource_inc(dev_priv); | ||
| 640 | if (unlikely(ret != 0)) | ||
| 641 | return ret; | ||
| 642 | vmw_kms_save_vga(dev_priv); | ||
| 643 | mutex_lock(&dev_priv->hw_mutex); | ||
| 644 | vmw_write(dev_priv, SVGA_REG_TRACES, 0); | ||
| 645 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 646 | } | ||
| 647 | |||
| 592 | if (active) { | 648 | if (active) { |
| 593 | BUG_ON(active != &dev_priv->fbdev_master); | 649 | BUG_ON(active != &dev_priv->fbdev_master); |
| 594 | ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); | 650 | ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); |
| @@ -617,7 +673,13 @@ static int vmw_master_set(struct drm_device *dev, | |||
| 617 | return 0; | 673 | return 0; |
| 618 | 674 | ||
| 619 | out_no_active_lock: | 675 | out_no_active_lock: |
| 620 | vmw_release_device(dev_priv); | 676 | if (!dev_priv->enable_fb) { |
| 677 | mutex_lock(&dev_priv->hw_mutex); | ||
| 678 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | ||
| 679 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 680 | vmw_kms_restore_vga(dev_priv); | ||
| 681 | vmw_3d_resource_dec(dev_priv); | ||
| 682 | } | ||
| 621 | return ret; | 683 | return ret; |
| 622 | } | 684 | } |
| 623 | 685 | ||
| @@ -645,11 +707,23 @@ static void vmw_master_drop(struct drm_device *dev, | |||
| 645 | 707 | ||
| 646 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); | 708 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); |
| 647 | 709 | ||
| 710 | if (!dev_priv->enable_fb) { | ||
| 711 | ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); | ||
| 712 | if (unlikely(ret != 0)) | ||
| 713 | DRM_ERROR("Unable to clean VRAM on master drop.\n"); | ||
| 714 | mutex_lock(&dev_priv->hw_mutex); | ||
| 715 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | ||
| 716 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 717 | vmw_kms_restore_vga(dev_priv); | ||
| 718 | vmw_3d_resource_dec(dev_priv); | ||
| 719 | } | ||
| 720 | |||
| 648 | dev_priv->active_master = &dev_priv->fbdev_master; | 721 | dev_priv->active_master = &dev_priv->fbdev_master; |
| 649 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); | 722 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); |
| 650 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); | 723 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); |
| 651 | 724 | ||
| 652 | vmw_fb_on(dev_priv); | 725 | if (dev_priv->enable_fb) |
| 726 | vmw_fb_on(dev_priv); | ||
| 653 | } | 727 | } |
| 654 | 728 | ||
| 655 | 729 | ||
| @@ -722,6 +796,7 @@ static struct drm_driver driver = { | |||
| 722 | .irq_postinstall = vmw_irq_postinstall, | 796 | .irq_postinstall = vmw_irq_postinstall, |
| 723 | .irq_uninstall = vmw_irq_uninstall, | 797 | .irq_uninstall = vmw_irq_uninstall, |
| 724 | .irq_handler = vmw_irq_handler, | 798 | .irq_handler = vmw_irq_handler, |
| 799 | .get_vblank_counter = vmw_get_vblank_counter, | ||
| 725 | .reclaim_buffers_locked = NULL, | 800 | .reclaim_buffers_locked = NULL, |
| 726 | .get_map_ofs = drm_core_get_map_ofs, | 801 | .get_map_ofs = drm_core_get_map_ofs, |
| 727 | .get_reg_ofs = drm_core_get_reg_ofs, | 802 | .get_reg_ofs = drm_core_get_reg_ofs, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 429f917b60bf..58de6393f611 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
| @@ -277,6 +277,7 @@ struct vmw_private { | |||
| 277 | 277 | ||
| 278 | bool stealth; | 278 | bool stealth; |
| 279 | bool is_opened; | 279 | bool is_opened; |
| 280 | bool enable_fb; | ||
| 280 | 281 | ||
| 281 | /** | 282 | /** |
| 282 | * Master management. | 283 | * Master management. |
| @@ -285,6 +286,9 @@ struct vmw_private { | |||
| 285 | struct vmw_master *active_master; | 286 | struct vmw_master *active_master; |
| 286 | struct vmw_master fbdev_master; | 287 | struct vmw_master fbdev_master; |
| 287 | struct notifier_block pm_nb; | 288 | struct notifier_block pm_nb; |
| 289 | |||
| 290 | struct mutex release_mutex; | ||
| 291 | uint32_t num_3d_resources; | ||
| 288 | }; | 292 | }; |
| 289 | 293 | ||
| 290 | static inline struct vmw_private *vmw_priv(struct drm_device *dev) | 294 | static inline struct vmw_private *vmw_priv(struct drm_device *dev) |
| @@ -319,6 +323,9 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv, | |||
| 319 | return val; | 323 | return val; |
| 320 | } | 324 | } |
| 321 | 325 | ||
| 326 | int vmw_3d_resource_inc(struct vmw_private *dev_priv); | ||
| 327 | void vmw_3d_resource_dec(struct vmw_private *dev_priv); | ||
| 328 | |||
| 322 | /** | 329 | /** |
| 323 | * GMR utilities - vmwgfx_gmr.c | 330 | * GMR utilities - vmwgfx_gmr.c |
| 324 | */ | 331 | */ |
| @@ -511,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv, | |||
| 511 | unsigned bbp, unsigned depth); | 518 | unsigned bbp, unsigned depth); |
| 512 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | 519 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, |
| 513 | struct drm_file *file_priv); | 520 | struct drm_file *file_priv); |
| 521 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc); | ||
| 514 | 522 | ||
| 515 | /** | 523 | /** |
| 516 | * Overlay control - vmwgfx_overlay.c | 524 | * Overlay control - vmwgfx_overlay.c |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 870967a97c15..409e172f4abf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
| @@ -615,6 +615,11 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, | |||
| 615 | if (unlikely(ret != 0)) | 615 | if (unlikely(ret != 0)) |
| 616 | goto err_unlock; | 616 | goto err_unlock; |
| 617 | 617 | ||
| 618 | if (bo->mem.mem_type == TTM_PL_VRAM && | ||
| 619 | bo->mem.mm_node->start < bo->num_pages) | ||
| 620 | (void) ttm_bo_validate(bo, &vmw_sys_placement, false, | ||
| 621 | false, false); | ||
| 622 | |||
| 618 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); | 623 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); |
| 619 | 624 | ||
| 620 | /* Could probably bug on */ | 625 | /* Could probably bug on */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index e6a1eb7ea954..0fe31766e4cf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
| @@ -106,6 +106,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
| 106 | mutex_lock(&dev_priv->hw_mutex); | 106 | mutex_lock(&dev_priv->hw_mutex); |
| 107 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); | 107 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); |
| 108 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); | 108 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); |
| 109 | dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); | ||
| 109 | vmw_write(dev_priv, SVGA_REG_ENABLE, 1); | 110 | vmw_write(dev_priv, SVGA_REG_ENABLE, 1); |
| 110 | 111 | ||
| 111 | min = 4; | 112 | min = 4; |
| @@ -175,6 +176,8 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
| 175 | dev_priv->config_done_state); | 176 | dev_priv->config_done_state); |
| 176 | vmw_write(dev_priv, SVGA_REG_ENABLE, | 177 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
| 177 | dev_priv->enable_state); | 178 | dev_priv->enable_state); |
| 179 | vmw_write(dev_priv, SVGA_REG_TRACES, | ||
| 180 | dev_priv->traces_state); | ||
| 178 | 181 | ||
| 179 | mutex_unlock(&dev_priv->hw_mutex); | 182 | mutex_unlock(&dev_priv->hw_mutex); |
| 180 | vmw_fence_queue_takedown(&fifo->fence_queue); | 183 | vmw_fence_queue_takedown(&fifo->fence_queue); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 64d7f47df868..e882ba099f0c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -898,7 +898,19 @@ int vmw_kms_save_vga(struct vmw_private *vmw_priv) | |||
| 898 | save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); | 898 | save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); |
| 899 | save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); | 899 | save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); |
| 900 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); | 900 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); |
| 901 | if (i == 0 && vmw_priv->num_displays == 1 && | ||
| 902 | save->width == 0 && save->height == 0) { | ||
| 903 | |||
| 904 | /* | ||
| 905 | * It should be fairly safe to assume that these | ||
| 906 | * values are uninitialized. | ||
| 907 | */ | ||
| 908 | |||
| 909 | save->width = vmw_priv->vga_width - save->pos_x; | ||
| 910 | save->height = vmw_priv->vga_height - save->pos_y; | ||
| 911 | } | ||
| 901 | } | 912 | } |
| 913 | |||
| 902 | return 0; | 914 | return 0; |
| 903 | } | 915 | } |
| 904 | 916 | ||
| @@ -984,3 +996,8 @@ out_unlock: | |||
| 984 | ttm_read_unlock(&vmaster->lock); | 996 | ttm_read_unlock(&vmaster->lock); |
| 985 | return ret; | 997 | return ret; |
| 986 | } | 998 | } |
| 999 | |||
| 1000 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc) | ||
| 1001 | { | ||
| 1002 | return 0; | ||
| 1003 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 2ff5cf78235f..11cb39e3accb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | 27 | ||
| 28 | #include "vmwgfx_kms.h" | 28 | #include "vmwgfx_kms.h" |
| 29 | 29 | ||
| 30 | #define VMWGFX_LDU_NUM_DU 8 | ||
| 31 | |||
| 30 | #define vmw_crtc_to_ldu(x) \ | 32 | #define vmw_crtc_to_ldu(x) \ |
| 31 | container_of(x, struct vmw_legacy_display_unit, base.crtc) | 33 | container_of(x, struct vmw_legacy_display_unit, base.crtc) |
| 32 | #define vmw_encoder_to_ldu(x) \ | 34 | #define vmw_encoder_to_ldu(x) \ |
| @@ -335,7 +337,8 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector) | |||
| 335 | } | 337 | } |
| 336 | 338 | ||
| 337 | static enum drm_connector_status | 339 | static enum drm_connector_status |
| 338 | vmw_ldu_connector_detect(struct drm_connector *connector) | 340 | vmw_ldu_connector_detect(struct drm_connector *connector, |
| 341 | bool force) | ||
| 339 | { | 342 | { |
| 340 | if (vmw_connector_to_ldu(connector)->pref_active) | 343 | if (vmw_connector_to_ldu(connector)->pref_active) |
| 341 | return connector_status_connected; | 344 | return connector_status_connected; |
| @@ -516,7 +519,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
| 516 | 519 | ||
| 517 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, | 520 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, |
| 518 | DRM_MODE_CONNECTOR_LVDS); | 521 | DRM_MODE_CONNECTOR_LVDS); |
| 519 | connector->status = vmw_ldu_connector_detect(connector); | 522 | connector->status = vmw_ldu_connector_detect(connector, true); |
| 520 | 523 | ||
| 521 | drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, | 524 | drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, |
| 522 | DRM_MODE_ENCODER_LVDS); | 525 | DRM_MODE_ENCODER_LVDS); |
| @@ -535,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
| 535 | 538 | ||
| 536 | int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | 539 | int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) |
| 537 | { | 540 | { |
| 541 | struct drm_device *dev = dev_priv->dev; | ||
| 542 | int i; | ||
| 543 | int ret; | ||
| 544 | |||
| 538 | if (dev_priv->ldu_priv) { | 545 | if (dev_priv->ldu_priv) { |
| 539 | DRM_INFO("ldu system already on\n"); | 546 | DRM_INFO("ldu system already on\n"); |
| 540 | return -EINVAL; | 547 | return -EINVAL; |
| @@ -552,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | |||
| 552 | 559 | ||
| 553 | drm_mode_create_dirty_info_property(dev_priv->dev); | 560 | drm_mode_create_dirty_info_property(dev_priv->dev); |
| 554 | 561 | ||
| 555 | vmw_ldu_init(dev_priv, 0); | ||
| 556 | /* for old hardware without multimon only enable one display */ | ||
| 557 | if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { | 562 | if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { |
| 558 | vmw_ldu_init(dev_priv, 1); | 563 | for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i) |
| 559 | vmw_ldu_init(dev_priv, 2); | 564 | vmw_ldu_init(dev_priv, i); |
| 560 | vmw_ldu_init(dev_priv, 3); | 565 | ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU); |
| 561 | vmw_ldu_init(dev_priv, 4); | 566 | } else { |
| 562 | vmw_ldu_init(dev_priv, 5); | 567 | /* for old hardware without multimon only enable one display */ |
| 563 | vmw_ldu_init(dev_priv, 6); | 568 | vmw_ldu_init(dev_priv, 0); |
| 564 | vmw_ldu_init(dev_priv, 7); | 569 | ret = drm_vblank_init(dev, 1); |
| 565 | } | 570 | } |
| 566 | 571 | ||
| 567 | return 0; | 572 | return ret; |
| 568 | } | 573 | } |
| 569 | 574 | ||
| 570 | int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) | 575 | int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) |
| 571 | { | 576 | { |
| 577 | struct drm_device *dev = dev_priv->dev; | ||
| 578 | |||
| 579 | drm_vblank_cleanup(dev); | ||
| 572 | if (!dev_priv->ldu_priv) | 580 | if (!dev_priv->ldu_priv) |
| 573 | return -ENOSYS; | 581 | return -ENOSYS; |
| 574 | 582 | ||
| @@ -610,7 +618,7 @@ int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num, | |||
| 610 | ldu->pref_height = 600; | 618 | ldu->pref_height = 600; |
| 611 | ldu->pref_active = false; | 619 | ldu->pref_active = false; |
| 612 | } | 620 | } |
| 613 | con->status = vmw_ldu_connector_detect(con); | 621 | con->status = vmw_ldu_connector_detect(con, true); |
| 614 | } | 622 | } |
| 615 | 623 | ||
| 616 | mutex_unlock(&dev->mode_config.mutex); | 624 | mutex_unlock(&dev->mode_config.mutex); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 5f2d5df01e5c..c8c40e9979db 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
| @@ -211,6 +211,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) | |||
| 211 | cmd->body.cid = cpu_to_le32(res->id); | 211 | cmd->body.cid = cpu_to_le32(res->id); |
| 212 | 212 | ||
| 213 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 213 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
| 214 | vmw_3d_resource_dec(dev_priv); | ||
| 214 | } | 215 | } |
| 215 | 216 | ||
| 216 | static int vmw_context_init(struct vmw_private *dev_priv, | 217 | static int vmw_context_init(struct vmw_private *dev_priv, |
| @@ -247,6 +248,7 @@ static int vmw_context_init(struct vmw_private *dev_priv, | |||
| 247 | cmd->body.cid = cpu_to_le32(res->id); | 248 | cmd->body.cid = cpu_to_le32(res->id); |
| 248 | 249 | ||
| 249 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 250 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
| 251 | (void) vmw_3d_resource_inc(dev_priv); | ||
| 250 | vmw_resource_activate(res, vmw_hw_context_destroy); | 252 | vmw_resource_activate(res, vmw_hw_context_destroy); |
| 251 | return 0; | 253 | return 0; |
| 252 | } | 254 | } |
| @@ -406,6 +408,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res) | |||
| 406 | cmd->body.sid = cpu_to_le32(res->id); | 408 | cmd->body.sid = cpu_to_le32(res->id); |
| 407 | 409 | ||
| 408 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 410 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
| 411 | vmw_3d_resource_dec(dev_priv); | ||
| 409 | } | 412 | } |
| 410 | 413 | ||
| 411 | void vmw_surface_res_free(struct vmw_resource *res) | 414 | void vmw_surface_res_free(struct vmw_resource *res) |
| @@ -473,6 +476,7 @@ int vmw_surface_init(struct vmw_private *dev_priv, | |||
| 473 | } | 476 | } |
| 474 | 477 | ||
| 475 | vmw_fifo_commit(dev_priv, submit_size); | 478 | vmw_fifo_commit(dev_priv, submit_size); |
| 479 | (void) vmw_3d_resource_inc(dev_priv); | ||
| 476 | vmw_resource_activate(res, vmw_hw_surface_destroy); | 480 | vmw_resource_activate(res, vmw_hw_surface_destroy); |
| 477 | return 0; | 481 | return 0; |
| 478 | } | 482 | } |
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index b87569e96b16..f366f968155a 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c | |||
| @@ -598,7 +598,7 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev, | |||
| 598 | pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count); | 598 | pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count); |
| 599 | } | 599 | } |
| 600 | 600 | ||
| 601 | void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) | 601 | static void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) |
| 602 | { | 602 | { |
| 603 | struct vga_device *vgadev; | 603 | struct vga_device *vgadev; |
| 604 | unsigned long flags; | 604 | unsigned long flags; |
